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

Last change on this file since 258 was 258, checked in by gregli@…, 13 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
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:
[258]16; DX
[150]17;--------------------------------------------------------------------
18ALIGN JUMP_ALIGN
19FindDPT_ForNewDriveToDSDI:
[258]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
[150]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:
[3]40; Nothing
41;--------------------------------------------------------------------
42ALIGN JUMP_ALIGN
[150]43FindDPT_ForDriveNumber:
44 push dx
[161]45 xchg di, ax ; Save the contents of AX in DI
[3]46
[258]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
[150]61 mov al, LARGEST_DPT_SIZE
[258]62
[150]63 mul dl
64 add ax, BYTE RAMVARS_size
[3]65
[258]66 xchg di, ax ; Restore AX and put result in DI
[150]67 pop dx
68 ret
69
[3]70;--------------------------------------------------------------------
71; Finds Disk Parameter Table for
72; Master or Slave drive at wanted port.
73;
[150]74; FindDPT_ToDSDIForIdeMasterAtPortDX
75; FindDPT_ToDSDIForIdeSlaveAtPortDX
[3]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:
[150]85; SI
[200]86;
87; Converted to macros since there is only once call site for each of these
88;
[3]89;--------------------------------------------------------------------
[200]90
91%macro FindDPT_ToDSDIForIdeMasterAtPortDX 0
[152]92 mov si, IterateToMasterAtPortCallback
[200]93 call IterateAllDPTs
94%endmacro
[3]95
[200]96%macro FindDPT_ToDSDIForIdeSlaveAtPortDX 0
[152]97 mov si, IterateToSlaveAtPortCallback
[200]98 call IterateAllDPTs
99%endmacro
[3]100
[200]101
[3]102;--------------------------------------------------------------------
103; Iteration callback for finding DPT using
104; IDE base port for Master or Slave drive.
105;
[152]106; IterateToSlaveAtPortCallback
107; IterateToMasterAtPortCallback
[3]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
[152]118IterateToSlaveAtPortCallback:
[158]119 test BYTE [di+DPT.bFlagsLow], FLGL_DPT_SLAVE ; Clears CF
[150]120 jnz SHORT CompareBasePortAddress
121 ret ; Wrong DPT
[3]122
123ALIGN JUMP_ALIGN
[152]124IterateToMasterAtPortCallback:
[158]125 test BYTE [di+DPT.bFlagsLow], FLGL_DPT_SLAVE
[150]126 jnz SHORT ReturnWrongDPT ; Return if slave drive
[3]127
[150]128CompareBasePortAddress:
[3]129 push bx
[150]130 eMOVZX bx, BYTE [di+DPT.bIdevarsOffset] ; CS:BX now points to IDEVARS
131 cmp dx, [cs:bx+IDEVARS.wPort] ; Wanted port?
[3]132 pop bx
[150]133 jne SHORT ReturnWrongDPT
[200]134
135ReturnRightDPT:
[150]136 stc ; Set CF since wanted DPT
[3]137 ret
[152]138
139
140;--------------------------------------------------------------------
[233]141; IterateToDptWithFlagsHighInBL
[152]142; Parameters:
143; DS:DI: Ptr to DPT to examine
[233]144; BL: Bit(s) to test in DPT.bFlagsHigh
[152]145; Returns:
146; CF: Set if wanted DPT found
147; Cleared if wrong DPT
148; Corrupts registers:
149; Nothing
150;--------------------------------------------------------------------
151ALIGN JUMP_ALIGN
[233]152IterateToDptWithFlagsHighInBL:
153 test BYTE [di+DPT.bFlagsHigh], bl ; Clears CF (but we need the clc
154 ; below anyway for callers above)
[200]155 jnz SHORT ReturnRightDPT
156
[150]157ReturnWrongDPT:
[152]158 clc ; Clear CF since wrong DPT
[3]159 ret
160
161;--------------------------------------------------------------------
[233]162; FindDPT_ToDSDIforSerialDevice
[161]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:
[203]170; SI
[161]171;--------------------------------------------------------------------
[233]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;--------------------------------------------------------------------
[161]189ALIGN JUMP_ALIGN
[233]190FindDPT_ToDSDIforFlagsHighInBL:
191 mov si, IterateToDptWithFlagsHighInBL
[161]192 ; Fall to IterateAllDPTs
193
194;--------------------------------------------------------------------
[3]195; Iterates all Disk Parameter Tables.
196;
[150]197; IterateAllDPTs
[3]198; Parameters:
[152]199; AX,BX,DX: Parameters to callback function
200; CS:SI: Ptr to callback function
201; DS: RAMVARS segment
[3]202; Returns:
[152]203; DS:DI: Ptr to wanted DPT (if found)
[258]204; If not found, points to first empty DPT
[152]205; CF: Set if wanted DPT found
[200]206; Cleared if DPT not found, or no DPTs present
[3]207; Corrupts registers:
[150]208; Nothing unless corrupted by callback function
[3]209;--------------------------------------------------------------------
210ALIGN JUMP_ALIGN
[150]211IterateAllDPTs:
[3]212 push cx
[258]213
214 mov cl, [RAMVARS.bDrvCnt]
215 mov ch, 0
216
217 mov di, RAMVARS_size ; Point DS:DI to first DPT
218
[200]219 jcxz .NotFound ; Return if no drives
[258]220
[3]221ALIGN JUMP_ALIGN
222.LoopWhileDPTsLeft:
223 call si ; Is wanted DPT?
[150]224 jc SHORT .AllDptsIterated ; If so, return
225 add di, BYTE LARGEST_DPT_SIZE ; Point to next DPT
[258]226 loop .LoopWhileDPTsLeft
227
[200]228.NotFound:
[3]229 clc ; Clear CF since DPT not found
[258]230
[3]231ALIGN JUMP_ALIGN
[150]232.AllDptsIterated:
[3]233 pop cx
234 ret
Note: See TracBrowser for help on using the repository browser.