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

Last change on this file since 609 was 609, checked in by krille_n_, 3 years ago

Changes:

  • Added autodetection of Arco Computer Products AC-1075 / AC-1070 controllers to XTIDECFG. These are MCA bus controllers and probably rare as hens teeth but apparently compatible with XUB as one person has confirmed using an AC-1075 as a regular 16-bit IDE controller. The port ranges used by these controllers are not used by anything else according to RBIL so autodetection should be fairly safe.
File size: 11.4 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    mov     al, DEVICE_8BIT_XTCF_PIO8
142    jnc     SHORT .IdeDeviceFound
143    shr     bx, 1
144.SkipXTCF:
145
146    ; *** Try to detect 8-bit XT-IDE rev 1 or rev 2 ***
147    ; Note that A0<->A3 address swaps Status Register and Alternative
148    ; Status Register addresses. That is why we need another step
149    ; to check is this XT-IDE rev 1 or rev 2.
150    mov     si, dx
151    add     si, BYTE XTIDE_CONTROL_BLOCK_OFFSET
152    call    DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
153    jc      SHORT NoIdeDeviceFound      ; No XT-IDE rev 1 or rev 2 found
154
155    ; Now we can be sure that we have XT-IDE rev 1 or rev 2.
156    ; Rev 2 swaps address lines A0 and A3 thus LBA Low Register
157    ; moves from offset 3h to offset Ah. There is no Register at
158    ; offset Ah so if we can write to it and read back, then we
159    ; must have XT-IDE rev 2 or modded rev 1.
160    push    dx
161    add     dx, BYTE 0Ah                ; LBA Low Register for XT-IDE rev 2
162    mov     al, DEVICE_8BIT_XTIDE_REV2  ; Our test byte
163    out     dx, al                      ; Output our test byte
164    JMP_DELAY
165    in      al, dx                      ; Read back
166    pop     dx
167    cmp     al, DEVICE_8BIT_XTIDE_REV2
168    je      SHORT .IdeDeviceFound
169    mov     al, DEVICE_8BIT_XTIDE_REV1  ; We must have rev 1
170.IdeDeviceFound:
171    clc
172    ret
173
174
175;--------------------------------------------------------------------
176; DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
177;   Parameters:
178;       BL:     Offset to IDE Status Register
179;       BH:     Offset to Alternative Status Register
180;       DX:     IDE Base Port address
181;       SI:     IDE Control Block address
182;   Returns:
183;       CF:     Clear if IDE Device found
184;               Set if IDE Device not found
185;   Corrupts registers:
186;       AX
187;--------------------------------------------------------------------
188DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH:
189    ; Read Status and Alternative Status Registers
190    push    dx
191
192    add     dl, bl
193    cli                         ; Disable Interrupts
194    in      al, dx              ; Read Status Register...
195    mov     ah, al              ; ...to AH
196    mov     dx, si
197    add     dl, bh
198    in      al, dx              ; Read Alternative Status Register to AL
199    sti                         ; Enable Interrupts
200
201    pop     dx
202    ; Fall to CompareIdeStatusRegistersFromALandAH
203
204
205;--------------------------------------------------------------------
206; CompareIdeStatusRegistersFromALandAH
207;   Parameters:
208;       AH:     Possible IDE Status Register contents
209;       AL:     Possible IDE Alternative Status Register contents
210;   Returns:
211;       CF:     Clear if valid Status Register Contents
212;               Set if not possible IDE Status Registers
213;   Corrupts registers:
214;       Nothing
215;--------------------------------------------------------------------
216CompareIdeStatusRegistersFromALandAH:
217    ; Status Register now in AH and Alternative Status Register in AL.
218    ; They must be the same if base port was in use by IDE device.
219    cmp     al, ah
220    jne     SHORT NoIdeDeviceFound
221
222    ; Bytes were the same but it is possible they were both FFh, for
223    ; example. We must make sure bits are what is expected from valid
224    ; IDE Status Register. So far all drives I've tested return 50h
225    ; (FLG_STATUS_DRDY and FLG_STATUS_DSC set) or 00h.
226    ; I suspect that the zero might mean non available drive is selected. For example if Master
227    ; drive is present but Slave is selected from IDE Drive and Head Select Register,
228    ; then the Status Register can be 00h. We cannot accept 00h as valid byte
229    ; since that can easily cause invalid JR-IDE/ISA detections.
230    test    al, FLG_STATUS_BSY | FLG_STATUS_DF | FLG_STATUS_DRQ | FLG_STATUS_ERR
231    jnz     SHORT NoIdeDeviceFound  ; Busy or Errors cannot be set
232    test    al, FLG_STATUS_DRDY
233    jz      SHORT NoIdeDeviceFound  ; Device needs to be ready
234    ret                             ; Return with CF cleared
235
236NoIdeDeviceFound:
237    stc
238    ret
239
240
241;--------------------------------------------------------------------
242; ChangeControlBlockAddressInSI
243;   Parameters:
244;       DX:     IDE Base Port address
245;       SI:     IDE Control Block address
246;   Returns:
247;       ZF:     Set if SI changed
248;               Cleared if different control block address is not possible
249;   Corrupts registers:
250;       Nothing
251;--------------------------------------------------------------------
252ChangeControlBlockAddressInSI:
253    cmp     si, 368h
254    je      SHORT .TrySecondAlternative
255    cmp     si, 3E8h
256    je      SHORT .TrySecondAlternative
257
258    cmp     si, 360h
259    je      SHORT .TryLastAlternative
260    cmp     si, 3E0h
261    jne     SHORT .Return   ; With ZF cleared
262
263.TryLastAlternative:
264    mov     si, DEVICE_ATA_SECONDARY_PORTCTRL + 8   ; Changes to 370h used by Sound Blaster 16 (CT2290)
265    ; Fall to .TrySecondAlternative
266.TrySecondAlternative:
267    lea     si, [si-8]      ; 368h to 360h, 3E8h to 3E0h
268.Return:
269    ret
270
271
272;--------------------------------------------------------------------
273; IdeAutodetect_IncrementDXtoNextIdeBasePort
274;   Parameters:
275;       DX:     Previous IDE Base Port or IDE_PORT_TO_START_DETECTION
276;   Returns:
277;       DX:     Next IDE Base Port
278;       ZF:     Set if no more Base Ports (DX was last base port on entry)
279;               Clear if new base port returned in DX
280;   Corrupts registers:
281;       AX
282;--------------------------------------------------------------------
283ALIGN JUMP_ALIGN
284IdeAutodetect_IncrementDXtoNextIdeBasePort:
285    cmp     dx, [cs:.wLastIdePort]
286    je      SHORT .AllPortsAlreadyDetected
287
288    push    si
289    mov     si, .rgwIdeBasePorts
290.CompareNextIdeBasePort:
291    cmp     [cs:si], dx
292    lea     si, [si+2]          ; Increment SI and preserve FLAGS
293    jne     SHORT .CompareNextIdeBasePort
294
295    mov     dx, [cs:si]         ; Get next port
296    test    dx, dx              ; Clear ZF
297    pop     si
298.AllPortsAlreadyDetected:
299    ret
300
301
302    ; All ports used in autodetection. Ports can be in any order.
303ALIGN WORD_ALIGN
304.rgwIdeBasePorts:
305    dw      IDE_PORT_TO_START_DETECTION     ; Must be first
306    ; Standard IDE
307    dw      DEVICE_ATA_PRIMARY_PORT
308    dw      DEVICE_ATA_SECONDARY_PORT
309    dw      DEVICE_ATA_TERTIARY_PORT
310    dw      DEVICE_ATA_QUATERNARY_PORT
311    ; 8-bit Devices
312    dw      200h
313    dw      220h
314    dw      240h
315    dw      260h
316    dw      280h
317    dw      2A0h
318    dw      2C0h
319    dw      2E0h
320    dw      300h
321    dw      320h
322    dw      340h
323    dw      360h
324    dw      380h
325    dw      3A0h
326    dw      3C0h
327    dw      3E0h
328    ; Arco Computer Products AC-1075 / AC-1070 (16-bit MCA IDE adapters with Control Block at +8 and no IRQ)
329    dw      2510h
330    dw      2520h
331    ; Memory Segment Addresses
332    dw      0C000h  ; JR-IDE/ISA
333    dw      0C400h  ; JR-IDE/ISA
334    dw      0C800h  ; JR-IDE/ISA and ADP50L
335    dw      0CA00h  ; ADP50L
336    dw      0CC00h  ; JR-IDE/ISA and ADP50L
337    dw      0CE00h  ; ADP50L
338    dw      0D000h  ; JR-IDE/ISA
339    dw      0D400h  ; JR-IDE/ISA
340    dw      0D800h  ; JR-IDE/ISA
341.wLastIdePort:
342    dw      0DC00h  ; JR-IDE/ISA
Note: See TracBrowser for help on using the repository browser.