Changeset 216 in xtideuniversalbios


Ignore:
Timestamp:
Jan 23, 2012, 8:17:19 AM (12 years ago)
Author:
gregli@…
google:author:
gregli@hotmail.com
Message:

Serial port code - improved pointer re-normalization.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialCommand.asm

    r214 r216  
    1414SerialCommand_UART_transmitByte                 EQU     0
    1515SerialCommand_UART_receiveByte                  EQU     0
    16 SerialCommand_UART_divisorLow                   EQU     0
     16
     17;
    1718; Values for UART_divisorLow:
    1819; 60h = 1200, 30h = 2400, 18h = 4800, 0ch = 9600, 6 = 19200, 3 = 38400, 2 = 57600, 1 = 115200
    19 
    20 SerialCommand_UART_divisorLow_startingBaud      EQU   030h
     20;
     21SerialCommand_UART_divisorLow                   EQU     0
     22
     23;
    2124; We support 4 baud rates, starting here going higher and skipping every other baud rate
    2225; Starting with 30h, that means 30h (1200 baud), 0ch (9600 baud), 3 (38400 baud), and 1 (115200 baud)
    2326; Note: hardware baud multipliers (2x, 4x) will impact the final baud rate and are not known at this level
     27;
     28SerialCommand_UART_divisorLow_startingBaud      EQU   030h
    2429
    2530SerialCommand_UART_interruptEnable              EQU     1
     31
     32;
     33; UART_divisorHigh is zero for all speeds including and above 1200 baud (which is all we do)
     34;
    2635SerialCommand_UART_divisorHigh                  EQU     1
    27 ; UART_divisorHigh is zero for all speeds including and above 1200 baud
    2836
    2937SerialCommand_UART_interruptIdent               EQU     2
     
    7684;  all other commands return success
    7785;  including function 0ech which should return drive information, this is handled with the identify functions
     86;
    7887        xor     ah,ah           ;  also clears carry
    7988        ret
     
    130139        push    ax
    131140
    132 ;       cld     ; Shouldn't be needed. DF has already been cleared (line 24, Int13h.asm)
     141%if 0
     142        cld     ; Shouldn't be needed. DF has already been cleared (line 24, Int13h.asm)
     143%endif
    133144
    134145;----------------------------------------------------------------------
     
    309320        jnz     SerialCommand_OutputWithParameters_Error
    310321
     322        pop     ax              ; sector count and command byte
     323        dec     al              ; decrememnt sector count
     324        push    ax              ; save
     325        jz      SerialCommand_OutputWithParameters_ReturnCodeInALCF    ; CF=0 from "cmp ax,bp" returning Zero above
     326
     327        cli                     ; interrupts back off for ACK byte to host
     328                                ; (host could start sending data immediately)
     329        out     dx,al           ; ACK with next sector number
     330
     331;
     332; Normalize buffer pointer for next go round, if needed.
     333;
     334; We need to re-nomrlize the pointer in ES:DI after processing every 7f sectors.  That number could
     335; have been 80 if we knew the offset was on a segment boundary, but this may not be the case.
     336;
     337; We re-normalize based on the sector count (flags from "dec al" above)...
     338;    a) we normalize before the first sector goes out, immediately after sending the command packet (above)
     339;    b) on transitions from FF to FE, very rare case for writing 255 or 256 sectors
     340;    c) on transitions from 80 to 7F, a large read/write
     341;    d) on transitions from 00 to FF, very, very rare case of writing 256 secotrs
     342;       We don't need to renormalize in this case, but it isn't worth the memory/effort to not do
     343;       the extra work, and it does no harm.
     344;
     345; I really don't care much about (d) because I have not seen cases where any OS makes a request
     346; for more than 127 sectors.  Back in the day, it appears that some BIOS could not support more than 127
     347; sectors, so that may be the practical limit for OS and application developers.  The Extended BIOS
     348; function also appear to be capped at 127 sectors.  So although this can support the full 256 sectors
     349; if needed, we are optimized for that 1-127 range.
     350;
     351; Assume we start with 0000:000f, with 256 sectors to write...
     352;    After first packet, 0000:020f
     353;    First decrement of AL, transition from 00 to FF: renormalize to 0020:000f (unnecessary)
     354;    After second packet, 0020:020f
     355;    Second derement of AL, transition from FF to FE: renormalize to 0040:000f
     356;    After 7f more packets, 0040:fe0f
     357;    Decrement of AL, transition from 80 to 7F: renormalize to 1020:000f
     358;    After 7f more packets, 1020:fe0f or 2000:000f if normalized
     359;    Decrement of AL, from 1 to 0: exit
     360;
     361        jge     short .nextSector       ; OF=SF, branch for 1-7e, most common case
     362                                        ; (0 kicked out above for return success)
     363
     364        add     al,2                    ; 7f-ff moves to 81-01
     365                                        ; (0-7e kicked out before we get here)
     366                                        ; 7f moves to 81 and OF=1, so OF=SF
     367                                        ; fe moves to 0 and OF=0, SF=0, so OF=SF
     368                                        ; ff moves to 1 and OF=0, SF=0, so OF=SF
     369                                        ; 80-fd moves to 82-ff and OF=0, so OF<>SF
     370
     371        jl      short .nextSector       ; OF<>SF, branch for all cases but 7f, fe, and ff
     372
     373%if 0
     374        jpo     short .nextSector       ; if we really wanted to avoid normalizing for ff, this
     375                                        ; is one way to do it, but it adds more memory and more
     376                                        ; cycles for the 7f and fe cases.  IMHO, given that I've
     377                                        ; never seen a request for more than 7f, this seems unnecessary.
     378%endif
     379
     380        jmp     short .nextSectorNormalize  ; our two renormalization cases (plus one for ff)
     381
     382;---------------------------------------------------------------------------
     383;
     384; Cleanup, error reporting, and exit
     385;
     386
     387;
     388; Used in situations where a call is underway, such as with SerialCommand_WaitAndPoll
     389;
     390ALIGN JUMP_ALIGN
     391SerialCommand_OutputWithParameters_ErrorAndPop4Words:
     392        add     sp,8
     393;;; fall-through
     394
     395ALIGN JUMP_ALIGN
     396SerialCommand_OutputWithParameters_Error:
    311397;----------------------------------------------------------------------
    312398;
     
    326412        in      al,dx
    327413        jc      .clearBuffer    ; note CF from shr above
    328         jmp     SerialCommand_OutputWithParameters_Error
    329 
    330 .clearBufferComplete:
    331 
    332         pop     ax              ; sector count and command byte
    333         dec     al              ; decrememnt sector count
    334         push    ax              ; save
    335         jz      SerialCommand_OutputWithParameters_ReturnCodeInALCF    ; CF clear from .clearBuffer test above
    336 
    337         cli                     ; interrupts back off for ACK byte to host
    338                                 ; (host could start sending data immediately)
    339         out     dx,al           ; ACK with next sector number
    340 
    341 ;
    342 ; Normalize buffer pointer for next go round, if needed
    343 ;
    344         test    di,di
    345         jns     short .nextSector
    346         jmp     short .nextSectorNormalize
    347 
    348 ;---------------------------------------------------------------------------
    349 ;
    350 ; Cleanup, error reporting, and exit
    351 ;
    352 
    353 ;
    354 ; Used in situations where a call is underway, such as with SerialCommand_WaitAndPoll
    355 ;
    356 ALIGN JUMP_ALIGN
    357 SerialCommand_OutputWithParameters_ErrorAndPop4Words:
    358         add     sp,8
    359 
    360 ALIGN JUMP_ALIGN
    361 SerialCommand_OutputWithParameters_Error:
     414
     415.clearBufferComplete:           
    362416        stc
    363417        mov     al,1
     
    365419ALIGN JUMP_ALIGN
    366420SerialCommand_OutputWithParameters_ReturnCodeInALCF:
    367         sti
     421%if 0
     422        sti                     ;  all paths here will already have interrupts turned back on
     423%endif
    368424        mov     ah,al
    369425
     
    696752.error:
    697753        stc
    698         ; mov       ah,1        ; setting the error code is unnecessary as this path can only be taken during
    699                                 ; drive detection, and drive detection works off CF and does not check AH
     754%if 0
     755        mov     ah,1        ; setting the error code is unnecessary as this path can only be taken during
     756                            ; drive detection, and drive detection works off CF and does not check AH
     757%endif
    700758        ret
    701759
Note: See TracChangeset for help on using the changeset viewer.