Changeset 364 in xtideuniversalbios for trunk/XTIDE_Universal_BIOS/Src/Initialization


Ignore:
Timestamp:
Mar 27, 2012, 4:21:58 PM (13 years ago)
Author:
aitotat@…
google:author:
aitotat@gmail.com
Message:

Changes to XTIDE Universal BIOS:

  • Advanced ATA Module variables are now kept in DPTs.
  • Forced full mode when using Advanced ATA Module.
Location:
trunk/XTIDE_Universal_BIOS/Src/Initialization
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/XTIDE_Universal_BIOS/Src/Initialization/AdvAtaInit.asm

    r363 r364  
    77
    88;--------------------------------------------------------------------
    9 ; AdvAtaInit_DetectControllerForIdeBaseInDX
     9; AdvAtaInit_DetectControllerForIdeBaseInBX
    1010;   Parameters:
    11 ;       DX:     IDE Controller base port
     11;       BX:     IDE Controller base port
    1212;   Returns:
    1313;       AX:     ID WORD specific for detected controller
    1414;               Zero if no controller detected
    15 ;       CX:     Controller base port (not IDE)
     15;       DX:     Controller base port (not IDE)
    1616;       CF:     Set if controller detected
    1717;               Cleared if no controller
     
    1919;       BX
    2020;--------------------------------------------------------------------
    21 AdvAtaInit_DetectControllerForIdeBaseInDX:
    22     call    Vision_DetectAndReturnIDinAXandPortInCXifControllerPresent
    23     jne     SHORT .NoAdvancedControllerForPortDX
    24     call    Vision_DoesIdePortInDXbelongToControllerWithIDinAX
    25     jne     SHORT .NoAdvancedControllerForPortDX
     21AdvAtaInit_DetectControllerForIdeBaseInBX:
     22    call    Vision_DetectAndReturnIDinAXandPortInDXifControllerPresent
     23    jne     SHORT .NoAdvancedControllerForPortBX
     24    call    Vision_DoesIdePortInBXbelongToControllerWithIDinAX
     25    jne     SHORT .NoAdvancedControllerForPortBX
    2626
    27     stc     ; Advanced Controller found for port DX
     27    stc     ; Advanced Controller found for port BX
    2828    ret
    2929
    30 .NoAdvancedControllerForPortDX:
     30.NoAdvancedControllerForPortBX:
    3131    xor     ax, ax
    3232    ret
     
    3838;       AX:     ID WORD specific for detected controller
    3939;   Returns:
    40 ;       AL:     Max supported PIO mode (if CF set)
     40;       AL:     Max supported PIO mode
     41;       AH:     FLGH_DPT_IORDY if IORDY supported, zero otherwise
    4142;       CF:     Set if PIO limit necessary
    4243;               Cleared if no need to limit timings
    4344;   Corrupts registers:
    44 ;       Nothing
     45;       (AX if CF cleared)
    4546;--------------------------------------------------------------------
    4647AdvAtaInit_GetControllerMaxPioModeToAL  equ Vision_GetMaxPioModeToAL
     
    5859;--------------------------------------------------------------------
    5960AdvAtaInit_InitializeControllerForDPTinDSDI:
    60     push    ds
     61    push    bp
    6162    push    si
    62     push    di
    63 
    64     ; PIO and Advanced Controller variables are stored to BOOTMENUINFO
    65     ; to keep the DPTs as small as possible.
    66     call    GetMasterAndSlaveBootMenuInfosToSIandDI
    67     cmp     WORD [BOOTVARS.wMagicWord], BOOTVARS_MAGIC_WORD
    68     clc
    69     jne     SHORT .BootMenuInfosAreNoLongerAvailable
    7063
    7164    ; Call Controller Specific initialization function
    72     mov     ax, [si+BOOTMENUINFO.wControllerID]
     65    mov     ax, [di+DPT_ADVANCED_ATA.wControllerID]
    7366    test    ax, ax
    74     jz      SHORT .NoAdvancedController
    75     call    Vision_InitializeWithIDinAHandConfigInAL    ; The only we support at the moment
     67    jz      SHORT .NoAdvancedController ; Return with CF cleared
    7668
    77 .BootMenuInfosAreNoLongerAvailable:
     69    ; We only support Vision at the moment so no need to identify ID
     70    call    AdvAtaInit_LoadMasterDPTtoDSSIifSlaveInDSDI
     71    call    Vision_InitializeWithIDinAHandConfigInAL
     72
    7873.NoAdvancedController:
    79     pop     di
    8074    pop     si
    81     pop     ds
     75    pop     bp
    8276    ret
    8377
    8478
    8579;--------------------------------------------------------------------
    86 ; AdvAtaInit_GetMasterAndSlaveBootMenuInfosToSIandDI
     80; AdvAtaInit_LoadMasterDPTtoDSSIifSlaveInDSDI
    8781;   Parameters:
    8882;       DS:DI:  Ptr to DPT for Single or Slave Drive
    8983;   Returns:
    90 ;       DS:SI:  Ptr to Single or Master Drive BOOTMENUINFO
    91 ;       DI:     Offset to Slave Drive BOOTMENUINFO
     84;       DS:DI:  Ptr to DPT for Single or Slave Drive
     85;       SI:     Offset to Master DPT if Slave Drive present
    9286;               Zero if Slave Drive not present
    9387;   Corrupts registers:
    94 ;       BX, DX, (DS will change!)
     88;       AX
    9589;--------------------------------------------------------------------
    96 GetMasterAndSlaveBootMenuInfosToSIandDI:
    97     call    BootMenuInfo_ConvertDPTtoBX
    98     LOAD_BDA_SEGMENT_TO ds, di, !               ; Zero DI to assume no Slave Drive present
     90AdvAtaInit_LoadMasterDPTtoDSSIifSlaveInDSDI:
     91    ; Must be Slave Drive if previous DPT has same IDEVARS offset
     92    lea     si, [di-LARGEST_DPT_SIZE]   ; DS:SI points to previous DPT
     93    mov     al, [di+DPT.bIdevarsOffset]
     94    cmp     al, [si+DPT.bIdevarsOffset]
     95    je      SHORT .MasterAndSlaveDrivePresent
    9996
    100     mov     dx, [bx+BOOTMENUINFO.wIdeBasePort]  ; Load IDE Port from Single or Slave Drive
    101     lea     si, [bx+BOOTMENUINFO_size]          ; SI points to Slave Drive if present
    102     cmp     dx, [si+BOOTMENUINFO.wIdeBasePort]
    103     jne     SHORT .BootMenuInfoForSingleDriveInDSBX
    104 
    105     mov     di, si                              ; Slave Drive detected, copy pointer to DS:DI
    106 .BootMenuInfoForSingleDriveInDSBX:
    107     mov     si, bx
     97    ; We only have single drive so zero SI
     98    xor     si, si
     99.MasterAndSlaveDrivePresent:
    108100    ret
    109101
    110102
    111103;--------------------------------------------------------------------
    112 ; AdvAtaInit_SelectSlowestTimingsToBXandCX
     104; AdvAtaInit_SelectSlowestCommonPioTimingsToBXandCXfromDSSIandDSDI
    113105;   Parameters:
    114 ;       DS:SI:  Ptr to BOOTMENUINFO for Master or Single Drive
    115 ;       DI:     Offset to BOOTMENUINFO for Slave Drive
     106;       DS:DI:  Ptr to DPT for Single or Slave Drive
     107;       SI:     Offset to Master DPT if Slave Drive present
    116108;               Zero if Slave Drive not present
    117109;   Returns:
    118 ;       BX:     Min Active Time in nanosecs
    119 ;       CX:     Min Recovery Time in nanosecs
     110;       BX:     Best common PIO mode
     111;       CX:     Slowest common PIO Cycle Time in nanosecs
    120112;   Corrupts registers:
    121113;       Nothing
    122114;--------------------------------------------------------------------
    123 AdvAtaInit_SelectSlowestTimingsToBXandCX:
    124     mov     bx, [si+BOOTMENUINFO.wMinPioActiveTimeNs]
    125     mov     cx, [si+BOOTMENUINFO.wMinPioRecoveryTimeNs]
    126     test    di, di
    127     jz      SHORT .ReturnSlowestTimingInBXandCX ; No Slave Drive
    128 
    129     ; If Active Time is greater, then must be the Recovery Time as well
    130     cmp     bx, [di+BOOTMENUINFO.wMinPioActiveTimeNs]
    131     jbe     SHORT .ReturnSlowestTimingInBXandCX
    132     mov     bx, [di+BOOTMENUINFO.wMinPioActiveTimeNs]
    133     mov     cx, [di+BOOTMENUINFO.wMinPioRecoveryTimeNs]
    134 .ReturnSlowestTimingInBXandCX:
     115AdvAtaInit_SelectSlowestCommonPioTimingsToBXandCXfromDSSIandDSDI:
     116    eMOVZX  bx, BYTE [di+DPT_ADVANCED_ATA.bPioMode]
     117    mov     cx, [di+DPT_ADVANCED_ATA.wMinPioCycleTime]
     118    test    si, si
     119    jz      SHORT .PioTimingsLoadedToAXandCX
     120    MIN_U   bl, [si+DPT_ADVANCED_ATA.bPioMode]
     121    MAX_U   cx, [si+DPT_ADVANCED_ATA.wMinPioCycleTime]
     122.PioTimingsLoadedToAXandCX:
    135123    ret
  • trunk/XTIDE_Universal_BIOS/Src/Initialization/AtaID.asm

    r363 r364  
    7676%ifdef MODULE_ADVANCED_ATA
    7777;--------------------------------------------------------------------
    78 ; AtaID_GetMaxPioModeToAXandMinCycleTimeToDX
     78; AtaID_GetMaxPioModeToAXandMinCycleTimeToCX
    7979;   Parameters:
    8080;       ES:SI:  Ptr to 512-byte ATA information read from the drive
    8181;   Returns:
    82 ;       AX:     Max supported PIO mode
    83 ;       DX:     Minimum Cycle Time in nanosecs
     82;       AL:     Max supported PIO mode
     83;       AH:     FLGH_DPT_IORDY if IORDY supported, zero otherwise
     84;       CX:     Minimum Cycle Time in nanosecs
    8485;   Corrupts registers:
    8586;       BX
    8687;--------------------------------------------------------------------
    87 AtaID_GetMaxPioModeToAXandMinCycleTimeToDX:
     88AtaID_GetMaxPioModeToAXandMinCycleTimeToCX:
    8889    ; Get PIO mode and cycle time for PIO 0...2
    8990    mov     bx, [es:si+ATA1.bPioMode]
    9091    shl     bx, 1                   ; Shift for WORD lookup
    91     mov     dx, [cs:bx+.rgwPio0to2CycleTimeInNanosecs]
     92    mov     cx, [cs:bx+.rgwPio0to2CycleTimeInNanosecs]
    9293    shr     bx, 1
    93     xchg    ax, bx                  ; AL = PIO mode 0, 1 or 2
     94    xchg    ax, bx                  ; AH = 0, AL = PIO mode 0, 1 or 2
     95
     96    ; Check if IORDY is supported
     97    test    BYTE [es:si+ATA2.wCaps+1], A2_wCaps_IORDY >> 8
     98    jz      SHORT .ReturnPioTimings ; No PIO 3 or higher if no IORDY
     99    mov     ah, FLGH_DPT_IORDY
    94100
    95101    ; Check if Advanced PIO modes are supported (3 and above)
     
    98104
    99105    ; Get Advanced PIO mode
    100     ; (Hard Disks supports up to 4 but CF cards might support 5)
     106    ; (Hard Disks supports up to 4 but CF cards can support 5 and 6)
    101107    mov     bx, [es:si+ATA2.bPIOSupp]
    102108.CheckNextFlag:
     
    104110    shr     bx, 1
    105111    jnz     SHORT .CheckNextFlag
    106     mov     dx, [es:si+ATA2.wPIOMinCyF] ; Advanced modes use IORDY
     112    MIN_U   al, 6                       ; Make sure not above lookup tables
     113    mov     cx, [es:si+ATA2.wPIOMinCyF] ; Advanced modes use IORDY
    107114.ReturnPioTimings:
    108115    ret
    109 
    110116
    111117.rgwPio0to2CycleTimeInNanosecs:
     
    116122
    117123;--------------------------------------------------------------------
    118 ; AtaID_ConvertPioModeFromAXandMinCycleTimeFromDXtoActiveAndRecoveryTime
     124; AtaID_GetRecoveryTimeToAXfromPioModeInBXandCycleTimeInCX
    119125;   Parameters:
    120 ;       AX:     Max supported PIO mode
    121 ;       DX:     Minimum PIO Cycle Time in nanosecs
     126;       BX:     PIO Mode
     127;       CX:     PIO Cycle Time in nanosecs
    122128;   Returns:
    123 ;       CX:     Minimum Active time in nanosecs
    124 ;       DX:     Minimum Recovery time in nanosecs
     129;       AX:     Active Time in nanosecs
    125130;   Corrupts registers:
    126 ;       BX
     131;       BX, CX
    127132;--------------------------------------------------------------------
    128 AtaID_ConvertPioModeFromAXandMinCycleTimeFromDXtoActiveAndRecoveryTime:
    129     ; Subtract Address Valid Time (t1) from Cycle Time (t0)
    130     mov     bx, ax
    131     eMOVZX  cx, BYTE [cs:bx+.rgbPioModeToAddressValidTimeNs]
    132     sub     dx, cx
    133 
    134     ; Subtract Active Time (t2) from previous result to get Recovery Time (t2i)
    135     shl     bx, 1           ; Shift PIO Mode for WORD lookup
    136     mov     cx, [cs:bx+.rgwPioModeToActiveTimeNs]
    137     sub     dx, cx
     133AtaID_GetRecoveryTimeToAXfromPioModeInBXandCycleTimeInCX:
     134    call    AtaID_GetActiveTimeToAXfromPioModeInBX
     135    mov     bl, [cs:bx+.rgbPioModeToAddressValidTimeNs]
     136    sub     cx, bx  ; Cycle Time (t0) - Address Valid Time (t1)
     137    sub     cx, ax  ; - Active Time (t2)
     138    xchg    ax, cx  ; AX = Recovery Time (t2i)
    138139    ret
    139 
    140140
    141141.rgbPioModeToAddressValidTimeNs:
     
    145145    db      PIO_3_MIN_ADDRESS_VALID_NS
    146146    db      PIO_4_MIN_ADDRESS_VALID_NS
     147    db      PIO_5_MIN_ADDRESS_VALID_NS
     148    db      PIO_6_MIN_ADDRESS_VALID_NS
     149
     150
     151;--------------------------------------------------------------------
     152; AtaID_GetActiveTimeToAXfromPioModeInBX
     153;   Parameters:
     154;       BX:     PIO Mode
     155;   Returns:
     156;       AX:     Active Time in nanosecs
     157;   Corrupts registers:
     158;       Nothing
     159;--------------------------------------------------------------------
     160AtaID_GetActiveTimeToAXfromPioModeInBX:
     161    shl     bx, 1
     162    mov     ax, [cs:bx+.rgwPioModeToActiveTimeNs]
     163    shr     bx, 1
     164    ret
    147165
    148166.rgwPioModeToActiveTimeNs:
     
    152170    dw      PIO_3_MIN_ACTIVE_TIME_NS
    153171    dw      PIO_4_MIN_ACTIVE_TIME_NS
     172    dw      PIO_5_MIN_ACTIVE_TIME_NS
     173    dw      PIO_6_MIN_ACTIVE_TIME_NS
    154174
    155175%endif ; MODULE_ADVANCED_ATA
  • trunk/XTIDE_Universal_BIOS/Src/Initialization/Vision.asm

    r363 r364  
    77
    88;--------------------------------------------------------------------
    9 ; Vision_DetectAndReturnIDinAXandPortInCXifControllerPresent
     9; Vision_DetectAndReturnIDinAXandPortInDXifControllerPresent
    1010;   Parameters:
    1111;       Nothing
     
    1414;               (AL = QD65xx Config Register contents)
    1515;               (AH = QDI Vision Controller ID (bits 4...7))
    16 ;       CX:     Controller port (not IDE port)
     16;       DX:     Controller port (not IDE port)
    1717;       ZF:     Set if controller found
    1818;               Cleared if supported controller not found (AX,DX = undefined)
     
    2020;       Nothing
    2121;--------------------------------------------------------------------
    22 Vision_DetectAndReturnIDinAXandPortInCXifControllerPresent:
     22Vision_DetectAndReturnIDinAXandPortInDXifControllerPresent:
    2323    ; Check QD65xx base port
    24     mov     cx, QD65XX_BASE_PORT
     24    mov     dx, QD65XX_BASE_PORT
    2525    in      al, QD65XX_BASE_PORT + QD65XX_CONFIG_REGISTER_in
    2626    call    IsConfigRegisterWithIDinAL
     
    2828
    2929    ; Check QD65xx alternative base port
    30     or      cl, QD65XX_ALTERNATIVE_BASE_PORT
     30    or      dl, QD65XX_ALTERNATIVE_BASE_PORT
    3131    in      al, QD65XX_ALTERNATIVE_BASE_PORT + QD65XX_CONFIG_REGISTER_in
    3232    ; Fall to IsConfigRegisterWithIDinAL
     
    5656
    5757;--------------------------------------------------------------------
    58 ; Vision_DoesIdePortInDXbelongToControllerWithIDinAX
    59 ;   Parameters:
    60 ;       AX:     ID WORD specific for QDI Vision Controllers
    61 ;               (AL = QD65xx Config Register contents)
    62 ;               (AH = QDI Vision Controller ID (bits 4...7))
    63 ;       CX:     Vision Controller port
    64 ;       DX:     IDE base port to check
     58; Vision_DoesIdePortInBXbelongToControllerWithIDinAX
     59;   Parameters:
     60;       AL:     QD65xx Config Register contents
     61;       AH:     QDI Vision Controller ID (bits 4...7)
     62;       BX:     IDE Base port to check
     63;       DX:     Vision Controller port
    6564;   Returns:
    6665;       ZF:     Set if port belongs to controller
    6766;               Cleared if port belongs to another controller
    6867;   Corrupts registers:
    69 ;       BX
    70 ;--------------------------------------------------------------------
    71 Vision_DoesIdePortInDXbelongToControllerWithIDinAX:
     68;       Nothing
     69;--------------------------------------------------------------------
     70Vision_DoesIdePortInBXbelongToControllerWithIDinAX:
    7271    cmp     ah, ID_QD6500 << 4
    7372    je      SHORT .DoesIdePortInDXbelongToQD6500
     
    7574    ; QD6580 always have Primary IDE at 1F0h
    7675    ; Secondary IDE at 170h can be enabled or disabled
    77     cmp     dx, DEVICE_ATA_DEFAULT_PORT
     76    cmp     bx, DEVICE_ATA_DEFAULT_PORT
    7877    je      SHORT .ReturnResultInZF
    7978
    8079    ; Check if Secondary IDE channel is enabled
    81     xchg    bx, ax      ; Backup AX
    82     xchg    dx, cx      ; Swap ports
    83 
     80    push    ax
    8481    add     dx, BYTE QD6580_CONTROL_REGISTER
    8582    in      al, dx
    8683    sub     dx, BYTE QD6580_CONTROL_REGISTER
    87 
    88     xchg    cx, dx
    89     xchg    ax, bx      ; Restore AX, Control Register to BL
    90     test    bl, FLG_QDCONTROL_SECONDARY_DISABLED_in
    91     jz      SHORT .CompareDXtoSecondaryIDE
     84    test    al, FLG_QDCONTROL_SECONDARY_DISABLED_in
     85    pop     ax
     86    jz      SHORT .CompareBXtoSecondaryIDE
    9287    ret
    9388
     
    9590.DoesIdePortInDXbelongToQD6500:
    9691    test    al, FLG_QDCONFIG_PRIMARY_IDE
    97     jz      SHORT .CompareDXtoSecondaryIDE
    98     cmp     dx, DEVICE_ATA_DEFAULT_PORT
    99     ret
    100 
    101 .CompareDXtoSecondaryIDE:
    102     cmp     dx, DEVICE_ATA_DEFAULT_SECONDARY_PORT
     92    jz      SHORT .CompareBXtoSecondaryIDE
     93    cmp     bx, DEVICE_ATA_DEFAULT_PORT
     94    ret
     95
     96.CompareBXtoSecondaryIDE:
     97    cmp     bx, DEVICE_ATA_DEFAULT_SECONDARY_PORT
    10398.ReturnResultInZF:
    10499    ret
     
    108103; Vision_GetMaxPioModeToAL
    109104;   Parameters:
    110 ;       AX:     ID WORD specific for QDI Vision Controllers
    111 ;               (AH = QDI Vision Controller ID (bits 4...7))
    112 ;   Returns:
    113 ;       AL:     Max supported PIO mode (if CF set)
     105;       AL:     QD65xx Config Register contents
     106;       AH:     QDI Vision Controller ID (bits 4...7)
     107;   Returns:
     108;       AL:     Max supported PIO mode
     109;       AH:     FLGH_DPT_IORDY if IORDY supported, zero otherwise
    114110;       CF:     Set if PIO limit necessary
    115111;               Cleared if no need to limit timings
    116112;   Corrupts registers:
     113;       (AX if CF cleared)
     114;   Corrupts registers:
    117115;       Nothing
    118116;--------------------------------------------------------------------
     
    122120    jne     SHORT .NoNeedToLimitForQD6580
    123121
    124     mov     al, 2   ; Limit to PIO 2 because QD6500 supports PIO 3 but without IORDY
     122    mov     ax, 2   ; Limit to PIO 2 because QD6500 does not support IORDY
    125123    stc
    126124.NoNeedToLimitForQD6580:
     
    131129; Vision_InitializeWithIDinAHandConfigInAL
    132130;   Parameters:
    133 ;       AX:     ID WORD specific for QDI Vision Controllers
    134 ;               (AL = QD65xx Config Register contents)
    135 ;               (AH = QDI Vision Controller ID (bits 4...7))
    136 ;       DS:SI:  Ptr to BOOTMENUINFO for Single or Master Drive
    137 ;       DS:DI:  Ptr to BOOTMENUINFO for Slave Drive
    138 ;               Zero if Slave not present
     131;       AL:     QD65xx Config Register contents
     132;       AH:     QDI Vision Controller ID (bits 4...7)
     133;       DS:DI:  Ptr to DPT for Single or Slave Drive
     134;       SI:     Offset to Master DPT if Slave Drive present
     135;               Zero if Slave Drive not present
    139136;   Returns:
    140137;       CF:     Cleared if success
    141138;               Set if error
    142139;   Corrupts registers:
    143 ;       AX, BX, CX, DX, SI, DI
     140;       AX, BX, CX, DX, BP
    144141;--------------------------------------------------------------------
    145142Vision_InitializeWithIDinAHandConfigInAL:
    146143    ; QD6580 has a Control Register that needs to be programmed
    147     mov     dx, [si+BOOTMENUINFO.wControllerBasePort]
    148     cmp     ah, ID_QD6500 << 4
    149     je      SHORT .GetPioTimingsInNanosecs
     144    mov     dx, [di+DPT_ADVANCED_ATA.wControllerBasePort]
     145    cmp     ah, ID_QD6500 << 4
     146    je      SHORT .CalculateTimingForQD6500
    150147
    151148    ; Program QD6580 Control Register (not available on QD6500) to
    152149    ; Enable or Disable Read-Ahead and Post-Write Buffer to match
    153150    ; jumper setting on the multi I/O card.
    154 .ProgramControlRegisterForQD6580:
    155     xchg    bx, ax                                  ; Backup AX
     151    xor     ax, ax
    156152    add     dx, BYTE QD6580_CONTROL_REGISTER
    157153    in      al, dx                                  ; Read to get ATAPI jumper status
    158154    test    al, FLG_QDCONTROL_HDONLY_in
    159     mov     al, MASK_QDCONTROL_FLAGS_TO_SET
    160     jz      SHORT .SkipHdonlyBitSinceAtapiPossible
    161     or      al, FLG_QDCONTROL_NONATAPI
    162 .SkipHdonlyBitSinceAtapiPossible:
     155    eCMOVNZ ah, FLG_QDCONTROL_NONATAPI              ; Enable Read-Ahead and Post-Write Buffers
     156    or      ah, MASK_QDCONTROL_FLAGS_TO_SET
     157    mov     al, ah
    163158    out     dx, al
    164     sub     dx, BYTE QD6580_CONTROL_REGISTER        ; Back to base port
    165     xchg    ax, bx                                  ; Restore AX
    166 
    167     ; If we have Master and Slave drive in the system, we must select
    168     ; timings from the slower drive (this is why it is a bad idea to use
    169     ; fast and slow drive on the same IDE channel)
    170 .GetPioTimingsInNanosecs:
    171     call    AdvAtaInit_SelectSlowestTimingsToBXandCX
     159    sub     dx, BYTE QD6580_CONTROL_REGISTER
    172160
    173161    ; Now we need to determine is the drive connected to the Primary or Secondary channel.
    174162    ; QD6500 has only one channel that can be Primary at 1F0h or Secondary at 170h.
    175163    ; QD6580 always has Primary channel at 1F0h. Secondary channel at 170h can be Enabled or Disabled.
    176     cmp     ah, ID_QD6500 << 4
    177     je      SHORT .CalculateTimingTicksForQD6500
    178     cmp     WORD [si+BOOTMENUINFO.wIdeBasePort], DEVICE_ATA_DEFAULT_PORT
    179     je      SHORT .CalculateTimingTicksForQD6580
     164    call    AccessDPT_GetIdeBasePortToBX
     165    cmp     bx, DEVICE_ATA_DEFAULT_PORT
     166    je      SHORT .CalculateTimingTicksForQD6580    ; Primary Channel so no need to modify DX
    180167    times 2 inc dx                                  ; Secondary Channel IDE Timing Register
    181168
    182     ; Now we must translate the PIO timing nanosecs in CX and DX to VLB ticks
    183     ; suitable for QD65xx IDE Timing Register.
    184     ; Both of the controllers require slightly different calculations.
     169    ; QD6500 and QD6580 require slightly different calculations.
    185170.CalculateTimingTicksForQD6580:
    186     mov     si, QD6580_MIN_ACTIVE_TIME_CLOCKS
    187     mov     di, QD6580_MAX_ACTIVE_TIME_CLOCKS
    188     jmp     SHORT .CalculateTimingForQD65xx
    189 
    190 .CalculateTimingTicksForQD6500:
    191     mov     si, QD6500_MIN_ACTIVE_TIME_CLOCKS
    192     mov     di, QD6500_MAX_ACTIVE_TIME_CLOCKS
    193 
    194 .CalculateTimingForQD65xx:
    195     test    al, FLG_QDCONFIG_ID3        ; Set ZF if 40 MHz VLB bus
    196     mov     al, VLB_33MHZ_CYCLE_TIME    ; Assume 33 MHz or slower VLB bus
    197     xchg    ax, bx                      ; Active Time to AX
    198     eCMOVZ  bl, VLB_40MHZ_CYCLE_TIME
    199 
    200     div     bl
     171    mov     bp, QD6580_MAX_ACTIVE_TIME_CLOCKS | (QD6580_MIN_ACTIVE_TIME_CLOCKS << 8)
     172    jmp     SHORT .CalculateTimingsForQD65xx
     173
     174.CalculateTimingForQD6500:
     175    mov     bp, QD6500_MAX_ACTIVE_TIME_CLOCKS | (QD6500_MIN_ACTIVE_TIME_CLOCKS << 8)
     176
     177    ; We need the PIO Cycle Time in CX to calculate Active and Recovery Times.
     178.CalculateTimingsForQD65xx:
     179    call    AdvAtaInit_SelectSlowestCommonPioTimingsToBXandCXfromDSSIandDSDI
     180
     181    ; Calculate Active Time value for QD65xx IDE Timing Register
     182    call    AtaID_GetActiveTimeToAXfromPioModeInBX
     183    call    ConvertNanosecsFromAXwithLimitsInBPtoRegisterValue
     184    xchg    bp, ax
     185
     186    ; Calculate Recovery Time value for QD65xx IDE Timing Register
     187    call    AtaID_GetRecoveryTimeToAXfromPioModeInBXandCycleTimeInCX
     188    mov     bx, bp                      ; Active Time value now in BL
     189    mov     bp, QD65xx_MAX_RECOVERY_TIME_CLOCKS | (QD65xx_MIN_RECOVERY_TIME_CLOCKS << 8)
     190    call    ConvertNanosecsFromAXwithLimitsInBPtoRegisterValue
     191
     192    ; Merge the values to a single byte to output
     193    eSHIFT_IM   al, POSITON_QD65XXIDE_RECOVERY_TIME, shl
     194    or      al, bl
     195    out     dx, al
     196    ret                                 ; Return with CF cleared
     197
     198
     199;--------------------------------------------------------------------
     200; ConvertNanosecsFromAXwithLimitsInBPtoRegisterValue
     201;   Parameters:
     202;       AX:     Nanosecs to convert
     203;       BP:     Low Byte:   Maximum allowed ticks
     204;               High Byte:  Minimum allowed ticks
     205;       DS:DI:  Ptr to DPT for Single or Slave Drive
     206;   Returns:
     207;       AL:     Timing value for QD65xx register
     208;   Corrupts registers:
     209;       Nothing
     210;--------------------------------------------------------------------
     211ConvertNanosecsFromAXwithLimitsInBPtoRegisterValue:
     212    push    cx
     213
     214    ; Get VLB Cycle Time in nanosecs
     215    mov     cl, VLB_33MHZ_CYCLE_TIME    ; Assume 33 MHz or slower VLB bus
     216    test    BYTE [di+DPT_ADVANCED_ATA.wControllerID], FLG_QDCONFIG_ID3
     217    eCMOVZ  cl, VLB_40MHZ_CYCLE_TIME
     218
     219    ; Convert value in AX to VLB ticks
     220    div     cl                          ; AL = VLB ticks
    201221    inc     ax                          ; Round up
    202     xor     ah, ah
    203     xchg    cx, ax                      ; CX = Active Time in VLB ticks
    204     MAX_U   cx, si                      ; Limit ticks to valid values...
    205     MIN_U   cx, di                      ; ...for QD65xx
    206 
    207     div     bl
    208     inc     ax                          ; Round up
    209     xchg    bx, ax                      ; BL = Recovery Time in VLB ticks
    210     mov     al, QD65xx_MAX_RECOVERY_TIME_CLOCKS
    211     MAX_U   bl, QD65xx_MIN_RECOVERY_TIME_CLOCKS
    212     MIN_U   bl, al
     222
     223    ; Limit value to QD65xx limits
     224    mov     cx, bp
     225    MAX_U   al, ch                      ; Make sure not below minimum
     226    MIN_U   al, cl                      ; Make sure not above maximum
    213227
    214228    ; Not done yet, we need to invert the ticks since 0 is the slowest
    215229    ; value on the timing register
    216     sub     di, cx                      ; DI = Active Time value to program
    217     sub     al, bl                      ; AL = Recovery Time value to program
    218 
    219     ; Finally we can shift the values in places and program the Timing Register
    220     eSHIFT_IM   al, POSITON_QD65XXIDE_RECOVERY_TIME, shl
    221     or      ax, di
    222     out     dx, al
    223     ret                                 ; Return with CF cleared
     230    sub     cl, al
     231    xchg    ax, cx                      ; Return in AL
     232
     233    pop     cx
     234    ret
Note: See TracChangeset for help on using the changeset viewer.