Changeset 364 in xtideuniversalbios for trunk/XTIDE_Universal_BIOS/Src
- Timestamp:
- Mar 27, 2012, 4:21:58 PM (13 years ago)
- google:author:
- aitotat@gmail.com
- Location:
- trunk/XTIDE_Universal_BIOS/Src
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/XTIDE_Universal_BIOS/Src/Boot/BootMenuInfo.asm
r363 r364 17 17 ; ES:BX: Ptr to BOOTMENUINFO (if successful) 18 18 ; Corrupts registers: 19 ; AX, CX, DX, DI19 ; AX, BX, CX, DX, DI 20 20 ;-------------------------------------------------------------------- 21 21 BootMenuInfo_CreateForHardDisk: 22 22 call BootMenuInfo_ConvertDPTtoBX ; ES:BX now points to new BOOTMENUINFO 23 push ds ; Preserve RAMVARS...24 push si ; ...and SI25 26 push es ; ES to be copied to DS27 28 %ifdef MODULE_ADVANCED_ATA29 ; Copy DPT_ADVANCED_ATA to BOOTMENUINFO to keep DPTs small.30 ; DPT_ADVANCED_ATA has variables that are only needed during initialization.31 mov ax, [di+DPT_ADVANCED_ATA.wIdeBasePort]32 mov [es:bx+BOOTMENUINFO.wIdeBasePort], ax33 mov dx, [di+DPT_ADVANCED_ATA.wMinPioActiveTimeNs]34 mov [es:bx+BOOTMENUINFO.wMinPioActiveTimeNs], dx35 36 mov ax, [di+DPT_ADVANCED_ATA.wMinPioRecoveryTimeNs]37 mov cx, [di+DPT_ADVANCED_ATA.wControllerID]38 mov dx, [di+DPT_ADVANCED_ATA.wControllerBasePort]39 pop ds ; ES copied to DS40 mov [bx+BOOTMENUINFO.wMinPioRecoveryTimeNs], ax41 mov [bx+BOOTMENUINFO.wControllerID], cx42 mov [bx+BOOTMENUINFO.wControllerBasePort], dx43 44 %else45 pop ds ; ES copied to DS46 %endif47 23 48 24 ; Store Drive Name 25 push ds ; Preserve RAMVARS 26 push si 27 28 push es ; ES copied to DS 29 pop ds 30 49 31 add si, BYTE ATA1.strModel ; DS:SI now points drive name 50 32 lea di, [bx+BOOTMENUINFO.szDrvName] ; ES:DI now points to name destination … … 60 42 pop si 61 43 pop ds 44 62 45 ret 63 46 … … 72 55 ; CX 73 56 ;-------------------------------------------------------------------- 57 ALIGN JUMP_ALIGN 74 58 BootMenuInfo_GetTotalSectorCount: 75 59 test BYTE [di+DPT.bFlagsLow], FLG_DRVNHEAD_LBA … … 117 101 xchg ax, bx 118 102 pop ax 119 ret 103 ret -
trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm
r363 r364 58 58 ; Nothing 59 59 ; Corrupts registers: 60 ; AX, CX, DX60 ; AX, BX, CX 61 61 ;-------------------------------------------------------------------- 62 62 .StorePioMode: 63 call AtaID_GetMaxPioModeToAXandMinCycleTimeToDX 64 call AtaID_ConvertPioModeFromAXandMinCycleTimeFromDXtoActiveAndRecoveryTime 65 mov [di+DPT_ATA.bPioMode], al 66 mov [di+DPT_ADVANCED_ATA.wMinPioActiveTimeNs], cx 67 mov [di+DPT_ADVANCED_ATA.wMinPioRecoveryTimeNs], dx 63 call AtaID_GetMaxPioModeToAXandMinCycleTimeToCX 64 mov [di+DPT_ADVANCED_ATA.wMinPioCycleTime], cx 65 mov [di+DPT_ADVANCED_ATA.bPioMode], al 66 or [di+DPT.bFlagsHigh], ah 68 67 69 68 ;-------------------------------------------------------------------- … … 79 78 ;-------------------------------------------------------------------- 80 79 .DetectAdvancedIdeController: 81 mov dx, [cs:bp+IDEVARS.wPort] 82 mov [di+DPT_ADVANCED_ATA.wIdeBasePort], dx 83 call AdvAtaInit_DetectControllerForIdeBaseInDX 80 call AccessDPT_GetIdeBasePortToBX 81 call AdvAtaInit_DetectControllerForIdeBaseInBX 84 82 mov [di+DPT_ADVANCED_ATA.wControllerID], ax ; Store zero if none detected 85 mov [di+DPT_ADVANCED_ATA.wControllerBasePort], cx83 mov [di+DPT_ADVANCED_ATA.wControllerBasePort], dx 86 84 jnc SHORT .NoAdvancedControllerDetected 87 85 … … 90 88 call AdvAtaInit_GetControllerMaxPioModeToAL 91 89 jnc SHORT .ChangeTo32bitDevice 92 MIN_U [di+DPT_ATA.bPioMode], al 90 and BYTE [di+DPT.bFlagsHigh], ~FLGH_DPT_IORDY ; No IORDY supported if need to limit 91 MIN_U [di+DPT_ADVANCED_ATA.bPioMode], al 93 92 94 93 ; We have detected 32-bit controller so change Device Type since 95 94 ; it might have been set to 16-bit on IDEVARS 96 95 .ChangeTo32bitDevice: 97 mov BYTE [di+DPT_A TA.bDevice], DEVICE_32BIT_ATA96 mov BYTE [di+DPT_ADVANCED_ATA.bDevice], DEVICE_32BIT_ATA 98 97 99 98 .NoAdvancedControllerDetected: … … 136 135 IdeDPT_StoreDeviceTypeFromIdevarsInCSBPtoDPTinDSDI: 137 136 mov al, [cs:bp+IDEVARS.bDevice] 138 mov [di+DPT_A TA.bDevice], al137 mov [di+DPT_ADVANCED_ATA.bDevice], al 139 138 ret 139 140 140 %endif -
trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm
r363 r364 189 189 mov dx, [cs:bx+IDEVARS.wPort] ; Load IDE Data port address 190 190 %ifdef MODULE_ADVANCED_ATA 191 mov bl, [di+DPT_A TA.bDevice]191 mov bl, [di+DPT_ADVANCED_ATA.bDevice] 192 192 %else 193 193 mov bl, [cs:bx+IDEVARS.bDevice] ; Load device type to BX -
trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm
r363 r364 171 171 ;-------------------------------------------------------------------- 172 172 InitializePioMode: 173 xor dx, dx ; Parameter to Sector Count Register = 0 = PIO_DEFAULT_MODE 174 mov al, [di+DPT_ATA.bPioMode] 175 cmp al, 3 ; PIO mode 3 and above require IORDY 176 jb SHORT .SetTransferMode 177 or dl, al 178 .SetTransferMode: 173 mov dl, PIO_DEFAULT_MODE_DISABLE_IORDY 174 test BYTE [di+DPT.bFlagsHigh], FLGH_DPT_IORDY 175 jz SHORT .IordyNotSupported 176 177 ; Advanced PIO mode 3 and above 178 mov dl, [di+DPT_ADVANCED_ATA.bPioMode] 179 or dl, PIO_FLOW_CONTROL_MODE_xxx 180 181 .IordyNotSupported: 179 182 mov si, FEATURE_SET_TRANSFER_MODE 180 183 jmp AH23h_SetControllerFeatures -
trunk/XTIDE_Universal_BIOS/Src/Initialization/AdvAtaInit.asm
r363 r364 7 7 8 8 ;-------------------------------------------------------------------- 9 ; AdvAtaInit_DetectControllerForIdeBaseIn DX9 ; AdvAtaInit_DetectControllerForIdeBaseInBX 10 10 ; Parameters: 11 ; DX: IDE Controller base port11 ; BX: IDE Controller base port 12 12 ; Returns: 13 13 ; AX: ID WORD specific for detected controller 14 14 ; Zero if no controller detected 15 ; CX: Controller base port (not IDE)15 ; DX: Controller base port (not IDE) 16 16 ; CF: Set if controller detected 17 17 ; Cleared if no controller … … 19 19 ; BX 20 20 ;-------------------------------------------------------------------- 21 AdvAtaInit_DetectControllerForIdeBaseIn DX:22 call Vision_DetectAndReturnIDinAXandPortIn CXifControllerPresent23 jne SHORT .NoAdvancedControllerForPort DX24 call Vision_DoesIdePortIn DXbelongToControllerWithIDinAX25 jne SHORT .NoAdvancedControllerForPort DX21 AdvAtaInit_DetectControllerForIdeBaseInBX: 22 call Vision_DetectAndReturnIDinAXandPortInDXifControllerPresent 23 jne SHORT .NoAdvancedControllerForPortBX 24 call Vision_DoesIdePortInBXbelongToControllerWithIDinAX 25 jne SHORT .NoAdvancedControllerForPortBX 26 26 27 stc ; Advanced Controller found for port DX27 stc ; Advanced Controller found for port BX 28 28 ret 29 29 30 .NoAdvancedControllerForPort DX:30 .NoAdvancedControllerForPortBX: 31 31 xor ax, ax 32 32 ret … … 38 38 ; AX: ID WORD specific for detected controller 39 39 ; 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 41 42 ; CF: Set if PIO limit necessary 42 43 ; Cleared if no need to limit timings 43 44 ; Corrupts registers: 44 ; Nothing45 ; (AX if CF cleared) 45 46 ;-------------------------------------------------------------------- 46 47 AdvAtaInit_GetControllerMaxPioModeToAL equ Vision_GetMaxPioModeToAL … … 58 59 ;-------------------------------------------------------------------- 59 60 AdvAtaInit_InitializeControllerForDPTinDSDI: 60 push ds61 push bp 61 62 push si 62 push di63 64 ; PIO and Advanced Controller variables are stored to BOOTMENUINFO65 ; to keep the DPTs as small as possible.66 call GetMasterAndSlaveBootMenuInfosToSIandDI67 cmp WORD [BOOTVARS.wMagicWord], BOOTVARS_MAGIC_WORD68 clc69 jne SHORT .BootMenuInfosAreNoLongerAvailable70 63 71 64 ; Call Controller Specific initialization function 72 mov ax, [ si+BOOTMENUINFO.wControllerID]65 mov ax, [di+DPT_ADVANCED_ATA.wControllerID] 73 66 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 76 68 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 78 73 .NoAdvancedController: 79 pop di80 74 pop si 81 pop ds75 pop bp 82 76 ret 83 77 84 78 85 79 ;-------------------------------------------------------------------- 86 ; AdvAtaInit_ GetMasterAndSlaveBootMenuInfosToSIandDI80 ; AdvAtaInit_LoadMasterDPTtoDSSIifSlaveInDSDI 87 81 ; Parameters: 88 82 ; DS:DI: Ptr to DPT for Single or Slave Drive 89 83 ; Returns: 90 ; DS: SI: Ptr to Single or Master Drive BOOTMENUINFO91 ; DI: Offset to Slave Drive BOOTMENUINFO84 ; DS:DI: Ptr to DPT for Single or Slave Drive 85 ; SI: Offset to Master DPT if Slave Drive present 92 86 ; Zero if Slave Drive not present 93 87 ; Corrupts registers: 94 ; BX, DX, (DS will change!)88 ; AX 95 89 ;-------------------------------------------------------------------- 96 GetMasterAndSlaveBootMenuInfosToSIandDI: 97 call BootMenuInfo_ConvertDPTtoBX 98 LOAD_BDA_SEGMENT_TO ds, di, ! ; Zero DI to assume no Slave Drive present 90 AdvAtaInit_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 99 96 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: 108 100 ret 109 101 110 102 111 103 ;-------------------------------------------------------------------- 112 ; AdvAtaInit_SelectSlowest TimingsToBXandCX104 ; AdvAtaInit_SelectSlowestCommonPioTimingsToBXandCXfromDSSIandDSDI 113 105 ; Parameters: 114 ; DS: SI: Ptr to BOOTMENUINFO for Master or Single Drive115 ; DI: Offset to BOOTMENUINFO for Slave Drive106 ; DS:DI: Ptr to DPT for Single or Slave Drive 107 ; SI: Offset to Master DPT if Slave Drive present 116 108 ; Zero if Slave Drive not present 117 109 ; Returns: 118 ; BX: Min Active Time in nanosecs119 ; CX: Min RecoveryTime in nanosecs110 ; BX: Best common PIO mode 111 ; CX: Slowest common PIO Cycle Time in nanosecs 120 112 ; Corrupts registers: 121 113 ; Nothing 122 114 ;-------------------------------------------------------------------- 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: 115 AdvAtaInit_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: 135 123 ret -
trunk/XTIDE_Universal_BIOS/Src/Initialization/AtaID.asm
r363 r364 76 76 %ifdef MODULE_ADVANCED_ATA 77 77 ;-------------------------------------------------------------------- 78 ; AtaID_GetMaxPioModeToAXandMinCycleTimeTo DX78 ; AtaID_GetMaxPioModeToAXandMinCycleTimeToCX 79 79 ; Parameters: 80 80 ; ES:SI: Ptr to 512-byte ATA information read from the drive 81 81 ; 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 84 85 ; Corrupts registers: 85 86 ; BX 86 87 ;-------------------------------------------------------------------- 87 AtaID_GetMaxPioModeToAXandMinCycleTimeTo DX:88 AtaID_GetMaxPioModeToAXandMinCycleTimeToCX: 88 89 ; Get PIO mode and cycle time for PIO 0...2 89 90 mov bx, [es:si+ATA1.bPioMode] 90 91 shl bx, 1 ; Shift for WORD lookup 91 mov dx, [cs:bx+.rgwPio0to2CycleTimeInNanosecs]92 mov cx, [cs:bx+.rgwPio0to2CycleTimeInNanosecs] 92 93 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 94 100 95 101 ; Check if Advanced PIO modes are supported (3 and above) … … 98 104 99 105 ; 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) 101 107 mov bx, [es:si+ATA2.bPIOSupp] 102 108 .CheckNextFlag: … … 104 110 shr bx, 1 105 111 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 107 114 .ReturnPioTimings: 108 115 ret 109 110 116 111 117 .rgwPio0to2CycleTimeInNanosecs: … … 116 122 117 123 ;-------------------------------------------------------------------- 118 ; AtaID_ ConvertPioModeFromAXandMinCycleTimeFromDXtoActiveAndRecoveryTime124 ; AtaID_GetRecoveryTimeToAXfromPioModeInBXandCycleTimeInCX 119 125 ; Parameters: 120 ; AX: Max supported PIO mode121 ; DX: MinimumPIO Cycle Time in nanosecs126 ; BX: PIO Mode 127 ; CX: PIO Cycle Time in nanosecs 122 128 ; Returns: 123 ; CX: Minimum Active time in nanosecs 124 ; DX: Minimum Recovery time in nanosecs 129 ; AX: Active Time in nanosecs 125 130 ; Corrupts registers: 126 ; BX 131 ; BX, CX 127 132 ;-------------------------------------------------------------------- 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 133 AtaID_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) 138 139 ret 139 140 140 141 141 .rgbPioModeToAddressValidTimeNs: … … 145 145 db PIO_3_MIN_ADDRESS_VALID_NS 146 146 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 ;-------------------------------------------------------------------- 160 AtaID_GetActiveTimeToAXfromPioModeInBX: 161 shl bx, 1 162 mov ax, [cs:bx+.rgwPioModeToActiveTimeNs] 163 shr bx, 1 164 ret 147 165 148 166 .rgwPioModeToActiveTimeNs: … … 152 170 dw PIO_3_MIN_ACTIVE_TIME_NS 153 171 dw PIO_4_MIN_ACTIVE_TIME_NS 172 dw PIO_5_MIN_ACTIVE_TIME_NS 173 dw PIO_6_MIN_ACTIVE_TIME_NS 154 174 155 175 %endif ; MODULE_ADVANCED_ATA -
trunk/XTIDE_Universal_BIOS/Src/Initialization/Vision.asm
r363 r364 7 7 8 8 ;-------------------------------------------------------------------- 9 ; Vision_DetectAndReturnIDinAXandPortIn CXifControllerPresent9 ; Vision_DetectAndReturnIDinAXandPortInDXifControllerPresent 10 10 ; Parameters: 11 11 ; Nothing … … 14 14 ; (AL = QD65xx Config Register contents) 15 15 ; (AH = QDI Vision Controller ID (bits 4...7)) 16 ; CX: Controller port (not IDE port)16 ; DX: Controller port (not IDE port) 17 17 ; ZF: Set if controller found 18 18 ; Cleared if supported controller not found (AX,DX = undefined) … … 20 20 ; Nothing 21 21 ;-------------------------------------------------------------------- 22 Vision_DetectAndReturnIDinAXandPortIn CXifControllerPresent:22 Vision_DetectAndReturnIDinAXandPortInDXifControllerPresent: 23 23 ; Check QD65xx base port 24 mov cx, QD65XX_BASE_PORT24 mov dx, QD65XX_BASE_PORT 25 25 in al, QD65XX_BASE_PORT + QD65XX_CONFIG_REGISTER_in 26 26 call IsConfigRegisterWithIDinAL … … 28 28 29 29 ; Check QD65xx alternative base port 30 or cl, QD65XX_ALTERNATIVE_BASE_PORT30 or dl, QD65XX_ALTERNATIVE_BASE_PORT 31 31 in al, QD65XX_ALTERNATIVE_BASE_PORT + QD65XX_CONFIG_REGISTER_in 32 32 ; Fall to IsConfigRegisterWithIDinAL … … 56 56 57 57 ;-------------------------------------------------------------------- 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 65 64 ; Returns: 66 65 ; ZF: Set if port belongs to controller 67 66 ; Cleared if port belongs to another controller 68 67 ; Corrupts registers: 69 ; BX70 ;-------------------------------------------------------------------- 71 Vision_DoesIdePortIn DXbelongToControllerWithIDinAX:68 ; Nothing 69 ;-------------------------------------------------------------------- 70 Vision_DoesIdePortInBXbelongToControllerWithIDinAX: 72 71 cmp ah, ID_QD6500 << 4 73 72 je SHORT .DoesIdePortInDXbelongToQD6500 … … 75 74 ; QD6580 always have Primary IDE at 1F0h 76 75 ; Secondary IDE at 170h can be enabled or disabled 77 cmp dx, DEVICE_ATA_DEFAULT_PORT76 cmp bx, DEVICE_ATA_DEFAULT_PORT 78 77 je SHORT .ReturnResultInZF 79 78 80 79 ; Check if Secondary IDE channel is enabled 81 xchg bx, ax ; Backup AX 82 xchg dx, cx ; Swap ports 83 80 push ax 84 81 add dx, BYTE QD6580_CONTROL_REGISTER 85 82 in al, dx 86 83 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 92 87 ret 93 88 … … 95 90 .DoesIdePortInDXbelongToQD6500: 96 91 test al, FLG_QDCONFIG_PRIMARY_IDE 97 jz SHORT .Compare DXtoSecondaryIDE98 cmp dx, DEVICE_ATA_DEFAULT_PORT99 ret 100 101 .Compare DXtoSecondaryIDE:102 cmp dx, DEVICE_ATA_DEFAULT_SECONDARY_PORT92 jz SHORT .CompareBXtoSecondaryIDE 93 cmp bx, DEVICE_ATA_DEFAULT_PORT 94 ret 95 96 .CompareBXtoSecondaryIDE: 97 cmp bx, DEVICE_ATA_DEFAULT_SECONDARY_PORT 103 98 .ReturnResultInZF: 104 99 ret … … 108 103 ; Vision_GetMaxPioModeToAL 109 104 ; 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 114 110 ; CF: Set if PIO limit necessary 115 111 ; Cleared if no need to limit timings 116 112 ; Corrupts registers: 113 ; (AX if CF cleared) 114 ; Corrupts registers: 117 115 ; Nothing 118 116 ;-------------------------------------------------------------------- … … 122 120 jne SHORT .NoNeedToLimitForQD6580 123 121 124 mov a l, 2 ; Limit to PIO 2 because QD6500 supports PIO 3 but without IORDY122 mov ax, 2 ; Limit to PIO 2 because QD6500 does not support IORDY 125 123 stc 126 124 .NoNeedToLimitForQD6580: … … 131 129 ; Vision_InitializeWithIDinAHandConfigInAL 132 130 ; 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 139 136 ; Returns: 140 137 ; CF: Cleared if success 141 138 ; Set if error 142 139 ; Corrupts registers: 143 ; AX, BX, CX, DX, SI, DI140 ; AX, BX, CX, DX, BP 144 141 ;-------------------------------------------------------------------- 145 142 Vision_InitializeWithIDinAHandConfigInAL: 146 143 ; 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 . GetPioTimingsInNanosecs144 mov dx, [di+DPT_ADVANCED_ATA.wControllerBasePort] 145 cmp ah, ID_QD6500 << 4 146 je SHORT .CalculateTimingForQD6500 150 147 151 148 ; Program QD6580 Control Register (not available on QD6500) to 152 149 ; Enable or Disable Read-Ahead and Post-Write Buffer to match 153 150 ; jumper setting on the multi I/O card. 154 .ProgramControlRegisterForQD6580: 155 xchg bx, ax ; Backup AX 151 xor ax, ax 156 152 add dx, BYTE QD6580_CONTROL_REGISTER 157 153 in al, dx ; Read to get ATAPI jumper status 158 154 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 163 158 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 172 160 173 161 ; Now we need to determine is the drive connected to the Primary or Secondary channel. 174 162 ; QD6500 has only one channel that can be Primary at 1F0h or Secondary at 170h. 175 163 ; 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 180 167 times 2 inc dx ; Secondary Channel IDE Timing Register 181 168 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. 185 170 .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 ;-------------------------------------------------------------------- 211 ConvertNanosecsFromAXwithLimitsInBPtoRegisterValue: 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 201 221 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 213 227 214 228 ; Not done yet, we need to invert the ticks since 0 is the slowest 215 229 ; 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 -
trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm
r358 r364 4 4 ; Section containing code 5 5 SECTION .text 6 7 %ifdef MODULE_ADVANCED_ATA 8 ;-------------------------------------------------------------------- 9 ; AccessDPT_GetIdeBasePortToBX 10 ; Parameters: 11 ; DS:DI: Ptr to Disk Parameter Table 12 ; Returns: 13 ; BX: IDE Base Port Address 14 ; Corrupts registers: 15 ; Nothing 16 ;-------------------------------------------------------------------- 17 ALIGN JUMP_ALIGN 18 AccessDPT_GetIdeBasePortToBX: 19 eMOVZX bx, [di+DPT.bIdevarsOffset] ; CS:BX points to IDEVARS 20 mov bx, [cs:bx+IDEVARS.wPort] 21 ret 22 23 %endif 24 6 25 7 26 ;-------------------------------------------------------------------- -
trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/RamVars.asm
r294 r364 31 31 ;-------------------------------------------------------------------- 32 32 .StealMemoryForRAMVARS: 33 ; Always steal memory when using Advanced ATA module since it 34 ; uses larger DPTs 35 %ifndef MODULE_ADVANCED_ATA 33 36 mov ax, LITE_MODE_RAMVARS_SEGMENT 34 37 test BYTE [cs:ROMVARS.wFlags], FLG_ROMVARS_FULLMODE 35 38 jz SHORT .InitializeRamvars ; No need to steal RAM 39 %endif 36 40 37 41 LOAD_BDA_SEGMENT_TO ds, ax, ! ; Zero AX
Note:
See TracChangeset
for help on using the changeset viewer.