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

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

Changes:

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