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

Last change on this file since 522 was 522, checked in by aitotat@…, 12 years ago

Changes to XTIDE Universal BIOS:

  • INT 13h stack is now at the beginning of RAMVARS.
  • RELOCATE_INT13H_STACK is now allowed only for AT builds. This saves few bytes from interrupt table when lite mode is used.
File size: 9.6 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-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; 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 jz SHORT .CalcDPTForDriveNumber
68 cmp al, dl ; Check first drive in all cases, redundant but OK to repeat
69 jnz 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-through 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 .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
117 mul dl
118 add ax, RAMVARS_size ; Clears CF (will not overflow)
119
120 pop dx
121
122 xchg di, ax ; Restore AX from entry at FindDPT_ForDriveNumber, put DPT pointer in DI
123 ret
124
125ALIGN JUMP_ALIGN
126.DiskIsNotHandledByThisBIOS:
127;
128; Drive not found...
129;
130 xor ax, ax ; Clear DPT pointer
131 stc ; Is not supported by our BIOS
132
133 xchg di, ax ; Restore AX from save at top
134 ret
135
136
137;--------------------------------------------------------------------
138; FindDPT_MasterOrSingleForIdevarsOffsetInDL
139; Parameters:
140; DL: Offset to IDEVARS to search for
141; DS: RAMVARS segment
142; Returns:
143; DS:DI: Ptr to first DPT with same IDEVARS as in DL
144; CF: Clear if wanted DPT found
145; Set if DPT not found, or no DPTs present
146; Corrupts registers:
147; SI
148;--------------------------------------------------------------------
149FindDPT_MasterOrSingleForIdevarsOffsetInDL:
150 mov si, IterateFindFirstDPTforIdevars ; iteration routine (see below)
151 jmp SHORT FindDPT_IterateAllDPTs ; look for the first drive on this controller, if any
152
153;--------------------------------------------------------------------
154; FindDPT_SlaveForIdevarsOffsetInDL
155; Parameters:
156; DL: Offset to IDEVARS to search for
157; DS: RAMVARS segment
158; Returns:
159; DS:DI: Ptr to second DPT with same IDEVARS as in DL
160; CF: Clear if wanted DPT found
161; Set if DPT not found, or no DPTs present
162; Corrupts registers:
163; SI
164;--------------------------------------------------------------------
165FindDPT_SlaveForIdevarsOffsetInDL:
166 mov si, IterateFindSecondDPTforIdevars ; iteration routine (see below)
167 jmp SHORT FindDPT_IterateAllDPTs ; look for the second drive on this controller, if any
168
169;--------------------------------------------------------------------
170; Iteration routines for FindDPT_MasterOrSingleForIdevarsOffsetInDL and
171; FindDPT_SlaveForIdevarsOffsetInDL, for use with IterateAllDPTs
172;
173; Returns when DPT is found on the controller with Idevars offset in DL
174;
175; IterateFindSecondDPTforIdevars
176; IterateFindFirstDPTforIdevars
177; DL: Offset to IDEVARS to search from DPTs
178; DS:DI: Ptr to DPT to examine
179; Returns:
180; CF: Clear if wanted DPT found
181; Set if wrong DPT
182;--------------------------------------------------------------------
183IterateFindSecondDPTforIdevars:
184 call IterateFindFirstDPTforIdevars
185 jc SHORT IterateFindFirstDPTforIdevars.done ; Wrong controller
186
187 ; We have found DPT for Master Drive,
188 ; next DPT is for slave drive or master for another controller
189 add di, BYTE LARGEST_DPT_SIZE
190 ; Fall to IterateFindFirstDPTforIdevars
191
192IterateFindFirstDPTforIdevars:
193 cmp dl, [di+DPT.bIdevarsOffset] ; Clears CF if matched
194 je .done
195 stc ; Set CF for not found
196.done:
197 ret
198
199
200;--------------------------------------------------------------------
201; Finds pointer to first unused Disk Parameter Table.
202; Should only be used before DetectDrives is complete (not valid after this time).
203;
204; FindDPT_ForNewDriveToDSDI
205; Parameters:
206; DS: RAMVARS segment
207; Returns:
208; DS:DI: Ptr to first unused DPT
209; Corrupts registers:
210; AX
211;--------------------------------------------------------------------
212ALIGN JUMP_ALIGN
213FindDPT_ForNewDriveToDSDI:
214 push dx
215
216%ifdef MODULE_SERIAL_FLOPPY
217 mov dx, [RAMVARS.wDrvCntAndFlopCnt]
218 add dl, dh
219%else
220 mov dl, [RAMVARS.bDrvCnt]
221%endif
222
223 jmp short FindDPT_ForDriveNumberInDL.CalcDPTForNewDrive
224
225;--------------------------------------------------------------------
226; IterateToDptWithFlagsHighInBL
227; Parameters:
228; DS:DI: Ptr to DPT to examine
229; BL: Bit(s) to test in DPT.bFlagsHigh
230; Returns:
231; CF: Clear if wanted DPT found
232; Set if wrong DPT
233; Corrupts registers:
234; Nothing
235;--------------------------------------------------------------------
236ALIGN JUMP_ALIGN
237IterateToDptWithFlagsHighInBL:
238 test [di+DPT.bFlagsHigh], bl ; Clears CF
239 jnz SHORT .ReturnRightDPT
240 stc
241.ReturnRightDPT:
242 ret
243
244;--------------------------------------------------------------------
245; FindDPT_ToDSDIforSerialDevice
246; Parameters:
247; DS: RAMVARS segment
248; Returns:
249; DS:DI: Ptr to DPT
250; CF: Set if wanted DPT found
251; Cleared if DPT not found
252; Corrupts registers:
253; SI
254;--------------------------------------------------------------------
255%ifdef MODULE_SERIAL
256ALIGN JUMP_ALIGN
257FindDPT_ToDSDIforSerialDevice:
258 mov bl, FLGH_DPT_SERIAL_DEVICE
259; fall-through
260%endif
261
262;--------------------------------------------------------------------
263; FindDPT_ToDSDIforFlagsHigh
264; Parameters:
265; DS: RAMVARS segment
266; BL: Bit(s) to test in DPT.bFlagsHigh
267; Returns:
268; DS:DI: Ptr to DPT
269; CF: Set if wanted DPT found
270; Cleared if DPT not found
271; Corrupts registers:
272; SI
273;--------------------------------------------------------------------
274%ifdef MODULE_IRQ
275ALIGN JUMP_ALIGN
276FindDPT_ToDSDIforFlagsHighInBL:
277%endif
278 mov si, IterateToDptWithFlagsHighInBL
279 ; Fall to IterateAllDPTs
280
281;--------------------------------------------------------------------
282; Iterates all Disk Parameter Tables.
283;
284; FindDPT_IterateAllDPTs
285; Parameters:
286; AX,BX,DX: Parameters to callback function
287; CS:SI: Ptr to callback function
288; Callback routine should return CF=clear if found
289; DS: RAMVARS segment
290; Returns:
291; DS:DI: Ptr to wanted DPT (if found)
292; If not found, points to first empty DPT
293; CF: Clear if wanted DPT found
294; Set if DPT not found, or no DPTs present
295; Corrupts registers:
296; Nothing unless corrupted by callback function
297;--------------------------------------------------------------------
298ALIGN JUMP_ALIGN
299FindDPT_IterateAllDPTs:
300 push cx
301
302 mov di, RAMVARS_size ; Point DS:DI to first DPT
303 eMOVZX cx, [RAMVARS.bDrvCnt]
304 jcxz .NotFound ; Return if no drives
305
306ALIGN JUMP_ALIGN
307.LoopWhileDPTsLeft:
308 call si ; Is wanted DPT?
309 jnc SHORT .Found ; If so, return
310 add di, BYTE LARGEST_DPT_SIZE ; Point to next DPT
311 loop .LoopWhileDPTsLeft
312
313ALIGN JUMP_ALIGN
314.NotFound:
315 stc
316
317ALIGN JUMP_ALIGN
318.Found:
319 pop cx
320 ret
Note: See TracBrowser for help on using the repository browser.