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

Last change on this file since 511 was 505, checked in by krille_n_@…, 11 years ago

Changes:

  • Reverted the changes to MenuEvents.inc done in r492 since they broke the F1 key function in XTIDECFG.
  • Added a tail-call optimized variant of the CALL_DISPLAY_LIBRARY macro (JMP_DISPLAY_LIBRARY).
  • Put a block size limit in AH1Eh_ChangeXTCFmodeBasedOnControlRegisterInAL. I think it's needed but if not, it's easy to remove.
  • Other optimizations and fixes.
File size: 10.3 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-2012 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
23;--------------------------------------------------------------------
24; IdeAutodetect_DetectIdeDeviceFromPortDXAndReturnControlBlockInSI
25; Parameters:
26; DX: IDE Base Port or segment address (Command Block)
27; DS:DI: Ptr to ROMVARS
28; Returns:
29; AL: Device Type
30; SI: IDE Control Block Base port (port mapped devices only)
31; CF: Clear if IDE Device found
32; Set if IDE Device not found
33; Corrupts registers:
34; AH, BX
35;--------------------------------------------------------------------
36IdeAutodetect_DetectIdeDeviceFromPortDXAndReturnControlBlockInSI:
37 cmp dx, FIRST_MEMORY_SEGMENT_ADDRESS
38 jb SHORT DetectPortMappedDeviceFromPortDX
39 ; Fall to DetectMemoryMappedDeviceFromSegmentDX
40
41;--------------------------------------------------------------------
42; DetectMemoryMappedDeviceFromSegmentDX
43; Parameters:
44; DX: Segment address for Memory Mapped Device
45; DS:DI: Ptr to ROMVARS
46; Returns:
47; AL: Device Type
48; CF: Clear if IDE Device found
49; Set if IDE Device not found
50; Corrupts registers:
51; AH, BX
52;--------------------------------------------------------------------
53DetectMemoryMappedDeviceFromSegmentDX:
54 ; *** Try to detect JR-IDE/ISA (only if MODULE_8BIT_IDE_ADVANCED is present) ***
55 test WORD [di+ROMVARS.wFlags], FLG_ROMVARS_MODULE_8BIT_IDE_ADVANCED
56 jz SHORT NoIdeDeviceFound
57
58 push ds
59 mov ds, dx
60 cli ; Disable Interrupts
61 mov ah, [JRIDE_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET + STATUS_REGISTER_in]
62 mov al, [JRIDE_CONTROL_BLOCK_REGISTER_WINDOW_OFFSET + ALTERNATE_STATUS_REGISTER_in]
63 sti ; Enable Interrupts
64 pop ds
65 call CompareIdeStatusRegistersFromALandAH
66 mov al, DEVICE_8BIT_JRIDE_ISA ; Assume CF was cleared
67 ret ; No need to return Control Block Port
68
69
70;--------------------------------------------------------------------
71; DetectPortMappedDeviceFromPortDX
72; Parameters:
73; DX: IDE Base Port (Command Block)
74; DS:DI: Ptr to ROMVARS
75; Returns:
76; AL: Device Type
77; SI: IDE Control Block Base port
78; CF: Clear if IDE Device found
79; Set if IDE Device not found
80; Corrupts registers:
81; AH, BX
82;--------------------------------------------------------------------
83DetectPortMappedDeviceFromPortDX:
84 ; *** Try to detect Standard 16- and 32-bit IDE Devices ***
85 mov al, DEVICE_16BIT_ATA ; Assume 16-bit ISA slot for AT builds
86 call Buffers_IsXTbuildLoaded
87 eCMOVE al, DEVICE_8BIT_ATA ; Assume 8-bit ISA slot for XT builds
88
89 ; Start with standard Control Block base port used by Primary and Secondary IDE
90 mov si, dx
91 add si, STANDARD_CONTROL_BLOCK_OFFSET
92 mov bx, STATUS_REGISTER_in | (ALTERNATE_STATUS_REGISTER_in << 8)
93.RedetectTertiaryOrQuaternaryWithDifferentControlBlockAddress:
94 push ax ; Store device type
95 call DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
96 pop ax ; Restore device type
97 jnc SHORT .IdeDeviceFound
98
99 ; 16- or 32-bit IDE Device was not found but we may have used wrong Control Block port if we were trying
100 ; to detect Tertiary or Quaternary IDE controllers. Control Block port location is not standardized. For
101 ; example Promise FloppyMAX has Control Block at STANDARD_CONTROL_BLOCK_OFFSET but Sound Blaster 16 (CT2290)
102 ; use DEVICE_ATA_SECONDARY_PORTCTRL for Tertiary and Quaternary even though only Secondary should use that.
103 call ChangeDifferentControlBlockAddressToSI
104 je SHORT .RedetectTertiaryOrQuaternaryWithDifferentControlBlockAddress
105
106
107 ; Detect 8-bit devices only if MODULE_8BIT_IDE is available
108 test BYTE [di+ROMVARS.wFlags], FLG_ROMVARS_MODULE_8BIT_IDE
109 jz SHORT NoIdeDeviceFound
110
111 ; *** Try to detect XT-CF ***
112 mov si, dx
113 add si, BYTE XTCF_CONTROL_BLOCK_OFFSET
114 shl bx, 1 ; SHL 1 register offsets for XT-CF
115 call DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
116 mov al, DEVICE_8BIT_XTCF_PIO8
117 jnc SHORT .IdeDeviceFound
118
119
120 ; *** Try to detect 8-bit XT-IDE rev 1 or rev 2 ***
121 ; Note that A0<->A3 address swaps Status Register and Alternative
122 ; Status Register addresses. That is why we need another step
123 ; to check is this XT-IDE rev 1 or rev 2.
124 sub si, BYTE XTCF_CONTROL_BLOCK_OFFSET >> 1
125 shr bx, 1
126 call DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
127 jc SHORT NoIdeDeviceFound ; No XT-IDE rev 1 or rev 2 found
128
129 ; Now we can be sure that we have XT-IDE rev 1 or rev 2.
130 ; Rev 2 swaps address lines A0 and A3 thus LBA Low Register
131 ; moves from offset 3h to offset Ah. There is no Register at
132 ; offset Ah so if we can write to it and read back, then we
133 ; must have XT-IDE rev 2 or modded rev 1.
134 push dx
135 add dx, BYTE 0Ah ; LBA Low Register for XT-IDE rev 2
136 mov al, DEVICE_8BIT_XTIDE_REV2 ; Our test byte
137 out dx, al ; Output our test byte
138 JMP_DELAY
139 in al, dx ; Read back
140 pop dx
141 cmp al, DEVICE_8BIT_XTIDE_REV2
142 je SHORT .IdeDeviceFound
143 mov al, DEVICE_8BIT_XTIDE_REV1 ; We must have rev 1
144.IdeDeviceFound:
145 ret
146
147
148;--------------------------------------------------------------------
149; DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
150; Parameters:
151; BL: Offset to IDE Status Register
152; BH: Offset to Alternative Status Register
153; DX: IDE Base Port address
154; SI: IDE Control Block address
155; Returns:
156; CF: Clear if IDE Device found
157; Set if IDE Device not found
158; Corrupts registers:
159; AX
160;--------------------------------------------------------------------
161DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH:
162 ; Read Status and Alternative Status Registers
163 push dx
164
165 add dl, bl
166 cli ; Disable Interrupts
167 in al, dx ; Read Status Register...
168 mov ah, al ; ...to AH
169 mov dx, si
170 add dl, bh
171 in al, dx ; Read Alternative Status Register to AL
172 sti ; Enable Interrupts
173
174 pop dx
175 ; Fall to CompareIdeStatusRegistersFromALandAH
176
177
178;--------------------------------------------------------------------
179; CompareIdeStatusRegistersFromALandAH
180; Parameters:
181; AH: Possible IDE Status Register contents
182; AL: Possible IDE Alternative Status Register contents
183; Returns:
184; CF: Clear if valid Status Register Contents
185; Set if not possible IDE Status Registers
186; Corrupts registers:
187; Nothing
188;--------------------------------------------------------------------
189CompareIdeStatusRegistersFromALandAH:
190 ; Status Register now in AH and Alternative Status Register in AL.
191 ; They must be the same if base port was in use by IDE device.
192 cmp al, ah
193 jne SHORT .InvalidStatusRegister
194
195 ; Bytes were the same but it is possible they were both FFh, for
196 ; example. We must make sure bits are what is expected from valid
197 ; IDE Status Register. So far all drives I've tested return 50h
198 ; (FLG_STATUS_DRDY and FLG_STATUS_DSC set) unless there is only
199 ; one drive present but wrong drive is selected. For example if Master
200 ; drive is present but Slave is selected from IDE Drive and Head Select Register,
201 ; then the Status Register can be 00h.
202 test al, FLG_STATUS_BSY | FLG_STATUS_DF | FLG_STATUS_DRQ | FLG_STATUS_ERR
203 jnz SHORT .InvalidStatusRegister ; Busy or Errors cannot be set
204 test al, FLG_STATUS_DRDY
205 jz SHORT .InvalidStatusRegister ; Device needs to be ready
206 ret ; Return with CF cleared
207
208.InvalidStatusRegister:
209NoIdeDeviceFound:
210 stc
211 ret
212
213
214;--------------------------------------------------------------------
215; ChangeDifferentControlBlockAddressToSI
216; Parameters:
217; DX: IDE Base Port address
218; SI: IDE Control Block address
219; Returns:
220; ZF: Set if SI changed
221; Cleared if different control block address is not possible
222; Corrupts registers:
223; AH
224;--------------------------------------------------------------------
225ChangeDifferentControlBlockAddressToSI:
226 cmp si, 368h
227 je SHORT .TrySecondAlternative
228 cmp si, 3E8h
229 je SHORT .TrySecondAlternative
230
231 cmp si, 360h
232 je SHORT .TryLastAlternative
233 cmp si, 3E0h
234 je SHORT .TryLastAlternative
235 ret ; Return with ZF cleared
236
237.TryLastAlternative:
238 mov si, DEVICE_ATA_SECONDARY_PORTCTRL + 8 ; Changes to 370h used by Sound Blaster 16 (CT2290)
239 ; Fall to .TrySecondAlternative
240.TrySecondAlternative:
241 sub si, BYTE 8h ; 368h to 360h, 3E8h to 3E0h
242 xor ah, ah ; Set ZF
243 ret
244
245
246;--------------------------------------------------------------------
247; IdeAutodetect_IncrementDXtoNextIdeBasePort
248; Parameters:
249; DX: Previous IDE Base Port
250; Returns:
251; DX: Next IDE Base Port
252; ZF: Set if no more Base Ports (DX was last base port on entry)
253; Clear if new base port returned in DX
254; Corrupts registers:
255; AX
256;--------------------------------------------------------------------
257ALIGN JUMP_ALIGN
258IdeAutodetect_IncrementDXtoNextIdeBasePort:
259 cmp dx, [cs:.wLastIdePort]
260 je SHORT .AllPortsAlreadyDetected
261
262 push si
263 mov si, .rgwIdeBasePorts
264.CompareNextIdeBasePort:
265 cmp [cs:si], dx
266 lea si, [si+2] ; Increment SI and preserve FLAGS
267 jne SHORT .CompareNextIdeBasePort
268
269 mov dx, [cs:si] ; Get next port
270 test dx, dx ; Clear ZF
271 pop si
272.AllPortsAlreadyDetected:
273 ret
274
275
276 ; All ports used in autodetection. Ports can be in any order.
277ALIGN WORD_ALIGN
278.rgwIdeBasePorts:
279 dw IDE_PORT_TO_START_DETECTION ; Must be first
280 ; Standard IDE
281 dw DEVICE_ATA_PRIMARY_PORT
282 dw DEVICE_ATA_SECONDARY_PORT
283 dw DEVICE_ATA_TERTIARY_PORT
284 dw DEVICE_ATA_QUATERNARY_PORT
285 ; 8-bit Devices
286 dw 200h
287 dw 220h
288 dw 240h
289 dw 260h
290 dw 280h
291 dw 2A0h
292 dw 2C0h
293 dw 2E0h
294 dw 300h
295 dw 320h
296 dw 340h
297 dw 360h
298 dw 380h
299 dw 3A0h
300 dw 3C0h
301 dw 3E0h
302 ; JR-IDE/ISA (Memory Segment Addresses)
303 dw 0C000h
304 dw 0C400h
305 dw 0C800h
306 dw 0CC00h
307 dw 0D000h
308 dw 0D400h
309 dw 0D800h
310.wLastIdePort:
311 dw 0DC00h
Note: See TracBrowser for help on using the repository browser.