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

Last change on this file since 320 was 294, checked in by krille_n_@…, 13 years ago

Commit 2/2 (BIOS):

  • Fixed a bug in AH1h_HStatus.asm.
  • Minor optimizations.
  • Fixed spelling and did some cleaning.
File size: 7.8 KB
Line 
1; Project name : XTIDE Universal BIOS
2; Description : Functions for finding Disk Parameter Table.
3
4; Section containing code
5SECTION .text
6
7;--------------------------------------------------------------------
8; Checks if drive is handled by this BIOS, and return DPT pointer.
9;
10; FindDPT_ForDriveNumberInDL
11; Parameters:
12; DL: Drive number
13; DS: RAMVARS segment
14; Returns:
15; CF: Cleared if drive is handled by this BIOS
16; Set if drive belongs to some other BIOS
17; DI: DPT Pointer if drive is handled by this BIOS
18; Zero if drive belongs to some other BIOS
19; Corrupts registers:
20; Nothing
21;--------------------------------------------------------------------
22ALIGN JUMP_ALIGN
23FindDPT_ForDriveNumberInDL:
24 xchg di, ax ; Save the contents of AX in DI
25
26;
27; Check Our Hard Disks
28;
29 mov ax, [RAMVARS.wDrvCntAndFirst] ; Drive count to AH, First number to AL
30 add ah, al ; One past last drive to AH
31
32%ifdef MODULE_SERIAL_FLOPPY
33 cmp dl, ah ; Above last supported?
34 jae SHORT .HardDiskNotHandledByThisBIOS
35
36 cmp dl, al ; Below first supported?
37 jae SHORT .CalcDPTForDriveNumber
38
39ALIGN JUMP_ALIGN
40.HardDiskNotHandledByThisBIOS:
41;
42; Check Our Floppy Disks
43;
44 call RamVars_UnpackFlopCntAndFirstToAL
45 js SHORT .DiskIsNotHandledByThisBIOS
46
47 cbw ; Always 0h (no floppy drive covered above)
48 adc ah, al ; Add in first drive number and number of drives
49
50 cmp ah, dl ; Check second drive if two, first drive if only one
51 jz SHORT .CalcDPTForDriveNumber
52 cmp al, dl ; Check first drive in all cases, redundant but OK to repeat
53 jnz SHORT .DiskIsNotHandledByThisBIOS
54%else
55 cmp dl, ah ; Above last supported?
56 jae SHORT .DiskIsNotHandledByThisBIOS
57
58 cmp dl, al ; Below first supported?
59 jb SHORT .DiskIsNotHandledByThisBIOS
60%endif
61 ; fall-through to CalcDPTForDriveNumber
62
63;--------------------------------------------------------------------
64; Finds Disk Parameter Table for drive number.
65; Not intended to be called except by FindDPT_ForDriveNumberInDL
66;
67; CalcDPTForDriveNumber
68; Parameters:
69; DL: Drive number
70; DS: RAMVARS segment
71; DI: Saved copy of AX from entry at FindDPT_ForDriveNumberInDL
72; Returns:
73; DS:DI: Ptr to DPT
74; CF: Clear
75; Corrupts registers:
76; Nothing
77;--------------------------------------------------------------------
78ALIGN JUMP_ALIGN
79.CalcDPTForDriveNumber:
80 push dx
81
82%ifdef MODULE_SERIAL_FLOPPY
83 mov ax, [RAMVARS.wDrvCntAndFirst]
84
85 test dl, dl
86 js .harddisk
87
88 call RamVars_UnpackFlopCntAndFirstToAL
89 add dl, ah ; add in end of hard disk DPT list, floppies start immediately after
90
91ALIGN JUMP_ALIGN
92.harddisk:
93 sub dl, al ; subtract off beginning of either hard disk or floppy list (as appropriate)
94%else
95 sub dl, [RAMVARS.bFirstDrv] ; subtract off beginning of hard disk list
96%endif
97
98.CalcDPTForNewDrive:
99 mov al, LARGEST_DPT_SIZE
100
101 mul dl
102 add ax, BYTE RAMVARS_size ; Clears CF (will not overflow)
103
104 pop dx
105
106 xchg di, ax ; Restore AX from entry at FindDPT_ForDriveNumber, put DPT pointer in DI
107 ret
108
109ALIGN JUMP_ALIGN
110.DiskIsNotHandledByThisBIOS:
111;
112; Drive not found...
113;
114 xor ax, ax ; Clear DPT pointer
115 stc ; Is not supported by our BIOS
116
117 xchg di, ax ; Restore AX from save at top
118 ret
119
120
121;--------------------------------------------------------------------
122; FindDPT_ForIdevarsOffsetInDL
123; Parameters:
124; DL: Offset to IDEVARS to search for
125; DS: RAMVARS segment
126; Returns:
127; DS:DI: Ptr to first DPT with same IDEVARS as in DL
128; CF: Clear if wanted DPT found
129; Set if DPT not found, or no DPTs present
130; Corrupts registers:
131; SI
132;--------------------------------------------------------------------
133FindDPT_ForIdevarsOffsetInDL:
134 mov si, IterateFindFirstDPTforIdevars ; iteration routine (see below)
135 jmp SHORT FindDPT_IterateAllDPTs ; look for the first drive on this controller, if any
136
137;--------------------------------------------------------------------
138; Iteration routine for FindDPT_ForIdevarsOffsetInDL,
139; for use with IterateAllDPTs
140;
141; Returns when DPT is found on the controller with Idevars offset in DL
142;
143; IterateFindFirstDPTforIdevars
144; DL: Offset to IDEVARS to search from DPTs
145; DS:DI: Ptr to DPT to examine
146; Returns:
147; CF: Clear if wanted DPT found
148; Set if wrong DPT
149;--------------------------------------------------------------------
150IterateFindFirstDPTforIdevars:
151 cmp dl, [di+DPT.bIdevarsOffset] ; Clears CF if matched
152 je .done
153 stc ; Set CF for not found
154.done:
155 ret
156
157
158;--------------------------------------------------------------------
159; Finds pointer to first unused Disk Parameter Table.
160; Should only be used before DetectDrives is complete (not valid after this time).
161;
162; FindDPT_ForNewDriveToDSDI
163; Parameters:
164; DS: RAMVARS segment
165; Returns:
166; DS:DI: Ptr to first unused DPT
167; Corrupts registers:
168; AX
169;--------------------------------------------------------------------
170ALIGN JUMP_ALIGN
171FindDPT_ForNewDriveToDSDI:
172 push dx
173
174%ifdef MODULE_SERIAL_FLOPPY
175 mov dx, [RAMVARS.wDrvCntAndFlopCnt]
176 add dl, dh
177%else
178 mov dl, [RAMVARS.bDrvCnt]
179%endif
180
181 jmp short FindDPT_ForDriveNumberInDL.CalcDPTForNewDrive
182
183;--------------------------------------------------------------------
184; IterateToDptWithFlagsHighInBL
185; Parameters:
186; DS:DI: Ptr to DPT to examine
187; BL: Bit(s) to test in DPT.bFlagsHigh
188; Returns:
189; CF: Clear if wanted DPT found
190; Set if wrong DPT
191; Corrupts registers:
192; Nothing
193;--------------------------------------------------------------------
194ALIGN JUMP_ALIGN
195IterateToDptWithFlagsHighInBL:
196 test [di+DPT.bFlagsHigh], bl ; Clears CF
197 jnz SHORT .ReturnRightDPT
198 stc
199.ReturnRightDPT:
200 ret
201
202;--------------------------------------------------------------------
203; FindDPT_ToDSDIforSerialDevice
204; Parameters:
205; DS: RAMVARS segment
206; Returns:
207; DS:DI: Ptr to DPT
208; CF: Set if wanted DPT found
209; Cleared if DPT not found
210; Corrupts registers:
211; SI
212;--------------------------------------------------------------------
213%ifdef MODULE_SERIAL
214ALIGN JUMP_ALIGN
215FindDPT_ToDSDIforSerialDevice:
216 mov bl, FLGH_DPT_SERIAL_DEVICE
217; fall-through
218%endif
219
220;--------------------------------------------------------------------
221; FindDPT_ToDSDIforFlagsHigh
222; Parameters:
223; DS: RAMVARS segment
224; BL: Bit(s) to test in DPT.bFlagsHigh
225; Returns:
226; DS:DI: Ptr to DPT
227; CF: Set if wanted DPT found
228; Cleared if DPT not found
229; Corrupts registers:
230; SI
231;--------------------------------------------------------------------
232ALIGN JUMP_ALIGN
233FindDPT_ToDSDIforFlagsHighInBL:
234 mov si, IterateToDptWithFlagsHighInBL
235 ; Fall to IterateAllDPTs
236
237;--------------------------------------------------------------------
238; Iterates all Disk Parameter Tables.
239;
240; FindDPT_IterateAllDPTs
241; Parameters:
242; AX,BX,DX: Parameters to callback function
243; CS:SI: Ptr to callback function
244; Callback routine should return CF=clear if found
245; DS: RAMVARS segment
246; Returns:
247; DS:DI: Ptr to wanted DPT (if found)
248; If not found, points to first empty DPT
249; CF: Clear if wanted DPT found
250; Set if DPT not found, or no DPTs present
251; Corrupts registers:
252; Nothing unless corrupted by callback function
253;--------------------------------------------------------------------
254ALIGN JUMP_ALIGN
255FindDPT_IterateAllDPTs:
256 push cx
257
258 mov di, RAMVARS_size ; Point DS:DI to first DPT
259 eMOVZX cx, [RAMVARS.bDrvCnt]
260 jcxz .NotFound ; Return if no drives
261
262ALIGN JUMP_ALIGN
263.LoopWhileDPTsLeft:
264 call si ; Is wanted DPT?
265 jnc SHORT .Found ; If so, return
266 add di, BYTE LARGEST_DPT_SIZE ; Point to next DPT
267 loop .LoopWhileDPTsLeft
268
269ALIGN JUMP_ALIGN
270.NotFound:
271 stc
272
273ALIGN JUMP_ALIGN
274.Found:
275 pop cx
276 ret
277
Note: See TracBrowser for help on using the repository browser.