Changeset 601 in xtideuniversalbios for trunk/Assembly_Library/Src/Serial/SerialServer.asm


Ignore:
Timestamp:
Feb 14, 2019, 7:38:08 PM (5 years ago)
Author:
krille_n_
Message:

Changes:

  • Building the BIOS now works again.
  • Added a new IDE device type/transfer mode for use only with XT-IDE rev 2+ (or Chuck(G)-modded rev 1) cards installed in any of the following machines: Olivetti M24, AT&T PC6300, Xerox 6060 and Logabax Persona 1600. This new transfer mode is slightly faster than the regular XT-IDE rev 1 device type and requires that the card is configured for High Speed mode (or, in case of the card being a rev 1 card, has the Chuck(G) mod done). The new device type is called "XTIDE rev 2 (Olivetti M24)" in XTIDECFG.
  • Made some minor improvements to the library code that handles 'Drive Not Ready' errors in XTIDECFG.
  • Optimizations.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Assembly_Library/Src/Serial/SerialServer.asm

    r592 r601  
    3838;--------------------------------------------------------------------
    3939SerialServer_SendReceive:
    40 
    41         push    si
    42         push    di
    43         push    bp
     40    push    si
     41    push    di
     42    push    bp
    4443
    4544;
     
    4847;       Baud in CH until UART initialization is complete
    4948;
    50         mov     ch,dh
    51         xor     dh,dh
    52         eSHL_IM dx, 2           ; shift from one byte to two
    53 
    54         mov     al,[bp+SerialServer_Command.bSectorCount]
    55         mov     ah,[bp+SerialServer_Command.bCommand]
     49    mov     ch, dh
     50    xor     dh, dh
     51    eSHL_IM dx, 2                       ; shift from one byte to two
     52
     53    mov     al, [bp+SerialServer_Command.bSectorCount]
     54    mov     ah, [bp+SerialServer_Command.bCommand]
    5655
    5756;
    5857; Command byte and sector count live at the top of the stack, pop/push are used to access
    5958;
    60         push    ax              ; save sector count for return value
    61         push    ax              ; working copy on the top of the stack
    62 
    63 %ifndef EXCLUDE_FROM_XUB        ; DF already cleared in Int13h.asm
     59    push    ax                          ; save sector count for return value
     60    push    ax                          ; working copy on the top of the stack
     61
     62%ifndef EXCLUDE_FROM_XUB                ; DF already cleared in Int13h.asm
    6463%ifdef CLD_NEEDED
    65         cld
     64    cld
    6665%endif
    6766%endif
     
    7473; decided to reprogram the UART
    7574;
    76         mov     bl,dl           ; setup BL with proper values for read/write loops (BH comes later)
    77 
    78         mov     al,83h
    79         add     dl, Serial_UART_lineControl ; Clears CF
    80         out     dx,al
    81 
    82         mov     al,ch
    83         mov     dl,bl           ; divisor low
    84         out     dx,al
     75    mov     bl, dl                      ; setup BL with proper values for read/write loops (BH comes later)
     76    mov     al, 83h
     77    add     dl, Serial_UART_lineControl ; Clears CF
     78    out     dx, al
     79
     80    mov     al, ch
     81    mov     dl, bl                      ; divisor low
     82    out     dx, al
    8583
    8684%ifdef USE_UNDOC_INTEL
    87         salc    ; Clear AL using CF
     85    salc                                ; Clear AL using CF
    8886%else
    89         xor     al, al
    90 %endif
    91         inc     dx              ; divisor high
    92         push    dx
    93         out     dx,al
    94 
    95         mov     al,047h
    96         inc     dx              ; fifo
    97         out     dx,al
    98 
    99         mov     al,03h
    100         inc     dx              ; linecontrol
    101         out     dx,al
    102 
    103         mov     al,0bh
    104         inc     dx              ; modemcontrol
    105         out     dx,al
    106 
    107         inc     dx              ; linestatus (no output now, just setting up BH for later use)
    108         mov     bh,dl
    109 
    110         pop     dx              ; base, interrupts disabled
     87    xor     al, al
     88%endif
     89    inc     dx                          ; divisor high
     90    push    dx
     91    out     dx, al
     92
     93    mov     al, 47h
     94    inc     dx                          ; fifo
     95    out     dx, al
     96
     97    mov     al, 03h
     98    inc     dx                          ; linecontrol
     99    out     dx, al
     100
     101    mov     al, 0Bh
     102    inc     dx                          ; modemcontrol
     103    out     dx, al
     104
     105    inc     dx                          ; linestatus (no output now, just setting up BH for later use)
     106    mov     bh, dl
     107
     108    pop     dx                          ; base, interrupts disabled
    111109%ifdef USE_UNDOC_INTEL
    112         salc    ; Clear AL using CF
     110    salc                                ; Clear AL using CF
    113111%else
    114         xor     al, al
    115 %endif
    116         out     dx,al
     112    xor     al, al
     113%endif
     114    out     dx, al
    117115
    118116;----------------------------------------------------------------------
     
    122120; Sends first six bytes of IDEREGS_AND_INTPACK as the command
    123121;
    124         push    es              ; save off real buffer location
    125         push    si
    126 
    127         mov     si,bp           ; point to IDEREGS for command dispatch;
    128         push    ss
    129         pop     es
    130 
    131         mov     di,0ffffh       ; initialize checksum for write
    132         mov     bp,di
    133 
    134         mov     cx,4            ; writing 3 words (plus 1)
    135 
    136         cli                     ; interrupts off...
    137 
    138         call    SerialServer_WriteProtocol.entry
    139 
    140         pop     di              ; restore real buffer location (note change from SI to DI)
    141                                 ; Buffer is primarily referenced through ES:DI throughout, since
    142                                 ; we need to store (read sector) faster than we read (write sector)
    143         pop     es
    144 
    145         pop     ax              ; load command byte (done before call to .nextSector on subsequent iterations)
    146         push    ax
     122    push    es                          ; save off real buffer location
     123    push    si
     124
     125    mov     si, bp                      ; point to IDEREGS for command dispatch;
     126    push    ss
     127    pop     es
     128
     129    mov     di, 0FFFFh                  ; initialize checksum for write
     130    mov     bp, di
     131
     132    mov     cx, 4                       ; writing 3 words (plus 1)
     133
     134    cli                                 ; interrupts off...
     135
     136    call    SerialServer_WriteProtocol.entry
     137
     138    pop     di                          ; restore real buffer location (note change from SI to DI)
     139                                        ; Buffer is primarily referenced through ES:DI throughout, since
     140                                        ; we need to store (read sector) faster than we read (write sector)
     141    pop     es
     142
     143    pop     ax                          ; load command byte (done before call to .nextSector on subsequent iterations)
     144    push    ax
    147145
    148146%ifndef SERIALSERVER_NO_ZERO_SECTOR_COUNTS
    149         test    al,al           ; if no sectors to be transferred, wait for the ACK checksum on the command
    150         jz      .zeroSectors
     147    test    al, al                      ; if no sectors to be transferred, wait for the ACK checksum on the command
     148    jz      SHORT .zeroSectors
    151149%endif
    152150
     
    155153;
    156154.nextSector:
    157         mov     si,0ffffh       ; initialize checksum for read or write
    158         mov     bp,si
    159 
    160         mov     cx,0101h        ; writing 256 words (plus 1)
    161 
    162         sahf                    ; command byte, are we doing a write?
    163         jnc     .readEntry
    164 
    165         xchg    si,di           ; swap pointer and checksum, will be re-swap'ed in WriteProtocol
    166         call    SerialServer_WriteProtocol.entry
     155    mov     si, 0FFFFh                  ; initialize checksum for read or write
     156    mov     bp, si
     157
     158    mov     cx, 0101h                   ; writing 256 words (plus 1)
     159
     160    sahf                                ; command byte, are we doing a write?
     161    jnc     SHORT .readEntry
     162
     163    xchg    si, di                      ; swap pointer and checksum, will be re-swap'ed in WriteProtocol
     164    call    SerialServer_WriteProtocol.entry
    167165
    168166.zeroSectors:
    169         inc     cx              ; CX = 1 now (0 out of WriteProtocol)
    170         jmp     .readEntry
     167    inc     cx                          ; CX = 1 now (0 out of WriteProtocol)
     168    jmp     SHORT .readEntry
    171169
    172170;----------------------------------------------------------------------
     
    177175;
    178176.readTimeout:
    179         push    ax              ; not only does this push preserve AX (which we need), but it also
    180                                 ; means the stack has the same number of bytes on it as when we are
    181                                 ; sending a packet, important for error cleanup and exit
    182         mov     ah,1
    183         call    SerialServer_WaitAndPoll_Read
    184         pop     ax
    185         test    dl,1
    186         jz      .readByte1Ready
    187         jmp     .readByte2Ready
     177    push    ax                          ; not only does this push preserve AX (which we need), but it also
     178                                        ; means the stack has the same number of bytes on it as when we are
     179                                        ; sending a packet, important for error cleanup and exit
     180    mov     ah, 1
     181    call    SerialServer_WaitAndPoll_Read
     182    pop     ax
     183    test    dl, 1
     184    jz      SHORT .readByte1Ready
     185    jmp     SHORT .readByte2Ready
    188186
    189187;----------------------------------------------------------------------------
     
    197195;
    198196.readLoop:
    199         stosw                   ; store word in caller's data buffer
    200 
    201         add     bp, ax          ; update Fletcher's checksum
    202         adc     bp, 0
    203         add     si, bp
    204         adc     si, 0
     197    stosw                               ; store word in caller's data buffer
     198
     199    add     bp, ax                      ; update Fletcher's checksum
     200    adc     bp, 0
     201    add     si, bp
     202    adc     si, 0
    205203
    206204.readEntry:
    207         mov     dl,bh
    208         in      al,dx
    209         shr     al,1            ; data ready (byte 1)?
    210         mov     dl,bl           ; get ready to read data
    211         jnc     .readTimeout    ; nope not ready, update timeouts
     205    mov     dl, bh
     206    in      al, dx
     207    shr     al, 1                       ; data ready (byte 1)?
     208    mov     dl, bl                      ; get ready to read data
     209    jnc     SHORT .readTimeout          ; nope not ready, update timeouts
    212210
    213211;
     
    216214;
    217215.readByte1Ready:
    218         in      al, dx          ; read data byte 1
    219 
    220         mov     ah, al          ; store byte in ah for now
     216    in      al, dx                      ; read data byte 1
     217    mov     ah, al                      ; store byte in ah for now
    221218
    222219;
     
    227224; .read_byte2_ready)
    228225;
    229         mov     dl,bh
    230 
    231         in      al,dx
    232         shr     al,1            ; data ready (byte 2)?
    233         jnc     .readTimeout
     226    mov     dl, bh
     227
     228    in      al, dx
     229    shr     al, 1                       ; data ready (byte 2)?
     230    jnc     SHORT .readTimeout
    234231.readByte2Ready:
    235         mov     dl,bl
    236         in      al, dx          ; read data byte 2
    237 
    238         xchg    al, ah          ; ah was holding byte 1, reverse byte order
    239 
    240         loop    .readLoop
    241 
    242         sti                     ; interrupts back on ASAP, between packets
     232    mov     dl, bl
     233    in      al, dx                      ; read data byte 2
     234    xchg    al, ah                      ; ah was holding byte 1, reverse byte order
     235    loop    .readLoop
     236    sti                                 ; interrupts back on ASAP, between packets
    243237
    244238;
    245239; Compare checksums
    246240;
    247         xchg    ax,bp
    248         xor     ah,al
    249         mov     cx,si
    250         xor     cl,ch
    251         mov     al,cl
    252         cmp     ax,bp
    253         jnz     SerialServer_OutputWithParameters_Error
    254 
    255         pop     ax              ; sector count and command byte
    256         dec     al              ; decrement sector count
    257         push    ax              ; save
    258         jz      SerialServer_OutputWithParameters_ReturnCodeInAL
    259 
    260         cli                     ; interrupts back off for ACK byte to host
    261                                 ; (host could start sending data immediately)
    262         out     dx,al           ; ACK with next sector number
    263 
    264         jmp     short .nextSector
     241    xchg    ax, bp
     242    xor     ah, al
     243    mov     cx, si
     244    xor     cl, ch
     245    mov     al, cl
     246    cmp     ax, bp
     247    jne     SHORT SerialServer_OutputWithParameters_Error
     248
     249    pop     ax                          ; sector count and command byte
     250    dec     al                          ; decrement sector count
     251    push    ax                          ; save
     252    jz      SHORT SerialServer_OutputWithParameters_ReturnCodeInAL
     253
     254    cli                                 ; interrupts back off for ACK byte to host
     255                                        ; (host could start sending data immediately)
     256    out     dx, al                      ; ACK with next sector number
     257    jmp     SHORT .nextSector
    265258
    266259;---------------------------------------------------------------------------
     
    274267ALIGN JUMP_ALIGN
    275268SerialServer_OutputWithParameters_ErrorAndPop4Words:
    276         add     sp,8
     269    add     sp, 8
    277270;;; fall-through
    278271
     
    287280; taken care of this, but I have seen cases where this is not true.
    288281;
    289         xor     cx,cx           ; timeout this clearing routine, in case the UART isn't there
     282    xor     cx, cx                      ; timeout this clearing routine, in case the UART isn't there
    290283.clearBuffer:
    291         mov     dl,bh
    292         in      al,dx
    293         mov     dl,bl
    294         test    al,08fh
    295         jz      .clearBufferComplete
    296         test    al,1
    297         in      al,dx
    298         loopnz  .clearBuffer    ; note ZF from test above
     284    mov     dl, bh
     285    in      al, dx
     286    mov     dl, bl
     287    test    al, 8Fh
     288    jz      SHORT .clearBufferComplete
     289    test    al, 1
     290    in      al, dx
     291    loopnz  .clearBuffer                ; note ZF from test above
    299292
    300293.clearBufferComplete:
    301         mov     al, 1           ; error return code
     294    mov     al, 1                       ; error return code
    302295
    303296ALIGN JUMP_ALIGN
    304297SerialServer_OutputWithParameters_ReturnCodeInAL:
    305298%if 0
    306         sti                     ; all paths here will already have interrupts turned back on
    307 %endif
    308         mov     ah, al          ; for success, AL will already be zero
    309 
    310         pop     bx              ; recover "ax" (command and count) from stack
    311         pop     cx              ; recover saved sector count
    312         xor     ch, ch
    313         sub     cl, bl          ; subtract off the number of sectors that remained
    314 
    315         pop     bp
    316         pop     di
    317         pop     si
    318 
    319         sahf                    ; error return code to CF
    320 
    321         ret
     299    sti                                 ; all paths here will already have interrupts turned back on
     300%endif
     301    mov     ah, al                      ; for success, AL will already be zero
     302
     303    pop     bx                          ; recover "ax" (command and count) from stack
     304    pop     cx                          ; recover saved sector count
     305    xor     ch, ch
     306    sub     cl, bl                      ; subtract off the number of sectors that remained
     307
     308    pop     bp
     309    pop     di
     310    pop     si
     311
     312    sahf                                ; error return code to CF
     313    ret
     314
    322315
    323316;--------------------------------------------------------------------
     
    345338SerialServer_WriteProtocol:
    346339.writeLoop:
    347         es lodsw                ; fetch next word
    348 
    349         out     dx,al           ; output first byte
    350 
    351         add     bp,ax           ; update checksum
    352         adc     bp,0
    353         add     di,bp
    354         adc     di,0
    355 
    356         mov     dl,bh           ; transmit buffer empty?
    357         in      al,dx
    358         test    al,20h
    359         jz      .writeTimeout2  ; nope, use our polling routine
     340    es lodsw                            ; fetch next word
     341
     342    out     dx, al                      ; output first byte
     343
     344    add     bp, ax                      ; update checksum
     345    adc     bp, 0
     346    add     di, bp
     347    adc     di, 0
     348
     349    mov     dl, bh                      ; transmit buffer empty?
     350    in      al, dx
     351    test    al, 20h
     352    jz      SHORT .writeTimeout2        ; nope, use our polling routine
    360353
    361354.writeByte2Ready:
    362         mov     dl,bl
    363         mov     al,ah           ; output second byte
    364         out     dx,al
     355    mov     dl, bl
     356    mov     al, ah                      ; output second byte
     357    out     dx, al
    365358
    366359.entry:
    367         mov     dl,bh           ; transmit buffer empty?
    368         in      al,dx
    369         test    al,20h
    370         mov     dl,bl
    371         jz      .writeTimeout1  ; nope, use our polling routine
     360    mov     dl, bh                      ; transmit buffer empty?
     361    in      al, dx
     362    test    al, 20h
     363    mov     dl, bl
     364    jz      SHORT .writeTimeout1        ; nope, use our polling routine
    372365
    373366.writeByte1Ready:
    374         loop    .writeLoop
    375 
    376         mov     ax,di           ; fold Fletcher's checksum and output
    377         xor     al,ah
    378         out     dx,al           ; byte 1
    379 
    380         call    SerialServer_WaitAndPoll_Write
    381 
    382         mov     ax,bp
    383         xor     al,ah
    384         out     dx,al           ; byte 2
    385 
    386         xchg    si,di           ; preserve checksum word in si, move pointer back to di
    387 
    388         ret
     367    loop    .writeLoop
     368
     369    mov     ax, di                      ; fold Fletcher's checksum and output
     370    xor     al, ah
     371    out     dx, al                      ; byte 1
     372
     373    call    SerialServer_WaitAndPoll_Write
     374
     375    mov     ax, bp
     376    xor     al, ah
     377    out     dx, al                      ; byte 2
     378
     379    xchg    si, di                      ; preserve checksum word in si, move pointer back to di
     380    ret
    389381
    390382.writeTimeout2:
    391         mov     dl,ah           ; need to preserve AH, but don't need DL (will be reset upon return)
    392         call    SerialServer_WaitAndPoll_Write
    393         mov     ah,dl
    394         jmp     .writeByte2Ready
     383    mov     dl, ah                      ; need to preserve AH, but don't need DL (will be reset upon return)
     384    call    SerialServer_WaitAndPoll_Write
     385    mov     ah, dl
     386    jmp     SHORT .writeByte2Ready
    395387
    396388.writeTimeout1:
    397         ePUSH_T ax, .writeByte1Ready    ; return address for ret at end of SC_writeTimeout2
     389    ePUSH_T ax, .writeByte1Ready        ; return address for ret at end of SC_writeTimeout2
    398390;;; fall-through
    399391
     
    418410ALIGN JUMP_ALIGN
    419411SerialServer_WaitAndPoll_Write:
    420         mov     ah,20h
     412    mov     ah, 20h
    421413;;; fall-through
    422414
    423415ALIGN JUMP_ALIGN
    424416SerialServer_WaitAndPoll_Read:
    425         push    cx
    426         push    dx
     417    push    cx
     418    push    dx
    427419
    428420;
    429421; We first poll in a tight loop, interrupts off, for the next character to come in/be sent
    430422;
    431         xor     cx,cx
     423    xor     cx, cx
    432424.readTimeoutLoop:
    433         mov     dl,bh
    434         in      al,dx
    435         test    al,ah
    436         jnz     .readTimeoutComplete
    437         loop    .readTimeoutLoop
     425    mov     dl, bh
     426    in      al, dx
     427    test    al, ah
     428    jnz     SHORT .readTimeoutComplete
     429    loop    .readTimeoutLoop
    438430
    439431;
     
    441433; and wait for a given number of timer ticks to pass.
    442434;
    443         sti
     435    sti
    444436%ifndef SERIALSERVER_TIMER_LOCATION
    445         mov     cl,SerialServer_WaitAndPoll_SoftDelayTicks
    446         call    Timer_InitializeTimeoutWithTicksInCL
     437    mov     cl, SerialServer_WaitAndPoll_SoftDelayTicks
     438    call    Timer_InitializeTimeoutWithTicksInCL
    447439%else
    448         push    ax
    449         push    bx
    450         mov     ax,SerialServer_WaitAndPoll_SoftDelayTicks
    451         mov     bx,SERIALSERVER_TIMER_LOCATION
    452         call    TimerTicks_InitializeTimeoutFromAX
    453         pop     bx
    454         pop     ax
     440    push    ax
     441    push    bx
     442    mov     ax, SerialServer_WaitAndPoll_SoftDelayTicks
     443    mov     bx, SERIALSERVER_TIMER_LOCATION
     444    call    TimerTicks_InitializeTimeoutFromAX
     445    pop     bx
     446    pop     ax
    455447%endif
    456448
    457449.WaitAndPoll:
    458450%ifndef SERIALSERVER_TIMER_LOCATION
    459         call    Timer_SetCFifTimeout
     451    call    Timer_SetCFifTimeout
    460452%else
    461         push    ax
    462         push    bx
    463         mov     bx,SERIALSERVER_TIMER_LOCATION
    464         call    TimerTicks_GetTimeoutTicksLeftToAXfromDSBX
    465         pop     bx
    466         pop     ax
    467 %endif
    468         jc      SerialServer_OutputWithParameters_ErrorAndPop4Words
    469         in      al,dx
    470         test    al,ah
    471         jz      .WaitAndPoll
    472         cli
     453    push    ax
     454    push    bx
     455    mov     bx, SERIALSERVER_TIMER_LOCATION
     456    call    TimerTicks_GetTimeoutTicksLeftToAXfromDSBX
     457    pop     bx
     458    pop     ax
     459%endif
     460    jc      SerialServer_OutputWithParameters_ErrorAndPop4Words
     461    in      al, dx
     462    test    al, ah
     463    jz      SHORT .WaitAndPoll
     464    cli
    473465
    474466.readTimeoutComplete:
    475         pop     dx
    476         pop     cx
    477         ret
    478 
    479 
     467    pop     dx
     468    pop     cx
     469    ret
     470
Note: See TracChangeset for help on using the changeset viewer.