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

Last change on this file since 277 was 277, checked in by gregli@…, 12 years ago

Moved the bulk of the serial code to the assembly library, for inclusion in other utilities. Fixed a bug in int13h.asm when floppy support was not enabled that was preventing foreign drives from working properly.

File size: 7.9 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;--------------------------------------------------------------------
[262]8; Checks if drive is handled by this BIOS, and return DPT pointer.
[3]9;
[262]10; FindDPT_ForDriveNumberInDL       
[3]11;   Parameters:
[262]12;       DL:     Drive number
[3]13;       DS:     RAMVARS segment
14;   Returns:
[262]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
[3]19;   Corrupts registers:
[262]20;       Nothing
[150]21;--------------------------------------------------------------------
22ALIGN JUMP_ALIGN
[262]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
[258]32%ifdef MODULE_SERIAL_FLOPPY
[262]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
[277]46               
47    cbw                                         ; Always 0h (no floppy drive covered above)
48    adc     ah, al                              ; Add in first drive number and number of drives
49
[262]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           
[258]60%endif
[262]61    ; fall-through to CalcDPTForDriveNumber
[150]62
63;--------------------------------------------------------------------
64; Finds Disk Parameter Table for drive number.
[262]65; Note intended to be called except by FindDPT_ForDriveNumber
[150]66;
[262]67; CalcDPTForDriveNumber
[150]68;   Parameters:
69;       DL:     Drive number
70;       DS:     RAMVARS segment
[262]71;       DI:     Saved copy of AX from entry at FindDPT_ForDriveNumber
[150]72;   Returns:
73;       DS:DI:  Ptr to DPT
[262]74;       CF:     Clear
[150]75;   Corrupts registers:
[3]76;       Nothing
77;--------------------------------------------------------------------
78ALIGN JUMP_ALIGN
[262]79.CalcDPTForDriveNumber:
[150]80    push    dx
[3]81
[258]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
[262]90       
91ALIGN JUMP_ALIGN               
[258]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
[262]97
98.CalcDPTForNewDrive:               
[150]99    mov     al, LARGEST_DPT_SIZE
[258]100       
[150]101    mul     dl
[262]102    add     ax, BYTE RAMVARS_size       ; Clears CF (will not oveflow)
[3]103
[150]104    pop     dx
[262]105
106    xchg    di, ax                      ; Restore AX from entry at FindDPT_ForDriveNumber, put DPT pointer in DI
[150]107    ret
108
[262]109ALIGN JUMP_ALIGN       
110.DiskIsNotHandledByThisBIOS:           
[259]111;
[262]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
[259]118    ret
119
[271]120
[259]121;--------------------------------------------------------------------
[271]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;--------------------------------------------------------------------
[262]159; Finds pointer to first unused Disk Parameter Table.
160; Should only be used before DetectDrives is complete (not valid after this time).
[3]161;
[262]162; FindDPT_ForNewDriveToDSDI
[3]163;   Parameters:
164;       DS:     RAMVARS segment
165;   Returns:
[262]166;       DS:DI:  Ptr to first unused DPT
[3]167;   Corrupts registers:
[262]168;       AX
[3]169;--------------------------------------------------------------------
[262]170ALIGN JUMP_ALIGN
171FindDPT_ForNewDriveToDSDI:
172    push    dx
[200]173       
[262]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
[3]182
[152]183;--------------------------------------------------------------------
[233]184; IterateToDptWithFlagsHighInBL
[152]185;   Parameters:
186;       DS:DI:  Ptr to DPT to examine
[233]187;       BL:     Bit(s) to test in DPT.bFlagsHigh 
[152]188;   Returns:
[262]189;       CF:     Clear if wanted DPT found
190;               Set if wrong DPT
[152]191;   Corrupts registers:
192;       Nothing
193;--------------------------------------------------------------------
194ALIGN JUMP_ALIGN
[233]195IterateToDptWithFlagsHighInBL:     
[262]196    test    BYTE [di+DPT.bFlagsHigh], bl        ; Clears CF
197    jnz     SHORT .ReturnRightDPT
198    stc
199.ReturnRightDPT:       
[3]200    ret
201
202;--------------------------------------------------------------------
[233]203; FindDPT_ToDSDIforSerialDevice
[161]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:
[203]211;       SI
[161]212;--------------------------------------------------------------------
[265]213%ifdef MODULE_SERIAL
[233]214ALIGN JUMP_ALIGN       
215FindDPT_ToDSDIforSerialDevice:         
216    mov     bl, FLGH_DPT_SERIAL_DEVICE
217; fall-through
[265]218%endif
[233]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;--------------------------------------------------------------------
[161]232ALIGN JUMP_ALIGN
[233]233FindDPT_ToDSDIforFlagsHighInBL:     
234    mov     si, IterateToDptWithFlagsHighInBL
[161]235    ; Fall to IterateAllDPTs
236
237;--------------------------------------------------------------------
[3]238; Iterates all Disk Parameter Tables.
239;
[271]240; FindDPT_IterateAllDPTs
[3]241;   Parameters:
[152]242;       AX,BX,DX:   Parameters to callback function
243;       CS:SI:      Ptr to callback function
[262]244;                   Callback routine should return CF=clear if found
[152]245;       DS:         RAMVARS segment
[3]246;   Returns:
[152]247;       DS:DI:      Ptr to wanted DPT (if found)
[258]248;                   If not found, points to first empty DPT
[262]249;       CF:         Clear if wanted DPT found
250;                   Set if DPT not found, or no DPTs present
[3]251;   Corrupts registers:
[150]252;       Nothing unless corrupted by callback function
[3]253;--------------------------------------------------------------------
254ALIGN JUMP_ALIGN
[271]255FindDPT_IterateAllDPTs:
[3]256    push    cx
[258]257
258    mov     di, RAMVARS_size            ; Point DS:DI to first DPT
259       
[259]260    mov     cl, [RAMVARS.bDrvCnt]
261    xor     ch, ch                      ; Clears CF 
[258]262       
[262]263    jcxz    .NotFound                   ; Return if no drives
[259]264       
[3]265ALIGN JUMP_ALIGN
266.LoopWhileDPTsLeft:
267    call    si                          ; Is wanted DPT?
[262]268    jnc     SHORT .Found                ;  If so, return
269    add     di, BYTE LARGEST_DPT_SIZE   ; Point to next DPT
[258]270    loop    .LoopWhileDPTsLeft
[262]271
[3]272ALIGN JUMP_ALIGN
[262]273.NotFound:
274    stc
275
276ALIGN JUMP_ALIGN
277.Found:
[3]278    pop     cx
279    ret
[259]280
Note: See TracBrowser for help on using the repository browser.