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

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

Changes to XTIDE Universal BIOS:

  • Hopefully fixed problems with recent changes to AH=00h.
  • Timeout error code is no longer displayed when trying to boot from floppy drive.
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, BYTE 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.