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

Last change on this file since 628 was 623, checked in by Krister Nordvall, 2 years 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.