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

Last change on this file since 505 was 505, checked in by krille_n_@…, 9 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.