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

Last change on this file since 616 was 614, checked in by Krister Nordvall, 3 years ago

Changes:

  • BIOSDRVS should now build again (broke in r613).
  • Removed the NO_ATAID_CORRECTION define from the Tiny build.
  • Added a new configuration option to skip detection of slave drives.
  • Made FLASH_SIGNATURE 2 bytes shorter to free up ROM space.
  • "Auto Configure" in XTIDECFG should now detect if running on an Olivetti M24, AT&T PC6300, Xerox 6060 or Logabax Persona 1600 and automatically select the fastest compatible transfer mode/device type for any IDE controllers found in the system.
  • Cleaned out some duplicate/unused definitions.
File size: 11.7 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 mov si, dx
102 mov bx, STATUS_REGISTER_in | (ALTERNATE_STATUS_REGISTER_in << 8)
103 ; *** Try to detect AC-1075 / AC-1070 controllers ***
104 cmp dh, 25h
105 jne SHORT .NotArcoComputerProducts
106 add si, BYTE 8 ; Add control block offset
107 call DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
108 mov al, DEVICE_16BIT_ATA
109 ret
110.NotArcoComputerProducts:
111 ; *** Try to detect Standard 16- and 32-bit IDE Devices ***
112 mov al, DEVICE_16BIT_ATA ; Assume 16-bit ISA slot for AT builds
113 call Buffers_IsXTbuildLoaded
114 eCMOVE al, DEVICE_8BIT_ATA ; Assume 8-bit ISA slot for XT builds
115
116 ; Start with standard Control Block base port used by Primary and Secondary IDE
117 add si, STANDARD_CONTROL_BLOCK_OFFSET
118.RedetectTertiaryOrQuaternaryWithDifferentControlBlockAddress:
119 push ax ; Store device type
120 call DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
121 pop ax ; Restore device type
122 jnc SHORT .IdeDeviceFound
123
124 ; 16- or 32-bit IDE Device was not found but we may have used wrong Control Block port if we were trying
125 ; to detect Tertiary or Quaternary IDE controllers. Control Block port location is not standardized. For
126 ; example Promise FloppyMAX has Control Block at STANDARD_CONTROL_BLOCK_OFFSET but Sound Blaster 16 (CT2290)
127 ; use DEVICE_ATA_SECONDARY_PORTCTRL for Tertiary and Quaternary even though only Secondary should use that.
128 call ChangeControlBlockAddressInSI
129 jz SHORT .RedetectTertiaryOrQuaternaryWithDifferentControlBlockAddress
130
131 ; Detect 8-bit devices only if MODULE_8BIT_IDE is available
132 test BYTE [di+ROMVARS.wFlags], FLG_ROMVARS_MODULE_8BIT_IDE | FLG_ROMVARS_MODULE_8BIT_IDE_ADVANCED
133 jz SHORT NoIdeDeviceFound
134 jpo SHORT .SkipXTCF ; Only 1 bit set means no MODULE_8BIT_IDE_ADVANCED
135
136 ; *** Try to detect XT-CF ***
137 mov si, dx
138 add si, BYTE XTCF_CONTROL_BLOCK_OFFSET
139 eSHL_IM bx, 1 ; SHL 1 register offsets for XT-CF
140 call DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
141 jc SHORT .ContinueDetection
142 mov al, DEVICE_8BIT_XTCF_PIO8_WITH_BIU_OFFLOAD
143 cmp BYTE [cs:IsOlivettiM24], 1
144 jne SHORT .IdeDeviceFound
145 mov al, DEVICE_8BIT_XTCF_PIO8
146 jmp SHORT .IdeDeviceFound
147.ContinueDetection:
148 shr bx, 1
149.SkipXTCF:
150
151 ; *** Try to detect 8-bit XT-IDE rev 1 or rev 2 ***
152 ; Note that A0<->A3 address swaps Status Register and Alternative
153 ; Status Register addresses. That is why we need another step
154 ; to check is this XT-IDE rev 1 or rev 2.
155 mov si, dx
156 add si, BYTE XTIDE_CONTROL_BLOCK_OFFSET
157 call DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
158 jc SHORT NoIdeDeviceFound ; No XT-IDE rev 1 or rev 2 found
159
160 ; Now we can be sure that we have XT-IDE rev 1 or rev 2.
161 ; Rev 2 swaps address lines A0 and A3 thus LBA Low Register
162 ; moves from offset 3h to offset Ah. There is no Register at
163 ; offset Ah so if we can write to it and read back, then we
164 ; must have XT-IDE rev 2 or modded rev 1.
165 push dx
166 add dx, BYTE 0Ah ; LBA Low Register for XT-IDE rev 2
167 mov al, DEVICE_8BIT_XTIDE_REV2 ; Our test byte
168 out dx, al ; Output our test byte
169 JMP_DELAY
170 in al, dx ; Read back
171 pop dx
172 cmp al, DEVICE_8BIT_XTIDE_REV2
173 jne SHORT .XtideRev1
174 cmp BYTE [cs:IsOlivettiM24], 1
175 jne SHORT .IdeDeviceFound
176 mov al, DEVICE_8BIT_XTIDE_REV2_OLIVETTI
177 ret ; With CF cleared
178.XtideRev1:
179 mov al, DEVICE_8BIT_XTIDE_REV1 ; We must have rev 1
180.IdeDeviceFound:
181 clc
182 ret
183
184
185;--------------------------------------------------------------------
186; DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
187; Parameters:
188; BL: Offset to IDE Status Register
189; BH: Offset to Alternative Status Register
190; DX: IDE Base Port address
191; SI: IDE Control Block address
192; Returns:
193; CF: Clear if IDE Device found
194; Set if IDE Device not found
195; Corrupts registers:
196; AX
197;--------------------------------------------------------------------
198DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH:
199 ; Read Status and Alternative Status Registers
200 push dx
201
202 add dl, bl
203 cli ; Disable Interrupts
204 in al, dx ; Read Status Register...
205 mov ah, al ; ...to AH
206 mov dx, si
207 add dl, bh
208 in al, dx ; Read Alternative Status Register to AL
209 sti ; Enable Interrupts
210
211 pop dx
212 ; Fall to CompareIdeStatusRegistersFromALandAH
213
214
215;--------------------------------------------------------------------
216; CompareIdeStatusRegistersFromALandAH
217; Parameters:
218; AH: Possible IDE Status Register contents
219; AL: Possible IDE Alternative Status Register contents
220; Returns:
221; CF: Clear if valid Status Register Contents
222; Set if not possible IDE Status Registers
223; Corrupts registers:
224; Nothing
225;--------------------------------------------------------------------
226CompareIdeStatusRegistersFromALandAH:
227 ; Status Register now in AH and Alternative Status Register in AL.
228 ; They must be the same if base port was in use by IDE device.
229 cmp al, ah
230 jne SHORT NoIdeDeviceFound
231
232 ; Bytes were the same but it is possible they were both FFh, for
233 ; example. We must make sure bits are what is expected from valid
234 ; IDE Status Register. So far all drives I've tested return 50h
235 ; (FLG_STATUS_DRDY and FLG_STATUS_DSC set) or 00h.
236 ; I suspect that the zero might mean non available drive is selected. For example if Master
237 ; drive is present but Slave is selected from IDE Drive and Head Select Register,
238 ; then the Status Register can be 00h. We cannot accept 00h as valid byte
239 ; since that can easily cause invalid JR-IDE/ISA detections.
240 test al, FLG_STATUS_BSY | FLG_STATUS_DF | FLG_STATUS_DRQ | FLG_STATUS_ERR
241 jnz SHORT NoIdeDeviceFound ; Busy or Errors cannot be set
242 test al, FLG_STATUS_DRDY
243 jz SHORT NoIdeDeviceFound ; Device needs to be ready
244 ret ; Return with CF cleared
245
246NoIdeDeviceFound:
247 stc
248 ret
249
250
251;--------------------------------------------------------------------
252; ChangeControlBlockAddressInSI
253; Parameters:
254; DX: IDE Base Port address
255; SI: IDE Control Block address
256; Returns:
257; ZF: Set if SI changed
258; Cleared if different control block address is not possible
259; Corrupts registers:
260; Nothing
261;--------------------------------------------------------------------
262ChangeControlBlockAddressInSI:
263 cmp si, 368h
264 je SHORT .TrySecondAlternative
265 cmp si, 3E8h
266 je SHORT .TrySecondAlternative
267
268 cmp si, 360h
269 je SHORT .TryLastAlternative
270 cmp si, 3E0h
271 jne SHORT .Return ; With ZF cleared
272
273.TryLastAlternative:
274 mov si, DEVICE_ATA_SECONDARY_PORTCTRL + 8 ; Changes to 370h used by Sound Blaster 16 (CT2290)
275 ; Fall to .TrySecondAlternative
276.TrySecondAlternative:
277 lea si, [si-8] ; 368h to 360h, 3E8h to 3E0h
278.Return:
279 ret
280
281
282;--------------------------------------------------------------------
283; IdeAutodetect_IncrementDXtoNextIdeBasePort
284; Parameters:
285; DX: Previous IDE Base Port or IDE_PORT_TO_START_DETECTION
286; Returns:
287; DX: Next IDE Base Port
288; ZF: Set if no more Base Ports (DX was last base port on entry)
289; Clear if new base port returned in DX
290; Corrupts registers:
291; AX
292;--------------------------------------------------------------------
293ALIGN JUMP_ALIGN
294IdeAutodetect_IncrementDXtoNextIdeBasePort:
295 cmp dx, [cs:.wLastIdePort]
296 je SHORT .AllPortsAlreadyDetected
297
298 push si
299 mov si, .rgwIdeBasePorts
300.CompareNextIdeBasePort:
301 cmp [cs:si], dx
302 lea si, [si+2] ; Increment SI and preserve FLAGS
303 jne SHORT .CompareNextIdeBasePort
304
305 mov dx, [cs:si] ; Get next port
306 test dx, dx ; Clear ZF
307 pop si
308.AllPortsAlreadyDetected:
309 ret
310
311
312 ; All ports used in autodetection. Ports can be in any order.
313ALIGN WORD_ALIGN
314.rgwIdeBasePorts:
315 dw IDE_PORT_TO_START_DETECTION ; Must be first
316 ; Standard IDE
317 dw DEVICE_ATA_PRIMARY_PORT
318 dw DEVICE_ATA_SECONDARY_PORT
319 dw DEVICE_ATA_TERTIARY_PORT
320 dw DEVICE_ATA_QUATERNARY_PORT
321 ; 8-bit Devices
322 dw 200h
323 dw 220h
324 dw 240h
325 dw 260h
326 dw 280h
327 dw 2A0h
328 dw 2C0h
329 dw 2E0h
330 dw 300h
331 dw 320h
332 dw 340h
333 dw 360h
334 dw 380h
335 dw 3A0h
336 dw 3C0h
337 dw 3E0h
338 ; Arco Computer Products AC-1075 / AC-1070 (16-bit MCA IDE adapters with Control Block at +8 and no IRQ)
339 dw 2510h
340 dw 2520h
341 ; Memory Segment Addresses
342 dw 0C000h ; JR-IDE/ISA
343 dw 0C400h ; JR-IDE/ISA
344 dw 0C800h ; JR-IDE/ISA and ADP50L
345 dw 0CA00h ; ADP50L
346 dw 0CC00h ; JR-IDE/ISA and ADP50L
347 dw 0CE00h ; ADP50L
348 dw 0D000h ; JR-IDE/ISA
349 dw 0D400h ; JR-IDE/ISA
350 dw 0D800h ; JR-IDE/ISA
351.wLastIdePort:
352 dw 0DC00h ; JR-IDE/ISA
Note: See TracBrowser for help on using the repository browser.