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

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

Added floppy drive emulation over the serial connection (MODULE_SERIAL_FLOPPY). Along the way, various optimizations were made to stay within the 8K ROM size target. Also, serial code now returns the number of sectors transferred.

File size: 6.3 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;       DX
17;--------------------------------------------------------------------
18ALIGN JUMP_ALIGN
19FindDPT_ForNewDriveToDSDI:
20    mov     ax, [RAMVARS.wDrvCntAndFirst]
21    add     al, ah
22%ifdef MODULE_SERIAL_FLOPPY
23    add     al, [RAMVARS.xlateVars+XLATEVARS.bFlopCreateCnt]
24%endif
25    xchg    ax, dx     
26    ; Fall to FindDPT_ForDriveNumber
27
28
29;--------------------------------------------------------------------
30; Finds Disk Parameter Table for drive number.
31; IDE Base Port address will be stored to RAMVARS if correct DPT is found.
32;
33; FindDPT_ForDriveNumber
34;   Parameters:
35;       DL:     Drive number
36;       DS:     RAMVARS segment
37;   Returns:
38;       DS:DI:  Ptr to DPT
39;   Corrupts registers:
40;       Nothing
41;--------------------------------------------------------------------
42ALIGN JUMP_ALIGN
43FindDPT_ForDriveNumber:
44    push    dx
45    xchg    di, ax  ; Save the contents of AX in DI
46
47%ifdef MODULE_SERIAL_FLOPPY
48    mov     ax, [RAMVARS.wDrvCntAndFirst]
49       
50    test    dl, dl
51    js      .harddisk
52
53    call    RamVars_UnpackFlopCntAndFirstToAL
54    add     dl, ah                      ; add in end of hard disk DPT list, floppies start immediately after
55.harddisk:
56    sub     dl, al                      ; subtract off beginning of either hard disk or floppy list (as appropriate)
57%else
58    sub     dl, [RAMVARS.bFirstDrv]     ; subtract off beginning of hard disk list
59%endif
60       
61    mov     al, LARGEST_DPT_SIZE
62       
63    mul     dl
64    add     ax, BYTE RAMVARS_size
65
66    xchg    di, ax                      ; Restore AX and put result in DI
67    pop     dx
68    ret
69
70;--------------------------------------------------------------------
71; Finds Disk Parameter Table for
72; Master or Slave drive at wanted port.
73;
74; FindDPT_ToDSDIForIdeMasterAtPortDX
75; FindDPT_ToDSDIForIdeSlaveAtPortDX
76;   Parameters:
77;       DX:     IDE Base Port address
78;       DS:     RAMVARS segment
79;   Returns:
80;       DL:     Drive number (if DPT found)
81;       DS:DI:  Ptr to DPT
82;       CF:     Set if wanted DPT found
83;               Cleared if DPT not found
84;   Corrupts registers:
85;       SI
86;
87; Converted to macros since there is only once call site for each of these
88;
89;--------------------------------------------------------------------
90   
91%macro FindDPT_ToDSDIForIdeMasterAtPortDX 0
92    mov     si, IterateToMasterAtPortCallback
93    call    IterateAllDPTs
94%endmacro
95
96%macro FindDPT_ToDSDIForIdeSlaveAtPortDX 0
97    mov     si, IterateToSlaveAtPortCallback
98    call    IterateAllDPTs
99%endmacro
100
101       
102;--------------------------------------------------------------------
103; Iteration callback for finding DPT using
104; IDE base port for Master or Slave drive.
105;
106; IterateToSlaveAtPortCallback
107; IterateToMasterAtPortCallback
108;   Parameters:
109;       DX:     IDE Base Port address
110;       DS:DI:  Ptr to DPT to examine
111;   Returns:
112;       CF:     Set if wanted DPT found
113;               Cleared if wrong DPT
114;   Corrupts registers:
115;       Nothing
116;--------------------------------------------------------------------
117ALIGN JUMP_ALIGN
118IterateToSlaveAtPortCallback:
119    test    BYTE [di+DPT.bFlagsLow], FLGL_DPT_SLAVE ; Clears CF
120    jnz     SHORT CompareBasePortAddress
121    ret     ; Wrong DPT
122
123ALIGN JUMP_ALIGN
124IterateToMasterAtPortCallback:
125    test    BYTE [di+DPT.bFlagsLow], FLGL_DPT_SLAVE
126    jnz     SHORT ReturnWrongDPT                ; Return if slave drive
127
128CompareBasePortAddress:
129    push    bx
130    eMOVZX  bx, BYTE [di+DPT.bIdevarsOffset]    ; CS:BX now points to IDEVARS
131    cmp     dx, [cs:bx+IDEVARS.wPort]           ; Wanted port?
132    pop     bx
133    jne     SHORT ReturnWrongDPT
134
135ReturnRightDPT:
136    stc                                         ; Set CF since wanted DPT
137    ret
138
139
140;--------------------------------------------------------------------
141; IterateToDptWithFlagsHighInBL
142;   Parameters:
143;       DS:DI:  Ptr to DPT to examine
144;       BL:     Bit(s) to test in DPT.bFlagsHigh 
145;   Returns:
146;       CF:     Set if wanted DPT found
147;               Cleared if wrong DPT
148;   Corrupts registers:
149;       Nothing
150;--------------------------------------------------------------------
151ALIGN JUMP_ALIGN
152IterateToDptWithFlagsHighInBL:     
153    test    BYTE [di+DPT.bFlagsHigh], bl        ; Clears CF (but we need the clc
154                                                ; below anyway for callers above)
155    jnz     SHORT ReturnRightDPT
156
157ReturnWrongDPT:
158    clc                                     ; Clear CF since wrong DPT
159    ret
160
161;--------------------------------------------------------------------
162; FindDPT_ToDSDIforSerialDevice
163;   Parameters:
164;       DS:     RAMVARS segment
165;   Returns:
166;       DS:DI:  Ptr to DPT
167;       CF:     Set if wanted DPT found
168;               Cleared if DPT not found
169;   Corrupts registers:
170;       SI
171;--------------------------------------------------------------------
172ALIGN JUMP_ALIGN       
173FindDPT_ToDSDIforSerialDevice:         
174    mov     bl, FLGH_DPT_SERIAL_DEVICE
175; fall-through
176               
177;--------------------------------------------------------------------
178; FindDPT_ToDSDIforFlagsHigh
179;   Parameters:
180;       DS:     RAMVARS segment
181;       BL:     Bit(s) to test in DPT.bFlagsHigh
182;   Returns:
183;       DS:DI:  Ptr to DPT
184;       CF:     Set if wanted DPT found
185;               Cleared if DPT not found
186;   Corrupts registers:
187;       SI
188;--------------------------------------------------------------------
189ALIGN JUMP_ALIGN
190FindDPT_ToDSDIforFlagsHighInBL:     
191    mov     si, IterateToDptWithFlagsHighInBL
192    ; Fall to IterateAllDPTs
193
194;--------------------------------------------------------------------
195; Iterates all Disk Parameter Tables.
196;
197; IterateAllDPTs
198;   Parameters:
199;       AX,BX,DX:   Parameters to callback function
200;       CS:SI:      Ptr to callback function
201;       DS:         RAMVARS segment
202;   Returns:
203;       DS:DI:      Ptr to wanted DPT (if found)
204;                   If not found, points to first empty DPT
205;       CF:         Set if wanted DPT found
206;                   Cleared if DPT not found, or no DPTs present
207;   Corrupts registers:
208;       Nothing unless corrupted by callback function
209;--------------------------------------------------------------------
210ALIGN JUMP_ALIGN
211IterateAllDPTs:
212    push    cx
213
214    mov     cl, [RAMVARS.bDrvCnt]       
215    mov     ch, 0
216       
217    mov     di, RAMVARS_size            ; Point DS:DI to first DPT
218       
219    jcxz    .NotFound                   ; Return if no drives
220       
221ALIGN JUMP_ALIGN
222.LoopWhileDPTsLeft:
223    call    si                          ; Is wanted DPT?
224    jc      SHORT .AllDptsIterated      ;  If so, return
225    add     di, BYTE LARGEST_DPT_SIZE   ; Point to next DPT
226    loop    .LoopWhileDPTsLeft
227       
228.NotFound:     
229    clc                                 ; Clear CF since DPT not found
230       
231ALIGN JUMP_ALIGN
232.AllDptsIterated:
233    pop     cx
234    ret
Note: See TracBrowser for help on using the repository browser.