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

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

Added logic to skip scanning COM ports if a COM port was already found during the normal detection process, to avoid finding the same serial drive twice and preseting the OS with two drives which in reality point to the same physical file on the server. Also added logic to skip scanning for the slave serial drive if the master was not found. And various small optimizations.

File size: 5.7 KB
RevLine 
[150]1; Project name : XTIDE Universal BIOS
[3]2; Description : Functions for finding Disk Parameter Table.
3
4; Section containing code
5SECTION .text
6
7;--------------------------------------------------------------------
8; Finds pointer to first unused Disk Parameter Table.
9;
[150]10; FindDPT_ForNewDriveToDSDI
[3]11; Parameters:
12; DS: RAMVARS segment
13; Returns:
14; DS:DI: Ptr to first unused DPT
15; Corrupts registers:
[150]16; DL
17;--------------------------------------------------------------------
18ALIGN JUMP_ALIGN
19FindDPT_ForNewDriveToDSDI:
20 mov dl, [RAMVARS.bFirstDrv]
21 add dl, [RAMVARS.bDrvCnt]
22 ; Fall to FindDPT_ForDriveNumber
23
24
25;--------------------------------------------------------------------
26; Finds Disk Parameter Table for drive number.
27; IDE Base Port address will be stored to RAMVARS if correct DPT is found.
28;
29; FindDPT_ForDriveNumber
30; Parameters:
31; DL: Drive number
32; DS: RAMVARS segment
33; Returns:
34; DS:DI: Ptr to DPT
35; Corrupts registers:
[3]36; Nothing
37;--------------------------------------------------------------------
38ALIGN JUMP_ALIGN
[150]39FindDPT_ForDriveNumber:
40 push dx
[161]41 xchg di, ax ; Save the contents of AX in DI
[3]42
[150]43 mov al, LARGEST_DPT_SIZE
44 sub dl, [RAMVARS.bFirstDrv]
45 mul dl
46 add ax, BYTE RAMVARS_size
[3]47
[161]48 xchg di, ax ; Restore AX and put result in DI
[150]49 pop dx
50 ret
51
[3]52;--------------------------------------------------------------------
53; Finds Disk Parameter Table for
54; Master or Slave drive at wanted port.
55;
[150]56; FindDPT_ToDSDIForIdeMasterAtPortDX
57; FindDPT_ToDSDIForIdeSlaveAtPortDX
[3]58; Parameters:
59; DX: IDE Base Port address
60; DS: RAMVARS segment
61; Returns:
62; DL: Drive number (if DPT found)
63; DS:DI: Ptr to DPT
64; CF: Set if wanted DPT found
65; Cleared if DPT not found
66; Corrupts registers:
[150]67; SI
[200]68;
69; Converted to macros since there is only once call site for each of these
70;
[3]71;--------------------------------------------------------------------
[200]72
73%macro FindDPT_ToDSDIForIdeMasterAtPortDX 0
[152]74 mov si, IterateToMasterAtPortCallback
[200]75 call IterateAllDPTs
76%endmacro
[3]77
[200]78%macro FindDPT_ToDSDIForIdeSlaveAtPortDX 0
[152]79 mov si, IterateToSlaveAtPortCallback
[200]80 call IterateAllDPTs
81%endmacro
[3]82
[200]83
[3]84;--------------------------------------------------------------------
85; Iteration callback for finding DPT using
86; IDE base port for Master or Slave drive.
87;
[152]88; IterateToSlaveAtPortCallback
89; IterateToMasterAtPortCallback
[3]90; Parameters:
[150]91; CH: Drive number
[3]92; DX: IDE Base Port address
93; DS:DI: Ptr to DPT to examine
94; Returns:
95; DL: Drive number if correct DPT
96; CF: Set if wanted DPT found
97; Cleared if wrong DPT
98; Corrupts registers:
99; Nothing
100;--------------------------------------------------------------------
101ALIGN JUMP_ALIGN
[152]102IterateToSlaveAtPortCallback:
[158]103 test BYTE [di+DPT.bFlagsLow], FLGL_DPT_SLAVE ; Clears CF
[150]104 jnz SHORT CompareBasePortAddress
105 ret ; Wrong DPT
[3]106
107ALIGN JUMP_ALIGN
[152]108IterateToMasterAtPortCallback:
[158]109 test BYTE [di+DPT.bFlagsLow], FLGL_DPT_SLAVE
[150]110 jnz SHORT ReturnWrongDPT ; Return if slave drive
[3]111
[150]112CompareBasePortAddress:
[3]113 push bx
[150]114 eMOVZX bx, BYTE [di+DPT.bIdevarsOffset] ; CS:BX now points to IDEVARS
115 cmp dx, [cs:bx+IDEVARS.wPort] ; Wanted port?
[3]116 pop bx
[150]117 jne SHORT ReturnWrongDPT
118 mov dl, ch ; Return drive number in DL
[200]119
120ReturnRightDPT:
[150]121 stc ; Set CF since wanted DPT
[3]122 ret
[152]123
124
125;--------------------------------------------------------------------
[200]126; IterateToDptWithFlagsHighSet:
[152]127; Parameters:
128; DS:DI: Ptr to DPT to examine
[200]129; AL: Bit in bFlagsHigh to test
[152]130; Returns:
131; CF: Set if wanted DPT found
132; Cleared if wrong DPT
133; Corrupts registers:
134; Nothing
135;--------------------------------------------------------------------
136ALIGN JUMP_ALIGN
[200]137IterateToDptWithFlagsHighSet:
138 test BYTE [di+DPT.bFlagsHigh], al ; Clears CF (but we need the clc below anyway callers above)
139 jnz SHORT ReturnRightDPT
140
[150]141ReturnWrongDPT:
[152]142 clc ; Clear CF since wrong DPT
[3]143 ret
144
145;--------------------------------------------------------------------
[161]146; FindDPT_ToDSDIforInterruptInService
[200]147; FindDPT_ToDSDIforSerialDevice
[161]148; Parameters:
149; DS: RAMVARS segment
150; Returns:
151; DS:DI: Ptr to DPT
152; CF: Set if wanted DPT found
153; Cleared if DPT not found
154; Corrupts registers:
[200]155; SI, AX, BX (for SerialDevice only)
[161]156;--------------------------------------------------------------------
157ALIGN JUMP_ALIGN
[200]158
159%ifdef MODULE_SERIAL
160FindDPT_ToDSDIforSerialDevice:
161 mov al, FLGH_DPT_SERIAL_DEVICE
162
163 SKIP2B bx
164%endif
165
166; do not align due to SKIP2B above
[161]167FindDPT_ToDSDIforInterruptInService:
[200]168 mov al, FLGH_DPT_INTERRUPT_IN_SERVICE
169
170 mov si, IterateToDptWithFlagsHighSet
[161]171 ; Fall to IterateAllDPTs
172
173;--------------------------------------------------------------------
[3]174; Iterates all Disk Parameter Tables.
175;
[150]176; IterateAllDPTs
[3]177; Parameters:
[152]178; AX,BX,DX: Parameters to callback function
179; CS:SI: Ptr to callback function
180; DS: RAMVARS segment
[3]181; Returns:
[152]182; DS:DI: Ptr to wanted DPT (if found)
183; CF: Set if wanted DPT found
[200]184; Cleared if DPT not found, or no DPTs present
[3]185; Corrupts registers:
[150]186; Nothing unless corrupted by callback function
[3]187;--------------------------------------------------------------------
188ALIGN JUMP_ALIGN
[150]189IterateAllDPTs:
[3]190 push cx
[150]191 mov cx, [RAMVARS.wDrvCntAndFirst]
[200]192 jcxz .NotFound ; Return if no drives
[152]193 mov di, RAMVARS_size ; Point DS:DI to first DPT
[3]194ALIGN JUMP_ALIGN
195.LoopWhileDPTsLeft:
196 call si ; Is wanted DPT?
[150]197 jc SHORT .AllDptsIterated ; If so, return
198 inc ch ; Increment drive number
199 add di, BYTE LARGEST_DPT_SIZE ; Point to next DPT
200 dec cl ; Decrement drives left
201 jnz SHORT .LoopWhileDPTsLeft
[200]202.NotFound:
[3]203 clc ; Clear CF since DPT not found
204ALIGN JUMP_ALIGN
[150]205.AllDptsIterated:
[3]206 pop cx
207 ret
Note: See TracBrowser for help on using the repository browser.