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

Last change on this file since 589 was 589, checked in by krille_n_, 8 years ago

Changes:

  • BIOS: Fixed a purely cosmetic bug from r542 where, in builds containing MODULE_EBIOS, the boot menu would display an incorrect drive size (0.4 kB with MODULE_STRINGS_COMPRESSED or 0.5 kB without) for old drives with no support for LBA.
  • Fixed a bug from r392 where Vision_DetectAndReturnIDinAXandPortInDXifControllerPresent would return the ID in AL instead of AH (if DANGEROUS_DETECTION had been defined).
  • Fixed a bug from r587 in AdvAtaInit.asm that would prevent detection of QDI Vision controllers.
  • Also changed how the QDI Vision IDs are defined (removed the need for shifting) to avoid confusion. This fixed a potential bug from r587 in AdvAtaInit.asm where some IDs were not being shifted.
  • Fixed a bug in PDC20x30.asm from r587 where GetPdcIDtoAX would not return with the IDE base port in DX so DisablePdcProgrammingMode would fail.
  • Made some changes to ModuleDependency.inc and other files so that MODULE_ADVANCED_ATA now requires USE_386. Consequently it is no longer included in the regular AT-builds, only in the 386_8k-build.
  • Moved the UNROLL_SECTORS_IN_CX_TO_xWORDS macros from IDE_8bit.inc to IdeIO.inc which means it's now possible to build a BIOS without MODULE_8BIT_IDE.
  • XTIDECFG: Added a minimum DOS version check (since it needs DOS version 2+) to allow the program to quit gracefully in the unlikely scenario where someone tries to run it under DOS version 1.
  • Made some changes to Drive.asm to improve drive enumeration. The old method using GET_DOS_DRIVE_PARAMETER_BLOCK_FOR_SPECIFIC_DRIVE worked well in Windows XP but not in Windows 98 SE (in Windows or in DOS mode). The two problems were; 1) The function call would access the drives which on single floppy drive systems would cause Windows to swap between A: and B: (throwing a blue screen asking the user to insert a disk etc). 2) Only floppy drives and FAT16 drives would be available in the list of drives, no FAT32/optical/network drives.
  • Improved code in IdeControllerMenu.asm so that the default port addresses for all IDE interfaces are now restored when (re-)selecting the (same) type of IDE device.
  • Also made it impossible to select a device type unless the required module is included in the loaded BIOS.
  • The version check done when loading a BIOS now uses the FLASH_SIGNATURE definition from Version.inc. Any changes affecting RomVars now only requires updating that definition. This means that changes to RomVars must be implemented in both the BIOS and XTIDECFG before being committed to the repository.
  • Added a compatibility fix for 3Com 3C503 cards to the ROM checksumming code in Buffers.asm (Buffers_GenerateChecksum).
  • SerDrive: Made some minor changes to file names and paths to improve compatibility with case sensitive environments.
  • BIOSDRVS: Made a minor size optimization which as a side effect also makes it compatible with all DOS versions including DOS version 1.
  • Library: Renamed the WAIT_RETRACE_IF_NECESSARY_THEN macro to CALL_WAIT_FOR_RETRACE_IF_NECESSARY_THEN and made a tail-call-optimized version of it (JMP_WAIT_FOR_RETRACE_IF_NECESSARY_THEN).
  • A speed optimization to the eRCL_IM macro for 386 and higher. This change breaks emulation in the sense that the macro will fail when given a memory operand as the first parameter.
  • Other minor optimizations and fixes.
File size: 11.1 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    ; *** Try to detect Standard 16- and 32-bit IDE Devices ***
102    mov     al, DEVICE_16BIT_ATA        ; Assume 16-bit ISA slot for AT builds
103    call    Buffers_IsXTbuildLoaded
104    eCMOVE  al, DEVICE_8BIT_ATA         ; Assume 8-bit ISA slot for XT builds
105
106    ; Start with standard Control Block base port used by Primary and Secondary IDE
107    mov     si, dx
108    add     si, STANDARD_CONTROL_BLOCK_OFFSET
109    mov     bx, STATUS_REGISTER_in | (ALTERNATE_STATUS_REGISTER_in << 8)
110.RedetectTertiaryOrQuaternaryWithDifferentControlBlockAddress:
111    push    ax                          ; Store device type
112    call    DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
113    pop     ax                          ; Restore device type
114    jnc     SHORT .IdeDeviceFound
115
116    ; 16- or 32-bit IDE Device was not found but we may have used wrong Control Block port if we were trying
117    ; to detect Tertiary or Quaternary IDE controllers. Control Block port location is not standardized. For
118    ; example Promise FloppyMAX has Control Block at STANDARD_CONTROL_BLOCK_OFFSET but Sound Blaster 16 (CT2290)
119    ; use DEVICE_ATA_SECONDARY_PORTCTRL for Tertiary and Quaternary even though only Secondary should use that.
120    call    ChangeDifferentControlBlockAddressToSI
121    je      SHORT .RedetectTertiaryOrQuaternaryWithDifferentControlBlockAddress
122
123
124    ; Detect 8-bit devices only if MODULE_8BIT_IDE is available
125    test    BYTE [di+ROMVARS.wFlags], FLG_ROMVARS_MODULE_8BIT_IDE | FLG_ROMVARS_MODULE_8BIT_IDE_ADVANCED
126    jz      SHORT NoIdeDeviceFound
127    jpo     SHORT .SkipXTCF             ; Only 1 bit set means no MODULE_8BIT_IDE_ADVANCED
128
129    ; *** Try to detect XT-CF ***
130    mov     si, dx
131    add     si, BYTE XTCF_CONTROL_BLOCK_OFFSET
132    shl     bx, 1                       ; SHL 1 register offsets for XT-CF
133    call    DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
134    mov     al, DEVICE_8BIT_XTCF_PIO8
135    jnc     SHORT .IdeDeviceFound
136    shr     bx, 1
137.SkipXTCF:
138
139    ; *** Try to detect 8-bit XT-IDE rev 1 or rev 2 ***
140    ; Note that A0<->A3 address swaps Status Register and Alternative
141    ; Status Register addresses. That is why we need another step
142    ; to check is this XT-IDE rev 1 or rev 2.
143    mov     si, dx
144    add     si, BYTE XTIDE_CONTROL_BLOCK_OFFSET
145    call    DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
146    jc      SHORT NoIdeDeviceFound      ; No XT-IDE rev 1 or rev 2 found
147
148    ; Now we can be sure that we have XT-IDE rev 1 or rev 2.
149    ; Rev 2 swaps address lines A0 and A3 thus LBA Low Register
150    ; moves from offset 3h to offset Ah. There is no Register at
151    ; offset Ah so if we can write to it and read back, then we
152    ; must have XT-IDE rev 2 or modded rev 1.
153    push    dx
154    add     dx, BYTE 0Ah                ; LBA Low Register for XT-IDE rev 2
155    mov     al, DEVICE_8BIT_XTIDE_REV2  ; Our test byte
156    out     dx, al                      ; Output our test byte
157    JMP_DELAY
158    in      al, dx                      ; Read back
159    pop     dx
160    cmp     al, DEVICE_8BIT_XTIDE_REV2
161    je      SHORT .IdeDeviceFound
162    mov     al, DEVICE_8BIT_XTIDE_REV1  ; We must have rev 1
163.IdeDeviceFound:
164    clc
165    ret
166
167
168;--------------------------------------------------------------------
169; DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH
170;   Parameters:
171;       BL:     Offset to IDE Status Register
172;       BH:     Offset to Alternative Status Register
173;       DX:     IDE Base Port address
174;       SI:     IDE Control Block address
175;   Returns:
176;       CF:     Clear if IDE Device found
177;               Set if IDE Device not found
178;   Corrupts registers:
179;       AX
180;--------------------------------------------------------------------
181DetectIdeDeviceFromPortsDXandSIwithOffsetsInBLandBH:
182    ; Read Status and Alternative Status Registers
183    push    dx
184
185    add     dl, bl
186    cli                         ; Disable Interrupts
187    in      al, dx              ; Read Status Register...
188    mov     ah, al              ; ...to AH
189    mov     dx, si
190    add     dl, bh
191    in      al, dx              ; Read Alternative Status Register to AL
192    sti                         ; Enable Interrupts
193
194    pop     dx
195    ; Fall to CompareIdeStatusRegistersFromALandAH
196
197
198;--------------------------------------------------------------------
199; CompareIdeStatusRegistersFromALandAH
200;   Parameters:
201;       AH:     Possible IDE Status Register contents
202;       AL:     Possible IDE Alternative Status Register contents
203;   Returns:
204;       CF:     Clear if valid Status Register Contents
205;               Set if not possible IDE Status Registers
206;   Corrupts registers:
207;       Nothing
208;--------------------------------------------------------------------
209CompareIdeStatusRegistersFromALandAH:
210    ; Status Register now in AH and Alternative Status Register in AL.
211    ; They must be the same if base port was in use by IDE device.
212    cmp     al, ah
213    jne     SHORT NoIdeDeviceFound
214
215    ; Bytes were the same but it is possible they were both FFh, for
216    ; example. We must make sure bits are what is expected from valid
217    ; IDE Status Register. So far all drives I've tested return 50h
218    ; (FLG_STATUS_DRDY and FLG_STATUS_DSC set) or 00h.
219    ; I suspect that the zero might mean non available drive is selected. For example if Master
220    ; drive is present but Slave is selected from IDE Drive and Head Select Register,
221    ; then the Status Register can be 00h. We cannot accept 00h as valid byte
222    ; since that can easily cause invalid JR-IDE/ISA detections.
223    test    al, FLG_STATUS_BSY | FLG_STATUS_DF | FLG_STATUS_DRQ | FLG_STATUS_ERR
224    jnz     SHORT NoIdeDeviceFound  ; Busy or Errors cannot be set
225    test    al, FLG_STATUS_DRDY
226    jz      SHORT NoIdeDeviceFound  ; Device needs to be ready
227    ret                             ; Return with CF cleared
228
229NoIdeDeviceFound:
230    stc
231    ret
232
233
234;--------------------------------------------------------------------
235; ChangeDifferentControlBlockAddressToSI
236;   Parameters:
237;       DX:     IDE Base Port address
238;       SI:     IDE Control Block address
239;   Returns:
240;       ZF:     Set if SI changed
241;               Cleared if different control block address is not possible
242;   Corrupts registers:
243;       AH
244;--------------------------------------------------------------------
245ChangeDifferentControlBlockAddressToSI:
246    cmp     si, 368h
247    je      SHORT .TrySecondAlternative
248    cmp     si, 3E8h
249    je      SHORT .TrySecondAlternative
250
251    cmp     si, 360h
252    je      SHORT .TryLastAlternative
253    cmp     si, 3E0h
254    je      SHORT .TryLastAlternative
255    ret     ; Return with ZF cleared
256
257.TryLastAlternative:
258    mov     si, DEVICE_ATA_SECONDARY_PORTCTRL + 8   ; Changes to 370h used by Sound Blaster 16 (CT2290)
259    ; Fall to .TrySecondAlternative
260.TrySecondAlternative:
261    sub     si, BYTE 8h     ; 368h to 360h, 3E8h to 3E0h
262    xor     ah, ah          ; Set ZF
263    ret
264
265
266;--------------------------------------------------------------------
267; IdeAutodetect_IncrementDXtoNextIdeBasePort
268;   Parameters:
269;       DX:     Previous IDE Base Port or IDE_PORT_TO_START_DETECTION
270;   Returns:
271;       DX:     Next IDE Base Port
272;       ZF:     Set if no more Base Ports (DX was last base port on entry)
273;               Clear if new base port returned in DX
274;   Corrupts registers:
275;       AX
276;--------------------------------------------------------------------
277ALIGN JUMP_ALIGN
278IdeAutodetect_IncrementDXtoNextIdeBasePort:
279    cmp     dx, [cs:.wLastIdePort]
280    je      SHORT .AllPortsAlreadyDetected
281
282    push    si
283    mov     si, .rgwIdeBasePorts
284.CompareNextIdeBasePort:
285    cmp     [cs:si], dx
286    lea     si, [si+2]  ; Increment SI and preserve FLAGS
287    jne     SHORT .CompareNextIdeBasePort
288
289    mov     dx, [cs:si]         ; Get next port
290    test    dx, dx              ; Clear ZF
291    pop     si
292.AllPortsAlreadyDetected:
293    ret
294
295
296    ; All ports used in autodetection. Ports can be in any order.
297ALIGN WORD_ALIGN
298.rgwIdeBasePorts:
299    dw      IDE_PORT_TO_START_DETECTION     ; Must be first
300    ; Standard IDE
301    dw      DEVICE_ATA_PRIMARY_PORT
302    dw      DEVICE_ATA_SECONDARY_PORT
303    dw      DEVICE_ATA_TERTIARY_PORT
304    dw      DEVICE_ATA_QUATERNARY_PORT
305    ; 8-bit Devices
306    dw      200h
307    dw      220h
308    dw      240h
309    dw      260h
310    dw      280h
311    dw      2A0h
312    dw      2C0h
313    dw      2E0h
314    dw      300h
315    dw      320h
316    dw      340h
317    dw      360h
318    dw      380h
319    dw      3A0h
320    dw      3C0h
321    dw      3E0h
322    ; Memory Segment Addresses
323    dw      0C000h  ; JR-IDE/ISA
324    dw      0C400h  ; JR-IDE/ISA
325    dw      0C800h  ; JR-IDE/ISA and ADP50L
326    dw      0CA00h  ; ADP50L
327    dw      0CC00h  ; JR-IDE/ISA and ADP50L
328    dw      0CE00h  ; ADP50L
329    dw      0D000h  ; JR-IDE/ISA
330    dw      0D400h  ; JR-IDE/ISA
331    dw      0D800h  ; JR-IDE/ISA
332.wLastIdePort:
333    dw      0DC00h  ; JR-IDE/ISA
Note: See TracBrowser for help on using the repository browser.