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

Last change on this file since 420 was 376, checked in by gregli@…, 13 years ago

WIDE checkin... Added copyright and license information to sorce files, as per the GPL instructions for usage.

File size: 8.5 KB
RevLine 
[150]1; Project name : XTIDE Universal BIOS
[3]2; Description : Functions for finding Disk Parameter Table.
3
[376]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
[3]20; Section containing code
21SECTION .text
22
23;--------------------------------------------------------------------
[262]24; Checks if drive is handled by this BIOS, and return DPT pointer.
[3]25;
[294]26; FindDPT_ForDriveNumberInDL
[3]27; Parameters:
[262]28; DL: Drive number
[3]29; DS: RAMVARS segment
30; Returns:
[262]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
[3]35; Corrupts registers:
[262]36; Nothing
[150]37;--------------------------------------------------------------------
38ALIGN JUMP_ALIGN
[294]39FindDPT_ForDriveNumberInDL:
[262]40 xchg di, ax ; Save the contents of AX in DI
41
[294]42;
[262]43; Check Our Hard Disks
44;
45 mov ax, [RAMVARS.wDrvCntAndFirst] ; Drive count to AH, First number to AL
46 add ah, al ; One past last drive to AH
47
[258]48%ifdef MODULE_SERIAL_FLOPPY
[262]49 cmp dl, ah ; Above last supported?
50 jae SHORT .HardDiskNotHandledByThisBIOS
[294]51
[262]52 cmp dl, al ; Below first supported?
53 jae SHORT .CalcDPTForDriveNumber
54
[294]55ALIGN JUMP_ALIGN
56.HardDiskNotHandledByThisBIOS:
[262]57;
58; Check Our Floppy Disks
[294]59;
[262]60 call RamVars_UnpackFlopCntAndFirstToAL
61 js SHORT .DiskIsNotHandledByThisBIOS
[294]62
[277]63 cbw ; Always 0h (no floppy drive covered above)
64 adc ah, al ; Add in first drive number and number of drives
65
[262]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
[294]69 jnz SHORT .DiskIsNotHandledByThisBIOS
[262]70%else
[294]71 cmp dl, ah ; Above last supported?
[262]72 jae SHORT .DiskIsNotHandledByThisBIOS
[294]73
[262]74 cmp dl, al ; Below first supported?
[294]75 jb SHORT .DiskIsNotHandledByThisBIOS
[258]76%endif
[262]77 ; fall-through to CalcDPTForDriveNumber
[150]78
79;--------------------------------------------------------------------
80; Finds Disk Parameter Table for drive number.
[294]81; Not intended to be called except by FindDPT_ForDriveNumberInDL
[150]82;
[262]83; CalcDPTForDriveNumber
[150]84; Parameters:
85; DL: Drive number
86; DS: RAMVARS segment
[294]87; DI: Saved copy of AX from entry at FindDPT_ForDriveNumberInDL
[150]88; Returns:
89; DS:DI: Ptr to DPT
[262]90; CF: Clear
[150]91; Corrupts registers:
[3]92; Nothing
93;--------------------------------------------------------------------
94ALIGN JUMP_ALIGN
[262]95.CalcDPTForDriveNumber:
[150]96 push dx
[3]97
[258]98%ifdef MODULE_SERIAL_FLOPPY
99 mov ax, [RAMVARS.wDrvCntAndFirst]
[294]100
[258]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
[294]106
107ALIGN JUMP_ALIGN
[258]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
[262]113
[294]114.CalcDPTForNewDrive:
[150]115 mov al, LARGEST_DPT_SIZE
[294]116
[150]117 mul dl
[294]118 add ax, BYTE RAMVARS_size ; Clears CF (will not overflow)
[3]119
[150]120 pop dx
[262]121
122 xchg di, ax ; Restore AX from entry at FindDPT_ForDriveNumber, put DPT pointer in DI
[150]123 ret
124
[294]125ALIGN JUMP_ALIGN
126.DiskIsNotHandledByThisBIOS:
[259]127;
[262]128; Drive not found...
129;
130 xor ax, ax ; Clear DPT pointer
[294]131 stc ; Is not supported by our BIOS
132
[262]133 xchg di, ax ; Restore AX from save at top
[259]134 ret
135
[271]136
[259]137;--------------------------------------------------------------------
[271]138; FindDPT_ForIdevarsOffsetInDL
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_ForIdevarsOffsetInDL:
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;--------------------------------------------------------------------
[294]154; Iteration routine for FindDPT_ForIdevarsOffsetInDL,
[271]155; for use with IterateAllDPTs
[294]156;
[271]157; Returns when DPT is found on the controller with Idevars offset in DL
158;
159; IterateFindFirstDPTforIdevars
160; DL: Offset to IDEVARS to search from DPTs
161; DS:DI: Ptr to DPT to examine
162; Returns:
163; CF: Clear if wanted DPT found
164; Set if wrong DPT
165;--------------------------------------------------------------------
[294]166IterateFindFirstDPTforIdevars:
[271]167 cmp dl, [di+DPT.bIdevarsOffset] ; Clears CF if matched
168 je .done
169 stc ; Set CF for not found
[294]170.done:
[271]171 ret
172
173
174;--------------------------------------------------------------------
[262]175; Finds pointer to first unused Disk Parameter Table.
176; Should only be used before DetectDrives is complete (not valid after this time).
[3]177;
[262]178; FindDPT_ForNewDriveToDSDI
[3]179; Parameters:
180; DS: RAMVARS segment
181; Returns:
[262]182; DS:DI: Ptr to first unused DPT
[3]183; Corrupts registers:
[262]184; AX
[3]185;--------------------------------------------------------------------
[262]186ALIGN JUMP_ALIGN
187FindDPT_ForNewDriveToDSDI:
188 push dx
[294]189
[262]190%ifdef MODULE_SERIAL_FLOPPY
191 mov dx, [RAMVARS.wDrvCntAndFlopCnt]
192 add dl, dh
193%else
194 mov dl, [RAMVARS.bDrvCnt]
195%endif
[294]196
[262]197 jmp short FindDPT_ForDriveNumberInDL.CalcDPTForNewDrive
[3]198
[152]199;--------------------------------------------------------------------
[233]200; IterateToDptWithFlagsHighInBL
[152]201; Parameters:
202; DS:DI: Ptr to DPT to examine
[294]203; BL: Bit(s) to test in DPT.bFlagsHigh
[152]204; Returns:
[262]205; CF: Clear if wanted DPT found
206; Set if wrong DPT
[152]207; Corrupts registers:
208; Nothing
209;--------------------------------------------------------------------
210ALIGN JUMP_ALIGN
[294]211IterateToDptWithFlagsHighInBL:
212 test [di+DPT.bFlagsHigh], bl ; Clears CF
[262]213 jnz SHORT .ReturnRightDPT
214 stc
[294]215.ReturnRightDPT:
[3]216 ret
217
218;--------------------------------------------------------------------
[233]219; FindDPT_ToDSDIforSerialDevice
[161]220; Parameters:
221; DS: RAMVARS segment
222; Returns:
223; DS:DI: Ptr to DPT
224; CF: Set if wanted DPT found
225; Cleared if DPT not found
226; Corrupts registers:
[203]227; SI
[161]228;--------------------------------------------------------------------
[265]229%ifdef MODULE_SERIAL
[294]230ALIGN JUMP_ALIGN
231FindDPT_ToDSDIforSerialDevice:
[233]232 mov bl, FLGH_DPT_SERIAL_DEVICE
233; fall-through
[265]234%endif
[294]235
[233]236;--------------------------------------------------------------------
237; FindDPT_ToDSDIforFlagsHigh
238; Parameters:
239; DS: RAMVARS segment
240; BL: Bit(s) to test in DPT.bFlagsHigh
241; Returns:
242; DS:DI: Ptr to DPT
243; CF: Set if wanted DPT found
244; Cleared if DPT not found
245; Corrupts registers:
246; SI
247;--------------------------------------------------------------------
[161]248ALIGN JUMP_ALIGN
[294]249FindDPT_ToDSDIforFlagsHighInBL:
[233]250 mov si, IterateToDptWithFlagsHighInBL
[161]251 ; Fall to IterateAllDPTs
252
253;--------------------------------------------------------------------
[3]254; Iterates all Disk Parameter Tables.
255;
[271]256; FindDPT_IterateAllDPTs
[3]257; Parameters:
[152]258; AX,BX,DX: Parameters to callback function
259; CS:SI: Ptr to callback function
[262]260; Callback routine should return CF=clear if found
[152]261; DS: RAMVARS segment
[3]262; Returns:
[152]263; DS:DI: Ptr to wanted DPT (if found)
[258]264; If not found, points to first empty DPT
[262]265; CF: Clear if wanted DPT found
266; Set if DPT not found, or no DPTs present
[3]267; Corrupts registers:
[150]268; Nothing unless corrupted by callback function
[3]269;--------------------------------------------------------------------
270ALIGN JUMP_ALIGN
[271]271FindDPT_IterateAllDPTs:
[3]272 push cx
[258]273
274 mov di, RAMVARS_size ; Point DS:DI to first DPT
[294]275 eMOVZX cx, [RAMVARS.bDrvCnt]
[262]276 jcxz .NotFound ; Return if no drives
[294]277
[3]278ALIGN JUMP_ALIGN
279.LoopWhileDPTsLeft:
280 call si ; Is wanted DPT?
[262]281 jnc SHORT .Found ; If so, return
282 add di, BYTE LARGEST_DPT_SIZE ; Point to next DPT
[258]283 loop .LoopWhileDPTsLeft
[262]284
[3]285ALIGN JUMP_ALIGN
[262]286.NotFound:
287 stc
288
289ALIGN JUMP_ALIGN
290.Found:
[3]291 pop cx
292 ret
[259]293
Note: See TracBrowser for help on using the repository browser.