source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/IdeAutodetect.asm@ 599

Last change on this file since 599 was 592, checked in by Krister Nordvall, 6 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: 11.1 KB
Line 
1; Project name : XTIDE Universal BIOS Configurator v2
2; Description : Functions to detect ports and devices.
3
4;
5; XTIDE Universal BIOS and Associated Tools
6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
7;
8; This program is free software; you can redistribute it and/or modify
9; it under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2 of the License, or
11; (at your option) any later version.
12;
13; This program is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16; GNU General Public License for more details.
17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18;
19
20; Section containing code
21SECTION .text
22
23IDE_PORT_TO_START_DETECTION EQU 00h ; Must be zero (not actual port)
24FIRST_MEMORY_SEGMENT_ADDRESS EQU 0C000h
25
26;--------------------------------------------------------------------
27; IdeAutodetect_DetectIdeDeviceFromPortDXAndReturnControlBlockInSI
28; Parameters:
29; DX: IDE Base Port or segment address (Command Block)
30; DS:DI: Ptr to ROMVARS
31; Returns:
32; AL: Device Type
33; SI: IDE Control Block Base port (port mapped devices only)
34; CF: Clear if IDE Device found
35; Set if IDE Device not found
36; Corrupts registers:
37; AH, BX
38;--------------------------------------------------------------------
39IdeAutodetect_DetectIdeDeviceFromPortDXAndReturnControlBlockInSI:
40 cmp dh, FIRST_MEMORY_SEGMENT_ADDRESS >> 8
41 jb SHORT DetectPortMappedDeviceFromPortDX
42 ; Fall to DetectMemoryMappedDeviceFromSegmentDX
43
44;--------------------------------------------------------------------
45; DetectMemoryMappedDeviceFromSegmentDX
46; Parameters:
47; DX: Segment address for Memory Mapped Device
48; DS:DI: Ptr to ROMVARS
49; Returns:
50; AL: Device Type
51; CF: Clear if IDE Device found
52; Set if IDE Device not found
53; Corrupts registers:
54; AH, BX
55;--------------------------------------------------------------------
56DetectMemoryMappedDeviceFromSegmentDX:
57 ; *** Try to detect JR-IDE/ISA and ADP50L (only if MODULE_8BIT_IDE_ADVANCED is present) ***
58 test BYTE [di+ROMVARS.wFlags], FLG_ROMVARS_MODULE_8BIT_IDE_ADVANCED
59 stc
60 jz SHORT .NoIdeDeviceFound
61
62 push ds
63 mov ds, dx
64
65 cli
66 mov ah, [JRIDE_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET + STATUS_REGISTER_in]
67 mov al, [JRIDE_CONTROL_BLOCK_REGISTER_WINDOW_OFFSET + ALTERNATE_STATUS_REGISTER_in]
68 sti
69 call CompareIdeStatusRegistersFromALandAH
70 mov al, DEVICE_8BIT_JRIDE_ISA
71 jnc .IdeDeviceFound
72
73 cli
74 mov ah, [ADP50L_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET + (STATUS_REGISTER_in << 1)]
75 mov al, [ADP50L_CONTROL_BLOCK_REGISTER_WINDOW_OFFSET + (ALTERNATE_STATUS_REGISTER_in << 1)]
76 sti
77 call CompareIdeStatusRegistersFromALandAH
78 mov al, DEVICE_8BIT_ADP50L
79
80.IdeDeviceFound:
81 mov si, dx ; For IDEDTCT.COM
82 pop ds
83.NoIdeDeviceFound:
84 ret
85
86
87;--------------------------------------------------------------------
88; DetectPortMappedDeviceFromPortDX
89; Parameters:
90; DX: IDE Base Port (Command Block)
91; DS:DI: Ptr to ROMVARS
92; Returns:
93; AL: Device Type
94; SI: IDE Control Block Base port
95; CF: Clear if IDE Device found
96; Set if IDE Device not found
97; Corrupts registers:
98; AH, BX
99;--------------------------------------------------------------------
100DetectPortMappedDeviceFromPortDX:
101 ; *** Try to detect Standard 16- and 32-bit IDE Devices ***
102 mov al, DEVICE_16BIT_ATA ; Assume 16-bit ISA slot for AT builds
103 call Buffers_IsXTbuildLoaded
104 eCMOVE al, DEVICE_8BIT_ATA ; Assume 8-bit ISA slot for XT builds
105
106 ; Start with standard Control Block base port used by Primary and Secondary IDE
107 mov si, dx
108 add si, STANDARD_CONTROL_BLOCK_OFFSET
109 mov bx, STATUS_REGISTER_in | (ALTERNATE_STATUS_REGISTER_in << 8)
110.RedetectTertiaryOrQuaternaryWithDifferentControlBlockAddress:
111 push ax ; Store device type
112 call DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
113 pop ax ; Restore device type
114 jnc SHORT .IdeDeviceFound
115
116 ; 16- or 32-bit IDE Device was not found but we may have used wrong Control Block port if we were trying
117 ; to detect Tertiary or Quaternary IDE controllers. Control Block port location is not standardized. For
118 ; example Promise FloppyMAX has Control Block at STANDARD_CONTROL_BLOCK_OFFSET but Sound Blaster 16 (CT2290)
119 ; use DEVICE_ATA_SECONDARY_PORTCTRL for Tertiary and Quaternary even though only Secondary should use that.
120 call ChangeControlBlockAddressInSI
121 jz SHORT .RedetectTertiaryOrQuaternaryWithDifferentControlBlockAddress
122
123
124 ; Detect 8-bit devices only if MODULE_8BIT_IDE is available
125 test BYTE [di+ROMVARS.wFlags], FLG_ROMVARS_MODULE_8BIT_IDE | FLG_ROMVARS_MODULE_8BIT_IDE_ADVANCED
126 jz SHORT NoIdeDeviceFound
127 jpo SHORT .SkipXTCF ; Only 1 bit set means no MODULE_8BIT_IDE_ADVANCED
128
129 ; *** Try to detect XT-CF ***
130 mov si, dx
131 add si, BYTE XTCF_CONTROL_BLOCK_OFFSET
132 eSHL_IM bx, 1 ; SHL 1 register offsets for XT-CF
133 call DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
134 mov al, DEVICE_8BIT_XTCF_PIO8
135 jnc SHORT .IdeDeviceFound
136 shr bx, 1
137.SkipXTCF:
138
139 ; *** Try to detect 8-bit XT-IDE rev 1 or rev 2 ***
140 ; Note that A0<->A3 address swaps Status Register and Alternative
141 ; Status Register addresses. That is why we need another step
142 ; to check is this XT-IDE rev 1 or rev 2.
143 mov si, dx
144 add si, BYTE XTIDE_CONTROL_BLOCK_OFFSET
145 call DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
146 jc SHORT NoIdeDeviceFound ; No XT-IDE rev 1 or rev 2 found
147
148 ; Now we can be sure that we have XT-IDE rev 1 or rev 2.
149 ; Rev 2 swaps address lines A0 and A3 thus LBA Low Register
150 ; moves from offset 3h to offset Ah. There is no Register at
151 ; offset Ah so if we can write to it and read back, then we
152 ; must have XT-IDE rev 2 or modded rev 1.
153 push dx
154 add dx, BYTE 0Ah ; LBA Low Register for XT-IDE rev 2
155 mov al, DEVICE_8BIT_XTIDE_REV2 ; Our test byte
156 out dx, al ; Output our test byte
157 JMP_DELAY
158 in al, dx ; Read back
159 pop dx
160 cmp al, DEVICE_8BIT_XTIDE_REV2
161 je SHORT .IdeDeviceFound
162 mov al, DEVICE_8BIT_XTIDE_REV1 ; We must have rev 1
163.IdeDeviceFound:
164 clc
165 ret
166
167
168;--------------------------------------------------------------------
169; DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
170; Parameters:
171; BL: Offset to IDE Status Register
172; BH: Offset to Alternative Status Register
173; DX: IDE Base Port address
174; SI: IDE Control Block address
175; Returns:
176; CF: Clear if IDE Device found
177; Set if IDE Device not found
178; Corrupts registers:
179; AX
180;--------------------------------------------------------------------
181DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH:
182 ; Read Status and Alternative Status Registers
183 push dx
184
185 add dl, bl
186 cli ; Disable Interrupts
187 in al, dx ; Read Status Register...
188 mov ah, al ; ...to AH
189 mov dx, si
190 add dl, bh
191 in al, dx ; Read Alternative Status Register to AL
192 sti ; Enable Interrupts
193
194 pop dx
195 ; Fall to CompareIdeStatusRegistersFromALandAH
196
197
198;--------------------------------------------------------------------
199; CompareIdeStatusRegistersFromALandAH
200; Parameters:
201; AH: Possible IDE Status Register contents
202; AL: Possible IDE Alternative Status Register contents
203; Returns:
204; CF: Clear if valid Status Register Contents
205; Set if not possible IDE Status Registers
206; Corrupts registers:
207; Nothing
208;--------------------------------------------------------------------
209CompareIdeStatusRegistersFromALandAH:
210 ; Status Register now in AH and Alternative Status Register in AL.
211 ; They must be the same if base port was in use by IDE device.
212 cmp al, ah
213 jne SHORT NoIdeDeviceFound
214
215 ; Bytes were the same but it is possible they were both FFh, for
216 ; example. We must make sure bits are what is expected from valid
217 ; IDE Status Register. So far all drives I've tested return 50h
218 ; (FLG_STATUS_DRDY and FLG_STATUS_DSC set) or 00h.
219 ; I suspect that the zero might mean non available drive is selected. For example if Master
220 ; drive is present but Slave is selected from IDE Drive and Head Select Register,
221 ; then the Status Register can be 00h. We cannot accept 00h as valid byte
222 ; since that can easily cause invalid JR-IDE/ISA detections.
223 test al, FLG_STATUS_BSY | FLG_STATUS_DF | FLG_STATUS_DRQ | FLG_STATUS_ERR
224 jnz SHORT NoIdeDeviceFound ; Busy or Errors cannot be set
225 test al, FLG_STATUS_DRDY
226 jz SHORT NoIdeDeviceFound ; Device needs to be ready
227 ret ; Return with CF cleared
228
229NoIdeDeviceFound:
230 stc
231 ret
232
233
234;--------------------------------------------------------------------
235; ChangeControlBlockAddressInSI
236; Parameters:
237; DX: IDE Base Port address
238; SI: IDE Control Block address
239; Returns:
240; ZF: Set if SI changed
241; Cleared if different control block address is not possible
242; Corrupts registers:
243; Nothing
244;--------------------------------------------------------------------
245ChangeControlBlockAddressInSI:
246 cmp si, 368h
247 je SHORT .TrySecondAlternative
248 cmp si, 3E8h
249 je SHORT .TrySecondAlternative
250
251 cmp si, 360h
252 je SHORT .TryLastAlternative
253 cmp si, 3E0h
254 jne SHORT .Return ; With ZF cleared
255
256.TryLastAlternative:
257 mov si, DEVICE_ATA_SECONDARY_PORTCTRL + 8 ; Changes to 370h used by Sound Blaster 16 (CT2290)
258 ; Fall to .TrySecondAlternative
259.TrySecondAlternative:
260 sub si, BYTE 8h ; 368h to 360h, 3E8h to 3E0h
261 cmp sp, sp ; Set ZF
262.Return:
263 ret
264
265
266;--------------------------------------------------------------------
267; IdeAutodetect_IncrementDXtoNextIdeBasePort
268; Parameters:
269; DX: Previous IDE Base Port or IDE_PORT_TO_START_DETECTION
270; Returns:
271; DX: Next IDE Base Port
272; ZF: Set if no more Base Ports (DX was last base port on entry)
273; Clear if new base port returned in DX
274; Corrupts registers:
275; AX
276;--------------------------------------------------------------------
277ALIGN JUMP_ALIGN
278IdeAutodetect_IncrementDXtoNextIdeBasePort:
279 cmp dx, [cs:.wLastIdePort]
280 je SHORT .AllPortsAlreadyDetected
281
282 push si
283 mov si, .rgwIdeBasePorts
284.CompareNextIdeBasePort:
285 cmp [cs:si], dx
286 lea si, [si+2] ; Increment SI and preserve FLAGS
287 jne SHORT .CompareNextIdeBasePort
288
289 mov dx, [cs:si] ; Get next port
290 test dx, dx ; Clear ZF
291 pop si
292.AllPortsAlreadyDetected:
293 ret
294
295
296 ; All ports used in autodetection. Ports can be in any order.
297ALIGN WORD_ALIGN
298.rgwIdeBasePorts:
299 dw IDE_PORT_TO_START_DETECTION ; Must be first
300 ; Standard IDE
301 dw DEVICE_ATA_PRIMARY_PORT
302 dw DEVICE_ATA_SECONDARY_PORT
303 dw DEVICE_ATA_TERTIARY_PORT
304 dw DEVICE_ATA_QUATERNARY_PORT
305 ; 8-bit Devices
306 dw 200h
307 dw 220h
308 dw 240h
309 dw 260h
310 dw 280h
311 dw 2A0h
312 dw 2C0h
313 dw 2E0h
314 dw 300h
315 dw 320h
316 dw 340h
317 dw 360h
318 dw 380h
319 dw 3A0h
320 dw 3C0h
321 dw 3E0h
322 ; Memory Segment Addresses
323 dw 0C000h ; JR-IDE/ISA
324 dw 0C400h ; JR-IDE/ISA
325 dw 0C800h ; JR-IDE/ISA and ADP50L
326 dw 0CA00h ; ADP50L
327 dw 0CC00h ; JR-IDE/ISA and ADP50L
328 dw 0CE00h ; ADP50L
329 dw 0D000h ; JR-IDE/ISA
330 dw 0D400h ; JR-IDE/ISA
331 dw 0D800h ; JR-IDE/ISA
332.wLastIdePort:
333 dw 0DC00h ; JR-IDE/ISA
Note: See TracBrowser for help on using the repository browser.