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

Last change on this file since 200 was 200, checked in by gregli@…, 11 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
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; Finds pointer to first unused Disk Parameter Table.
9;
10; FindDPT_ForNewDriveToDSDI
11;   Parameters:
12;       DS:     RAMVARS segment
13;   Returns:
14;       DS:DI:  Ptr to first unused DPT
15;   Corrupts registers:
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:
36;       Nothing
37;--------------------------------------------------------------------
38ALIGN JUMP_ALIGN
39FindDPT_ForDriveNumber:
40    push    dx
41    xchg    di, ax  ; Save the contents of AX in DI
42
43    mov     al, LARGEST_DPT_SIZE
44    sub     dl, [RAMVARS.bFirstDrv]
45    mul     dl
46    add     ax, BYTE RAMVARS_size
47
48    xchg    di, ax  ; Restore AX and put result in DI
49    pop     dx
50    ret
51
52;--------------------------------------------------------------------
53; Finds Disk Parameter Table for
54; Master or Slave drive at wanted port.
55;
56; FindDPT_ToDSDIForIdeMasterAtPortDX
57; FindDPT_ToDSDIForIdeSlaveAtPortDX
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:
67;       SI
68;
69; Converted to macros since there is only once call site for each of these
70;
71;--------------------------------------------------------------------
72   
73%macro FindDPT_ToDSDIForIdeMasterAtPortDX 0
74    mov     si, IterateToMasterAtPortCallback
75    call    IterateAllDPTs
76%endmacro
77
78%macro FindDPT_ToDSDIForIdeSlaveAtPortDX 0
79    mov     si, IterateToSlaveAtPortCallback
80    call    IterateAllDPTs
81%endmacro
82
83       
84;--------------------------------------------------------------------
85; Iteration callback for finding DPT using
86; IDE base port for Master or Slave drive.
87;
88; IterateToSlaveAtPortCallback
89; IterateToMasterAtPortCallback
90;   Parameters:
91;       CH:     Drive number
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
102IterateToSlaveAtPortCallback:
103    test    BYTE [di+DPT.bFlagsLow], FLGL_DPT_SLAVE ; Clears CF
104    jnz     SHORT CompareBasePortAddress
105    ret     ; Wrong DPT
106
107ALIGN JUMP_ALIGN
108IterateToMasterAtPortCallback:
109    test    BYTE [di+DPT.bFlagsLow], FLGL_DPT_SLAVE
110    jnz     SHORT ReturnWrongDPT                ; Return if slave drive
111
112CompareBasePortAddress:
113    push    bx
114    eMOVZX  bx, BYTE [di+DPT.bIdevarsOffset]    ; CS:BX now points to IDEVARS
115    cmp     dx, [cs:bx+IDEVARS.wPort]           ; Wanted port?
116    pop     bx
117    jne     SHORT ReturnWrongDPT
118    mov     dl, ch                              ; Return drive number in DL
119
120ReturnRightDPT:
121    stc                                         ; Set CF since wanted DPT
122    ret
123
124
125;--------------------------------------------------------------------
126; IterateToDptWithFlagsHighSet:
127;   Parameters:
128;       DS:DI:  Ptr to DPT to examine
129;       AL:     Bit in bFlagsHigh to test
130;   Returns:
131;       CF:     Set if wanted DPT found
132;               Cleared if wrong DPT
133;   Corrupts registers:
134;       Nothing
135;--------------------------------------------------------------------
136ALIGN JUMP_ALIGN
137IterateToDptWithFlagsHighSet:
138    test    BYTE [di+DPT.bFlagsHigh], al    ; Clears CF (but we need the clc below anyway callers above)
139    jnz     SHORT ReturnRightDPT
140
141ReturnWrongDPT:
142    clc                                     ; Clear CF since wrong DPT
143    ret
144
145;--------------------------------------------------------------------
146; FindDPT_ToDSDIforInterruptInService
147; FindDPT_ToDSDIforSerialDevice
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:
155;       SI, AX, BX (for SerialDevice only)
156;--------------------------------------------------------------------
157ALIGN JUMP_ALIGN
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
167FindDPT_ToDSDIforInterruptInService:
168    mov     al, FLGH_DPT_INTERRUPT_IN_SERVICE
169
170    mov     si, IterateToDptWithFlagsHighSet
171    ; Fall to IterateAllDPTs
172
173;--------------------------------------------------------------------
174; Iterates all Disk Parameter Tables.
175;
176; IterateAllDPTs
177;   Parameters:
178;       AX,BX,DX:   Parameters to callback function
179;       CS:SI:      Ptr to callback function
180;       DS:         RAMVARS segment
181;   Returns:
182;       DS:DI:      Ptr to wanted DPT (if found)
183;       CF:         Set if wanted DPT found
184;                   Cleared if DPT not found, or no DPTs present
185;   Corrupts registers:
186;       Nothing unless corrupted by callback function
187;--------------------------------------------------------------------
188ALIGN JUMP_ALIGN
189IterateAllDPTs:
190    push    cx
191    mov     cx, [RAMVARS.wDrvCntAndFirst]
192    jcxz    .NotFound                   ; Return if no drives
193    mov     di, RAMVARS_size            ; Point DS:DI to first DPT
194ALIGN JUMP_ALIGN
195.LoopWhileDPTsLeft:
196    call    si                          ; Is wanted DPT?
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
202.NotFound:     
203    clc                                 ; Clear CF since DPT not found
204ALIGN JUMP_ALIGN
205.AllDptsIterated:
206    pop     cx
207    ret
Note: See TracBrowser for help on using the repository browser.