source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Initialization/AdvancedAta/Vision.asm@ 592

Last change on this file since 592 was 592, checked in by Krister Nordvall, 7 years ago

Changes:

  • The problem with NASM in the previous revision (r591) has been fixed.
  • The colors used by the boot menu and hotkey bar can now be customized by selecting one of a number of pre-defined color themes. Suggestions for additional themes are more than welcome!
  • Large builds are now 10 KB. Small builds are still 8 KB with the exception of the Tiny build which is now 4 KB. In other words, builds are now as small as possible to make it easier to combine them with other BIOSes.
  • Added code to the library to improve drive error handling. XTIDECFG can now handle "Drive Not Ready" errors.
  • Fixed a couple of potential bugs in AtaID.asm (AtaID_GetMaxPioModeToAXandMinCycleTimeToCX); 1) ATA1.bPioMode was treated as a WORD variable. 2) ATA2.bPIOSupp was assumed to be non-zero which would result in PIO mode 3 being returned if the assumption was wrong.
  • Made the same changes in the equivalent function used by BIOSDRVS (DisplayPioModeInformationUsingAtaInfoFromDSBX in AtaInfo.asm).
  • Fixed a bug from r587 in PDC20x30.asm in PDC20x30_GetMaxPioModeToALandMinPioCycleTimeToBX.
  • Fixed a bug from r523 in XTIDECFG where Auto Configure would only set the IRQ on one IDE interface on AT-builds.
  • XTIDECFG will now restore the default settings for the "Serial port virtual device" when reselecting it in the list of device types. This makes it behave consistently for all device types.
  • The eAAM macro is now used regardless if USE_UNDOC_INTEL is defined or not because it is apparently supported on all processors including the NEC V20/V30 CPUs.
  • Renamed the EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS define to EXCLUDE_FROM_XUB.
  • Added a define to exclude unused library code from BIOSDRVS (EXCLUDE_FROM_BIOSDRVS). This makes it a lot smaller than in previous revisions.
  • All unnecessary CLD-instructions are now under a new define 'CLD_NEEDED' which is only enabled for the BIOS. It is disabled for XTIDECFG and BIOSDRVS but can be enabled if needed by adding this define to the respective makefile. This change was made because these unnecessary instructions are wasteful and should never be needed. In fact, they only serve to hide bugs (in other peoples code) which I strongly believe should be avoided. I recommend people making their own BIOSes from source to not use this define as it's extremely unlikely to be needed.
  • Updated the copyright info in SerDrive and changed an URL to point to the new site.
  • Updated the copyright info and version number in BIOSDRVS.
  • Updated the copyright info in XTIDECFG.
  • Optimizations in general.
File size: 8.6 KB
RevLine 
[392]1; Project name : XTIDE Universal BIOS
2; Description : Functions for initializing QDI Vision
3; QD6500 and QD6580 VLB IDE Controllers.
4
5;
[526]6; XTIDE Universal BIOS and Associated Tools
7; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
[392]8;
9; This program is free software; you can redistribute it and/or modify
10; it under the terms of the GNU General Public License as published by
11; the Free Software Foundation; either version 2 of the License, or
12; (at your option) any later version.
[526]13;
[392]14; This program is distributed in the hope that it will be useful,
15; but WITHOUT ANY WARRANTY; without even the implied warranty of
16; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
[526]17; GNU General Public License for more details.
[392]18; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
[526]19;
[392]20
21; Section containing code
22SECTION .text
23
24;--------------------------------------------------------------------
25; Vision_DetectAndReturnIDinAXandPortInDXifControllerPresent
26; Parameters:
27; Nothing
28; Returns:
29; AX: ID WORD specific for QDI Vision Controllers
30; (AL = QD65xx Config Register contents)
[589]31; (AH = QDI Vision Controller ID)
[392]32; DX: Controller port (not IDE port)
33; ZF: Set if controller found
34; Cleared if supported controller not found (AX,DX = undefined)
35; Corrupts registers:
36; Nothing
37;--------------------------------------------------------------------
38Vision_DetectAndReturnIDinAXandPortInDXifControllerPresent:
39 ; Check QD65xx base port
40 mov dx, QD65XX_BASE_PORT
41 in al, QD65XX_BASE_PORT + QD65XX_CONFIG_REGISTER_in
[534]42
[542]43%ifdef DANGEROUS_DETECTION
[534]44 ; Checking alternative base port is currently commented away
45 ; since Intel PIIX4 south bridge mirrors Interrupt Controller registers
46 ; from Axh to Bxh.
[392]47 call IsConfigRegisterWithIDinAL
[589]48 je SHORT VisionControllerDetected.Return
[392]49
50 ; Check QD65xx alternative base port
[589]51 mov dl, QD65XX_ALTERNATIVE_BASE_PORT
[392]52 in al, QD65XX_ALTERNATIVE_BASE_PORT + QD65XX_CONFIG_REGISTER_in
[542]53%endif ; DANGEROUS_DETECTION
[392]54 ; Fall to IsConfigRegisterWithIDinAL
55
56;--------------------------------------------------------------------
57; IsConfigRegisterWithIDinAL
58; Parameters:
59; AL: Possible QD65xx Config Register contents
60; Returns:
61; AH QDI Vision Controller ID or undefined
62; ZF: Set if controller found
63; Cleared if supported controller not found (AH = undefined)
64; Corrupts registers:
65; Nothing
66;--------------------------------------------------------------------
[542]67IsConfigRegisterWithIDinAL:
[392]68 mov ah, al
69 and al, MASK_QDCONFIG_CONTROLLER_ID
[589]70 cmp al, ID_QD6500
[392]71 je SHORT VisionControllerDetected
[589]72 cmp al, ID_QD6580
[392]73 je SHORT VisionControllerDetected
[589]74 cmp al, ID_QD6580_ALTERNATE
[392]75VisionControllerDetected:
76 xchg ah, al
[589]77.Return:
[392]78 ret
79
80
81;--------------------------------------------------------------------
82; Vision_DoesIdePortInBXbelongToControllerWithIDinAX
83; Parameters:
84; AL: QD65xx Config Register contents
[589]85; AH: QDI Vision Controller ID
[392]86; BX: IDE Base port to check
87; DX: Vision Controller port
88; Returns:
89; ZF: Set if port belongs to controller
90; Cleared if port belongs to another controller
91; Corrupts registers:
92; Nothing
93;--------------------------------------------------------------------
94Vision_DoesIdePortInBXbelongToControllerWithIDinAX:
[589]95 cmp ah, ID_QD6500
[392]96 je SHORT .DoesIdePortInDXbelongToQD6500
97
98 ; QD6580 always have Primary IDE at 1F0h
99 ; Secondary IDE at 170h can be enabled or disabled
[398]100 cmp bx, DEVICE_ATA_PRIMARY_PORT
[392]101 je SHORT .ReturnResultInZF
102
103 ; Check if Secondary IDE channel is enabled
104 push ax
[582]105 push dx
[392]106 add dx, BYTE QD6580_CONTROL_REGISTER
107 in al, dx
108 test al, FLG_QDCONTROL_SECONDARY_DISABLED_in
[582]109 pop dx
[392]110 pop ax
111 jz SHORT .CompareBXtoSecondaryIDE
112 ret
113
114 ; QD6500 has only one IDE channel that can be at 1F0h or 170h
115.DoesIdePortInDXbelongToQD6500:
116 test al, FLG_QDCONFIG_PRIMARY_IDE
117 jz SHORT .CompareBXtoSecondaryIDE
[398]118 cmp bx, DEVICE_ATA_PRIMARY_PORT
[392]119 ret
120
121.CompareBXtoSecondaryIDE:
[398]122 cmp bx, DEVICE_ATA_SECONDARY_PORT
[392]123.ReturnResultInZF:
124 ret
125
126
127;--------------------------------------------------------------------
[564]128; Vision_GetMaxPioModeToALandMinCycleTimeToBX
[392]129; Parameters:
130; AL: QD65xx Config Register contents
[589]131; AH: QDI Vision Controller ID
[392]132; Returns:
[592]133; AL: Max supported PIO mode (only if ZF set)
134; AH: ~FLGH_DPT_IORDY if IORDY not supported, -1 otherwise (only if ZF set)
[582]135; BX: Min PIO Cycle Time (only if ZF set)
136; ZF: Set if PIO limit necessary
[392]137; Cleared if no need to limit timings
138; Corrupts registers:
139; Nothing
140;--------------------------------------------------------------------
[564]141Vision_GetMaxPioModeToALandMinCycleTimeToBX:
[589]142 cmp ah, ID_QD6500
[392]143 jne SHORT .NoNeedToLimitForQD6580
[592]144 mov ax, (~FLGH_DPT_IORDY & 0FFh) << 8 | 2 ; Limit to PIO 2 because QD6500 does not support IORDY
[564]145 mov bx, PIO_2_MIN_CYCLE_TIME_NS
[392]146.NoNeedToLimitForQD6580:
147 ret
148
149
150;--------------------------------------------------------------------
[589]151; Vision_InitializeWithIDinAH
[392]152; Parameters:
[589]153; AH: QDI Vision Controller ID
[392]154; DS:DI: Ptr to DPT for Single or Slave Drive
155; SI: Offset to Master DPT if Slave Drive present
156; Zero if Slave Drive not present
157; Returns:
158; CF: Cleared if success
159; Set if error
160; Corrupts registers:
161; AX, BX, CX, DX, BP
162;--------------------------------------------------------------------
[589]163Vision_InitializeWithIDinAH:
[392]164 ; QD6580 has a Control Register that needs to be programmed
[589]165 cmp ah, ID_QD6500
[392]166 mov dx, [di+DPT_ADVANCED_ATA.wControllerBasePort]
[582]167 mov bp, QD6500_MAX_ACTIVE_TIME_CLOCKS | (QD6500_MIN_ACTIVE_TIME_CLOCKS << 8) ; Assume QD6500
168 je SHORT .CalculateTimingsForQD65xx
169 mov bp, QD6580_MAX_ACTIVE_TIME_CLOCKS | (QD6580_MIN_ACTIVE_TIME_CLOCKS << 8) ; It's a QD6580
[392]170
171 ; Program QD6580 Control Register (not available on QD6500) to
172 ; Enable or Disable Read-Ahead and Post-Write Buffer to match
173 ; jumper setting on the multi I/O card.
174 add dx, BYTE QD6580_CONTROL_REGISTER
[582]175 in al, dx ; Read to get ATAPI jumper status
[392]176 test al, FLG_QDCONTROL_HDONLY_in
[582]177 mov al, MASK_QDCONTROL_FLAGS_TO_SET
178 eCMOVNZ al, FLG_QDCONTROL_NONATAPI | MASK_QDCONTROL_FLAGS_TO_SET ; Enable Read-Ahead and Post-Write Buffers
[392]179 out dx, al
[582]180 dec dx ; Secondary Channel IDE Timing Register
[392]181
182 ; Now we need to determine is the drive connected to the Primary or Secondary channel.
183 ; QD6500 has only one channel that can be Primary at 1F0h or Secondary at 170h.
184 ; QD6580 always has Primary channel at 1F0h. Secondary channel at 170h can be Enabled or Disabled.
[582]185 cmp BYTE [di+DPT.wBasePort], DEVICE_ATA_SECONDARY_PORT & 0FFh
186 je SHORT .CalculateTimingsForQD65xx ; Secondary Channel so no need to modify DX
187 dec dx
188 dec dx ; Primary Channel IDE Timing Register
[392]189
190 ; We need the PIO Cycle Time in CX to calculate Active and Recovery Times.
191.CalculateTimingsForQD65xx:
192 call AdvAtaInit_SelectSlowestCommonPioTimingsToBXandCXfromDSSIandDSDI
193
194 ; Calculate Active Time value for QD65xx IDE Timing Register
195 call AtaID_GetActiveTimeToAXfromPioModeInBX
196 call ConvertNanosecsFromAXwithLimitsInBPtoRegisterValue
197 xchg bp, ax
198
199 ; Calculate Recovery Time value for QD65xx IDE Timing Register
200 call AtaID_GetRecoveryTimeToAXfromPioModeInBXandCycleTimeInCX
201 mov bx, bp ; Active Time value now in BL
202 mov bp, QD65xx_MAX_RECOVERY_TIME_CLOCKS | (QD65xx_MIN_RECOVERY_TIME_CLOCKS << 8)
203 call ConvertNanosecsFromAXwithLimitsInBPtoRegisterValue
204
205 ; Merge the values to a single byte to output
[566]206 eSHL_IM al, POSITION_QD65XXIDE_RECOVERY_TIME
[392]207 or al, bl
208 out dx, al
209 ret ; Return with CF cleared
210
211
212;--------------------------------------------------------------------
213; ConvertNanosecsFromAXwithLimitsInBPtoRegisterValue
214; Parameters:
215; AX: Nanosecs to convert
216; BP: Low Byte: Maximum allowed ticks
217; High Byte: Minimum allowed ticks
218; DS:DI: Ptr to DPT for Single or Slave Drive
219; Returns:
220; AL: Timing value for QD65xx register
221; Corrupts registers:
222; Nothing
223;--------------------------------------------------------------------
224ConvertNanosecsFromAXwithLimitsInBPtoRegisterValue:
225 push cx
226
227 ; Get VLB Cycle Time in nanosecs
228 mov cl, VLB_33MHZ_CYCLE_TIME ; Assume 33 MHz or slower VLB bus
229 test BYTE [di+DPT_ADVANCED_ATA.wControllerID], FLG_QDCONFIG_ID3
230 eCMOVZ cl, VLB_40MHZ_CYCLE_TIME
231
232 ; Convert value in AX to VLB ticks
233 div cl ; AL = VLB ticks
234 inc ax ; Round up
235
236 ; Limit value to QD65xx limits
237 mov cx, bp
238 MAX_U al, ch ; Make sure not below minimum
239 MIN_U al, cl ; Make sure not above maximum
240
241 ; Not done yet, we need to invert the ticks since 0 is the slowest
242 ; value on the timing register
243 sub cl, al
244 xchg ax, cx ; Return in AL
245
246 pop cx
247 ret
Note: See TracBrowser for help on using the repository browser.