Ignore:
Timestamp:
Feb 4, 2012, 6:21:22 PM (12 years ago)
Author:
gregli@…
google:author:
gregli@hotmail.com
Message:

Serial Port: split single byte port and baud into two bytes, taking advantage of the two bytes in DPT_SERIAL, which supports more serial baud rates and in particular fixed a bug where a 4x client machine couldn't talk to a 115.2K server machine. This is a wide change, touching lots of files, but most are shallow changes. DetectPrint.asm took the most significant changes, now it calculates the baud rate to display instead of using characters provided by the Configurator. The Configurator now has a new menu flag, FLG_MENUITEM_CHOICESTRINGS, for specifying that values are not linear and they should be lookedup rather than indexed. Finally, another important bug fixed here is that in some error cases, the serial port code could get into an infinite loop waiting ont the hardware; now it has a timeout.

File:
1 edited

Legend:

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

    r226 r233  
    1717;
    1818; Values for UART_divisorLow:
    19 ; 60h = 1200, 30h = 2400, 18h = 4800, 0ch = 9600, 6 = 19200, 3 = 38400, 2 = 57600, 1 = 115200
     19; 60h = 1200, 30h = 2400, 18h = 4800, 0ch = 9600, 6 = 19200, 4 = 28800, 3 = 38400, 2 = 57600, 1 = 115200
    2020;
    2121SerialCommand_UART_divisorLow                   EQU     0
    22 
    23 ;
    24 ; We support 4 baud rates, starting here going higher and skipping every other baud rate
    25 ; Starting with 30h, that means 30h (1200 baud), 0ch (9600 baud), 3 (38400 baud), and 1 (115200 baud)
    26 ; Note: hardware baud multipliers (2x, 4x) will impact the final baud rate and are not known at this level
    27 ;
    28 SerialCommand_UART_divisorLow_startingBaud      EQU   030h
    29 
    30 SerialCommand_UART_interruptEnable              EQU     1
    3122
    3223;
     
    9182        mov     [bp+IDEPACK.bFeatures],ah       ; store protocol command
    9283
    93         mov     dl, byte [di+DPT_SERIAL.bSerialPortAndBaud]
     84        mov     dx, [di+DPT_SERIAL.wSerialPortAndBaud]
    9485
    9586; fall-through
    9687
    9788;--------------------------------------------------------------------
    98 ; SerialCommand_OutputWithParameters_DeviceInDL
     89; SerialCommand_OutputWithParameters_DeviceInDX
    9990;   Parameters:
    10091;       AH:     Protocol Command
    101 ;       DL:     Packed I/O port and baud rate
     92;       DX:     Packed I/O port and baud rate
    10293;       ES:SI:  Ptr to buffer (for data transfer commands)
    10394;       SS:BP:  Ptr to IDEREGS_AND_INTPACK
     
    10899;       AL, BX, CX, DX, (ES:SI for data transfer commands)
    109100;--------------------------------------------------------------------
    110 SerialCommand_OutputWithParameters_DeviceInDL:
     101SerialCommand_OutputWithParameters_DeviceInDX:
    111102
    112103        push    si
     
    116107;
    117108; Unpack I/O port and baud from DPT
    118 ;       Port to DX more or less for the remainder of the routine
     109;       Port to DX for the remainder of the routine (+/- different register offsets)
    119110;       Baud in CH until UART initialization is complete
    120111;
    121         mov     dh, ((DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT & 0f00h) >> (8+1))
    122         shl     dx, 1       ; port offset already x4, needs one more shift to be x8
    123         mov     cl, dl
    124 
    125         and     cl, (DEVICE_SERIAL_PACKEDPORTANDBAUD_BAUDMASK << 1)
    126         mov     ch, SerialCommand_UART_divisorLow_startingBaud
    127         shr     ch, cl
    128         adc     ch, 0
    129 
    130         and     dl, ((DEVICE_SERIAL_PACKEDPORTANDBAUD_PORTMASK << 1) & 0ffh)
    131         add     dx, byte (DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT & 0ffh)
    132 
     112        mov     ch,dh
     113        xor     dh,dh
     114        eSHL_IM dx, 2           ; shift from one byte to two       
     115       
    133116        mov     al,[bp+IDEPACK.bSectorCount]
    134117
     
    414397; taken care of this, but I have seen cases where this is not true.
    415398;
     399        xor     cx,cx                   ; timeout this clearing routine, in case the UART isn't there
    416400.clearBuffer:
    417401        mov     dl,bh
     
    420404        test    al,08fh
    421405        jz      .clearBufferComplete
    422         shr     al,1
     406        test    al,1
    423407        in      al,dx
    424         jc      .clearBuffer    ; note CF from shr above
     408        loopnz  .clearBuffer            ; note ZF from test above
    425409
    426410.clearBufferComplete:
     
    641625;     master scan.
    642626;
    643         mov     dl,[cs:bp+IDEVARS.bSerialPackedPortAndBaud]
    644         mov     al, byte [RAMVARS.xlateVars+XLATEVARS.bLastSerial]
     627        mov     cx,1            ; 1 sector to move, 0 for non-scan
     628        mov     dx,[cs:bp+IDEVARS.wSerialPortAndBaud]
     629        xor     ax,ax
     630        push    si
     631        call    FindDPT_ToDSDIforSerialDevice
     632        pop     si
     633        jnc     .notfounddpt
     634        mov     ax,[ds:di+DPT_SERIAL.wSerialPortAndBaud]
     635.notfounddpt:   
    645636
    646637        test    bh, FLG_DRVNHEAD_DRV
    647638        jz      .master
    648639
    649         test    al,al           ; Take care of the case that is different between master and slave.
     640        test    ax,ax           ; Take care of the case that is different between master and slave.
    650641        jz      .error          ; Because we do this here, the jz after the "or" below will not be taken
    651642
    652643; fall-through
    653644.master:
    654         test    dl,dl
    655         jnz     .identifyDeviceInDL
    656 
    657         or      dl,al           ; Move bLast into position in dl, as well as test for zero
     645        test    dx,dx
     646        jnz     .identifyDeviceInDX
     647
     648        or      dx,ax           ; Move bLast into position in dl, as well as test for zero
    658649        jz      .scanSerial
    659650
    660651; fall-through
    661 .identifyDeviceInDL:
     652.identifyDeviceInDX:
    662653
    663654        push    bp              ; setup fake IDEREGS_AND_INTPACK
     
    665656        push    dx
    666657
    667         mov     cl,1            ; 1 sector to move
    668658        push    cx
    669659
     
    674664
    675665        mov     bp,sp
    676         call    SerialCommand_OutputWithParameters_DeviceInDL
     666        call    SerialCommand_OutputWithParameters_DeviceInDX
    677667
    678668        pop     bx
     
    680670        pop     cx
    681671        pop     dx
    682 
     672       
    683673        pop     bp
    684674;
    685675; place packed port/baud in RAMVARS, read by FinalizeDPT and DetectDrives
    686676;
    687 ; Note that this will be set during an int13h/25h call as well.  Which is OK since it is only used (at the
    688 ; top of this routine) for drives found during a COM scan, and we only COM scan if there were no other
    689 ; COM drives found.  So we will only reaffirm the port/baud for the one COM port/baud that has a drive.
    690 ;
    691         jc      .notFound                                           ; only store bLastSerial if success
    692         mov     byte [RAMVARS.xlateVars+XLATEVARS.bLastSerial], dl
     677        mov     [es:si+ATA6.wVendor],dx
    693678
    694679.notFound:
     
    714699.scanSerial:
    715700        mov     di,.scanPortAddresses-1
     701        mov     ch,1            ;  tell server that we are scanning
    716702
    717703.nextPort:
     
    741727
    742728;
    743 ; Pack into dl, baud rate starts at 0
    744 ;
    745         add     dx,-(DEVICE_SERIAL_PACKEDPORTANDBAUD_STARTINGPORT)
    746         shr     dx,1            ; dh is zero at this point, and will be sent to the server,
    747                                 ; so we know this is an auto detect
    748 
    749         jmp     .testFirstBaud
    750 
    751 ;
    752 ; Walk through 4 possible baud rates
    753 ;
     729; Begin baud rate scan on this port...
     730;
     731; On a scan, we support 6 baud rates, starting here and going higher by a factor of two each step, with a
     732; small jump between 9600 and 38800.  These 6 were selected since we wanted to support 9600 baud and 115200,
     733; *on the server side* if the client side had a 4x clock multiplier, a 2x clock multiplier, or no clock multiplier.
     734;
     735; Starting with 30h, that means 30h (2400 baud), 18h (4800 baud), 0ch (9600 baud), and
     736;                               04h (28800 baud), 02h (57600 baud), 01h (115200 baud)
     737;
     738; Note: hardware baud multipliers (2x, 4x) will impact the final baud rate and are not known at this level
     739;
     740        mov     dh,030h * 2     ; multiply by 2 since we are about to divide by 2
     741        mov     dl,[cs:di]      ; restore single byte port address for scan
     742
    754743.nextBaud:
    755         inc     dx
    756         test    dl,3
     744        shr     dh,1
    757745        jz      .nextPort
    758 
    759 .testFirstBaud:
    760         call    .identifyDeviceInDL
     746        cmp     dh,6            ; skip from 6 to 4, to move from the top of the 9600 baud range
     747        jnz     .testBaud       ; to the bottom of the 115200 baud range
     748        mov     dh,4
     749
     750.testBaud:
     751        call    .identifyDeviceInDX
    761752        jc      .nextBaud
    762753
Note: See TracChangeset for help on using the changeset viewer.