source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/FindDPT.asm @ 623

Last change on this file since 623 was 623, checked in by krille_n_, 22 months ago

Changes:

  • Reversed the change to IdeDPT.asm in r622 as it didn't work as intended.
  • Reordered some procedures to reduce alignment padding.
  • Added two new defines (EXTRA_LOOP_UNROLLING_SMALL and EXTRA_LOOP_UNROLLING_LARGE) that should improve transfer speeds for some hardware combinations, specifically 808x CPUs with any IDE controller using port I/O and any CPU with XT-IDE controllers.
  • Added a new define (USE_086) for use with 8086 and V30 CPUs only. Unlike the other USE_x86 defines, this define will not change the instruction set used and is therefore compatible with all CPUs. However, it will apply padding to make jump destinations WORD aligned which should improve performance on 8086/V30 CPUs but on 8088/V20 CPUs there is no benefit and, in addition to wasting ROM space, it might in fact be slower on these machines. Since the vast majority of XT class machines are using 8088/V20 CPUs this define is not used in the official XT builds - it's primarily intended for custom BIOS builds.
  • XTIDECFG: The URL to the support forum has been updated.
File size: 9.4 KB
Line 
1; Project name  :   XTIDE Universal BIOS
2; Description   :   Functions for finding Disk Parameter Table.
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
23;--------------------------------------------------------------------
24; Checks if drive is handled by this BIOS, and return DPT pointer.
25;
26; FindDPT_ForDriveNumberInDL
27;   Parameters:
28;       DL:     Drive number
29;       DS:     RAMVARS segment
30;   Returns:
31;       CF:     Cleared if drive is handled by this BIOS
32;               Set if drive belongs to some other BIOS
33;       DI:     DPT Pointer if drive is handled by this BIOS
34;               Zero if drive belongs to some other BIOS
35;   Corrupts registers:
36;       Nothing
37;--------------------------------------------------------------------
38ALIGN JUMP_ALIGN
39FindDPT_ForDriveNumberInDL:
40    xchg    di, ax                              ; Save the contents of AX in DI
41
42;
43; Check Our Hard Disks
44;
45    mov     ax, [RAMVARS.wFirstDrvAndCount]     ; Drive count to AH, First number to AL
46    add     ah, al                              ; One past last drive to AH
47
48%ifdef MODULE_SERIAL_FLOPPY
49    cmp     dl, ah                              ; Above last supported?
50    jae     SHORT .HardDiskNotHandledByThisBIOS
51
52    cmp     dl, al                              ; Below first supported?
53    jae     SHORT .CalcDPTForDriveNumber
54
55ALIGN JUMP_ALIGN
56.HardDiskNotHandledByThisBIOS:
57;
58; Check Our Floppy Disks
59;
60    call    RamVars_UnpackFlopCntAndFirstToAL
61    js      SHORT .DiskIsNotHandledByThisBIOS
62
63    cbw                                         ; Always 0h (no floppy drive covered above)
64    adc     ah, al                              ; Add in first drive number and number of drives
65
66    cmp     ah, dl                              ; Check second drive if two, first drive if only one
67    je      SHORT .CalcDPTForDriveNumber
68    cmp     al, dl                              ; Check first drive in all cases, redundant but OK to repeat
69    jne     SHORT .DiskIsNotHandledByThisBIOS
70%else
71    cmp     dl, ah                              ; Above last supported?
72    jae     SHORT .DiskIsNotHandledByThisBIOS
73
74    cmp     dl, al                              ; Below first supported?
75    jb      SHORT .DiskIsNotHandledByThisBIOS
76%endif
77    ; Fall to .CalcDPTForDriveNumber
78
79;--------------------------------------------------------------------
80; Finds Disk Parameter Table for drive number.
81; Not intended to be called except by FindDPT_ForDriveNumberInDL
82;
83; .CalcDPTForDriveNumber
84;   Parameters:
85;       DL:     Drive number
86;       DS:     RAMVARS segment
87;       DI:     Saved copy of AX from entry at FindDPT_ForDriveNumberInDL
88;   Returns:
89;       DS:DI:  Ptr to DPT
90;       CF:     Clear
91;   Corrupts registers:
92;       Nothing
93;--------------------------------------------------------------------
94ALIGN JUMP_ALIGN
95.CalcDPTForDriveNumber:
96    push    dx
97
98%ifdef MODULE_SERIAL_FLOPPY
99    mov     ax, [RAMVARS.wFirstDrvAndCount]
100
101    test    dl, dl
102    js      SHORT .Harddisk
103
104    call    RamVars_UnpackFlopCntAndFirstToAL
105    add     dl, ah                      ; add in end of hard disk DPT list, floppies start immediately after
106
107ALIGN JUMP_ALIGN
108.Harddisk:
109    sub     dl, al                      ; subtract off beginning of either hard disk or floppy list (as appropriate)
110%else
111    sub     dl, [RAMVARS.bFirstDrv]     ; subtract off beginning of hard disk list
112%endif
113
114.CalcDPTForNewDrive:
115    mov     al, LARGEST_DPT_SIZE
116    mul     dl
117    add     ax, RAMVARS_size            ; Clears CF (will not overflow)
118
119    pop     dx
120
121    xchg    di, ax                      ; Restore AX from entry at FindDPT_ForDriveNumber, put DPT pointer in DI
122    ret
123
124ALIGN JUMP_ALIGN
125.DiskIsNotHandledByThisBIOS:
126;
127; Drive not found...
128;
129    xor     ax, ax                              ; Clear DPT pointer
130    stc                                         ; Is not supported by our BIOS
131
132    xchg    di, ax                              ; Restore AX from save at top
133    ret
134
135
136;--------------------------------------------------------------------
137; Iteration routines for FindDPT_MasterOrSingleForIdevarsOffsetInDL and
138; FindDPT_SlaveForIdevarsOffsetInDL, for use with FindDPT_IterateAllDPTs
139;
140; Returns when DPT is found on the controller with Idevars offset in DL
141;
142; IterateFindSecondDPTforIdevars
143; IterateFindFirstDPTforIdevars
144;       DL:     Offset to IDEVARS to search from DPTs
145;       SI:     Offset to this callback function
146;       DS:DI:  Ptr to DPT to examine
147;   Returns:
148;       CF:     Cleared if wanted DPT found
149;               Set if wrong DPT
150;--------------------------------------------------------------------
151IterateFindSecondDPTforIdevars:
152    call    IterateFindFirstDPTforIdevars
153    jc      SHORT WrongController
154    mov     si, IterateFindFirstDPTforIdevars
155SetCFandReturn:
156    stc
157WrongController:
158    ret
159
160IterateFindFirstDPTforIdevars:
161    cmp     dl, [di+DPT.bIdevarsOffset]         ; Clears CF if matched
162    jne     SHORT SetCFandReturn
163    ret
164
165
166;--------------------------------------------------------------------
167; Finds pointer to first unused Disk Parameter Table.
168; Should only be used before DetectDrives is complete (not valid after this time).
169;
170; FindDPT_ForNewDriveToDSDI
171;   Parameters:
172;       DS:     RAMVARS segment
173;   Returns:
174;       DS:DI:  Ptr to first unused DPT
175;   Corrupts registers:
176;       AX
177;--------------------------------------------------------------------
178ALIGN JUMP_ALIGN
179FindDPT_ForNewDriveToDSDI:
180    push    dx
181
182%ifdef MODULE_SERIAL_FLOPPY
183    mov     dx, [RAMVARS.wDrvCntAndFlopCnt]
184    add     dl, dh
185%else
186    mov     dl, [RAMVARS.bDrvCnt]
187%endif
188
189    jmp     SHORT FindDPT_ForDriveNumberInDL.CalcDPTForNewDrive
190
191;--------------------------------------------------------------------
192; IterateToDptWithFlagsHighInBL
193;   Parameters:
194;       DS:DI:  Ptr to DPT to examine
195;       BL:     Bit(s) to test in DPT.bFlagsHigh
196;   Returns:
197;       CF:     Cleared if wanted DPT found
198;               Set if wrong DPT
199;   Corrupts registers:
200;       Nothing
201;--------------------------------------------------------------------
202%ifdef MODULE_SERIAL
203ALIGN JUMP_ALIGN
204IterateToDptWithFlagsHighInBL:
205    test    [di+DPT.bFlagsHigh], bl             ; Clears CF
206    jnz     SHORT .ReturnRightDPT
207    stc
208.ReturnRightDPT:
209    ret
210%endif
211
212;--------------------------------------------------------------------
213; FindDPT_ToDSDIforSerialDevice
214;   Parameters:
215;       DS:     RAMVARS segment
216;   Returns:
217;       DS:DI:  Ptr to DPT
218;       CF:     Cleared if wanted DPT found
219;               Set if DPT not found, or no DPTs present
220;   Corrupts registers:
221;       BL, SI
222;--------------------------------------------------------------------
223%ifdef MODULE_SERIAL
224ALIGN JUMP_ALIGN
225FindDPT_ToDSDIforSerialDevice:
226    mov     bl, FLGH_DPT_SERIAL_DEVICE
227    ; Fall to FindDPT_ToDSDIforFlagsHighInBL
228%endif
229
230;--------------------------------------------------------------------
231; FindDPT_ToDSDIforFlagsHighInBL
232;   Parameters:
233;       DS:     RAMVARS segment
234;       BL:     Bit(s) to test in DPT.bFlagsHigh
235;   Returns:
236;       DS:DI:  Ptr to DPT
237;       CF:     Cleared if wanted DPT found
238;               Set if DPT not found, or no DPTs present
239;   Corrupts registers:
240;       SI
241;--------------------------------------------------------------------
242%ifdef MODULE_SERIAL
243;%ifdef MODULE_IRQ
244;ALIGN JUMP_ALIGN
245;FindDPT_ToDSDIforFlagsHighInBL:    ; This label is unused
246;%endif
247    mov     si, IterateToDptWithFlagsHighInBL
248    jmp     SHORT FindDPT_IterateAllDPTs
249%endif
250
251;--------------------------------------------------------------------
252; FindDPT_MasterOrSingleForIdevarsOffsetInDL
253;   Parameters:
254;       DL:     Offset to IDEVARS to search for
255;       DS:     RAMVARS segment
256;   Returns:
257;       DS:DI:  Ptr to first DPT with same IDEVARS as in DL
258;       CF:     Cleared if wanted DPT found
259;               Set if DPT not found, or no DPTs present
260;   Corrupts registers:
261;       SI
262;--------------------------------------------------------------------
263FindDPT_MasterOrSingleForIdevarsOffsetInDL:
264    mov     si, IterateFindFirstDPTforIdevars
265    jmp     SHORT FindDPT_IterateAllDPTs
266
267;--------------------------------------------------------------------
268; FindDPT_SlaveForIdevarsOffsetInDL
269;   Parameters:
270;       DL:     Offset to IDEVARS to search for
271;       DS:     RAMVARS segment
272;   Returns:
273;       DS:DI:  Ptr to second DPT with same IDEVARS as in DL
274;       CF:     Cleared if wanted DPT found
275;               Set if DPT not found, or no DPTs present
276;   Corrupts registers:
277;       SI
278;--------------------------------------------------------------------
279FindDPT_SlaveForIdevarsOffsetInDL:
280    mov     si, IterateFindSecondDPTforIdevars
281    ; Fall to FindDPT_IterateAllDPTs
282
283;--------------------------------------------------------------------
284; Iterates all Disk Parameter Tables.
285;
286; FindDPT_IterateAllDPTs
287;   Parameters:
288;       AX,BX,DX:   Parameters to callback function
289;       CS:SI:      Ptr to callback function
290;                   Callback routine should return CF=clear if found
291;       DS:         RAMVARS segment
292;   Returns:
293;       DS:DI:      Ptr to wanted DPT (if found)
294;                   If not found, points to first empty DPT
295;       CF:         Cleared if wanted DPT found
296;                   Set if DPT not found, or no DPTs present
297;   Corrupts registers:
298;       Nothing unless corrupted by callback function
299;--------------------------------------------------------------------
300ALIGN JUMP_ALIGN
301FindDPT_IterateAllDPTs:
302    push    cx
303
304    mov     di, RAMVARS_size            ; Point DS:DI to first DPT
305    eMOVZX  cx, [RAMVARS.bDrvCnt]
306    jcxz    .NotFound                   ; Return if no drives
307
308ALIGN JUMP_ALIGN
309.LoopWhileDPTsLeft:
310    call    si                          ; Is wanted DPT?
311    jnc     SHORT .Found                ;  If so, return
312    add     di, BYTE LARGEST_DPT_SIZE   ; Point to next DPT
313    loop    .LoopWhileDPTsLeft
314
315.NotFound:
316    stc
317
318ALIGN JUMP_ALIGN
319.Found:
320    pop     cx
321    ret
Note: See TracBrowser for help on using the repository browser.