source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm@ 341

Last change on this file since 341 was 324, checked in by aitotat@…, 13 years ago

Changes to XTIDE Universal BIOS:

  • Boot Menu now displays correct capacity when using user defined LBA.
File size: 7.7 KB
RevLine 
[99]1; Project name : XTIDE Universal BIOS
[3]2; Description : Functions for accessing DPT data.
3
4; Section containing code
5SECTION .text
6
7;--------------------------------------------------------------------
[150]8; AccessDPT_GetDriveSelectByteToAL
9; Parameters:
10; DS:DI: Ptr to Disk Parameter Table
11; Returns:
12; AL: Drive Select Byte
13; Corrupts registers:
14; Nothing
15;--------------------------------------------------------------------
16ALIGN JUMP_ALIGN
17AccessDPT_GetDriveSelectByteToAL:
18 mov al, [di+DPT.wFlags]
19 and al, FLG_DRVNHEAD_LBA | FLG_DRVNHEAD_DRV
20 or al, MASK_DRVNHEAD_SET ; Bits set to 1 for old drives
21 ret
22
23
24;--------------------------------------------------------------------
25; AccessDPT_GetDeviceControlByteToAL
26; Parameters:
27; DS:DI: Ptr to Disk Parameter Table
28; Returns:
29; AL: Device Control Byte
30; Corrupts registers:
31; Nothing
32;--------------------------------------------------------------------
33ALIGN JUMP_ALIGN
34AccessDPT_GetDeviceControlByteToAL:
35 xor al, al
[158]36 test BYTE [di+DPT.bFlagsLow], FLGL_DPT_ENABLE_IRQ
[150]37 jnz SHORT .EnableDeviceIrq
38 or al, FLG_DEVCONTROL_nIEN ; Disable IRQ
39.EnableDeviceIrq:
40 ret
41
[227]42
[150]43;--------------------------------------------------------------------
[227]44; AccessDPT_GetLCHStoAXBLBH
[3]45; Parameters:
46; DS:DI: Ptr to Disk Parameter Table
47; Returns:
[227]48; AX: Number of L-CHS cylinders
49; BL: Number of L-CHS heads
50; BH: Number of L-CHS sectors per track
[3]51; Corrupts registers:
[227]52; CX, DX
[3]53;--------------------------------------------------------------------
[227]54AccessDPT_GetLCHStoAXBLBH:
55 ; Return LBA-assisted CHS if LBA addressing used
[173]56 test BYTE [di+DPT.bFlagsLow], FLG_DRVNHEAD_LBA
[227]57 jz SHORT .ConvertPchsToLchs
[173]58
[227]59 call AccessDPT_GetLbaSectorCountToBXDXAX
[324]60 call AccessDPT_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH
[227]61 test dx, dx
62 jnz SHORT .LimitAXtoMaxLCHScylinders
63 cmp ax, MAX_LCHS_CYLINDERS
[230]64 jb SHORT .returnLCHS
[227]65.LimitAXtoMaxLCHScylinders:
66 mov ax, MAX_LCHS_CYLINDERS
67.returnLCHS:
68 ret
[173]69
[227]70.ConvertPchsToLchs:
71 mov ax, [di+DPT.wPchsCylinders]
72 mov bx, [di+DPT.wPchsHeadsAndSectors]
[230]73 ; Fall to AccessDPT_ShiftPCHinAXBLtoLCH
[227]74
75
76;--------------------------------------------------------------------
77; AccessDPT_ShiftPCHinAXBLtoLCH
[173]78; Parameters:
[227]79; AX: P-CHS cylinders (1...16383)
80; BL: P-CHS heads (1...16)
[173]81; Returns:
[227]82; AX: Number of L-CHS cylinders (1...1024)
83; BL: Number of L-CHS heads (1...255)
[230]84; CX: Number of bits shifted (4 at most)
[173]85; Corrupts registers:
86; Nothing
87;--------------------------------------------------------------------
[227]88AccessDPT_ShiftPCHinAXBLtoLCH:
[173]89 xor cx, cx
90.ShiftLoop:
[227]91 cmp ax, MAX_LCHS_CYLINDERS ; Need to shift?
[231]92 jbe SHORT .Return ; If not, return
[173]93 inc cx ; Increment shift count
[227]94 shr ax, 1 ; Halve cylinders
95 shl bl, 1 ; Double heads
[231]96 jnz SHORT .ShiftLoop ; Falls through only on the last (4th) iteration and only if BL was 16 on entry
97 dec bl ; DOS doesn't support drives with 256 heads so we limit heads to 255
98 ; We can save a byte here by using DEC BX if we don't care about BH
99.Return:
[173]100 ret
101
[227]102
[173]103;--------------------------------------------------------------------
[230]104; AccessDPT_GetLbaSectorCountToBXDXAX
105; Parameters:
106; DS:DI: Ptr to Disk Parameter Table
107; Returns:
108; BX:DX:AX: 48-bit sector count
109; Corrupts registers:
110; Nothing
111;--------------------------------------------------------------------
112AccessDPT_GetLbaSectorCountToBXDXAX:
113 mov ax, [di+DPT.twLbaSectors]
114 mov dx, [di+DPT.twLbaSectors+2]
115 mov bx, [di+DPT.twLbaSectors+4]
116 ret
117
118
119;--------------------------------------------------------------------
[3]120; Returns pointer to DRVPARAMS for master or slave drive.
121;
122; AccessDPT_GetPointerToDRVPARAMStoCSBX
123; Parameters:
124; DS:DI: Ptr to Disk Parameter Table
125; Returns:
126; CS:BX: Ptr to DRVPARAMS
127; Corrupts registers:
128; Nothing
129;--------------------------------------------------------------------
130ALIGN JUMP_ALIGN
131AccessDPT_GetPointerToDRVPARAMStoCSBX:
[150]132 eMOVZX bx, [di+DPT.bIdevarsOffset] ; CS:BX points to IDEVARS
133 add bx, BYTE IDEVARS.drvParamsMaster ; CS:BX points to Master Drive DRVPARAMS
[158]134 test BYTE [di+DPT.bFlagsLow], FLGL_DPT_SLAVE
[150]135 jz SHORT .ReturnPointerToDRVPARAMS
136 add bx, BYTE DRVPARAMS_size ; CS:BX points to Slave Drive DRVPARAMS
137.ReturnPointerToDRVPARAMS:
[3]138 ret
[200]139
140;--------------------------------------------------------------------
141; AccessDPT_GetUnshiftedAddressModeToALZF
142; Parameters:
143; DS:DI: Ptr to Disk Parameter Table
144; Returns:
[230]145; AL: Addressing Mode (L-CHS, P-CHS, LBA28, LBA48)
[200]146; unshifted (still shifted where it is in bFlagsLow)
147; ZF: Set based on value in AL
148; Corrupts registers:
149; AL
150;--------------------------------------------------------------------
[230]151;
152; Converted to a macro since only called in two places, and the call/ret overhead
[200]153; is not worth it for these two instructions (4 bytes total)
154;
155%macro AccessDPT_GetUnshiftedAddressModeToALZF 0
156 mov al, [di+DPT.bFlagsLow]
157 and al, MASKL_DPT_ADDRESSING_MODE
158%endmacro
[324]159
160
161;--------------------------------------------------------------------
162; LBA assist calculation:
163; this is how to fit a big drive into INT13's skimpy size requirements,
164; with a maximum of 8.4G available.
165;
166; total LBAs (as obtained by words 60+61)
167; divided by 63 (sectors per track) (save as value A)
168; Sub 1 from A
169; divide A by 1024 + truncate.
170; == total number of heads to use.
171; add 1
172; this value must be either 16, 32, 64, 128, or 256 (round up)
173; then take the value A above and divide by # of heads
174; to get the # of cylinders to use.
175;
176;
177; so a LBA28 drive will have 268,435,456 as maximum LBAs
178;
179; 10000000h / 63 = 410410h (total cylinders or tracks)
180; 410410h / 1024 = 1041h, which is way more than 256 heads, but 256 is max.
181; 410410h / 256 = 4104h cylinders
182;
183; there's a wealth of information at: http://www.mossywell.com/boot-sequence
184; they show a slightly different approach to LBA assist calulations, but
185; the method here provides compatibility with phoenix BIOS
186;
187; we're using the values from 60+61 here because we're topping out at 8.4G
188; anyway, so there's no need to use the 48bit LBA values.
189;
190; AccessDPT_ConvertSectorCountFromBXDXAXtoLbaAssistedCHStoDXAXBLBH:
191; Parameters:
192; BX:DX:AX: Total number of sectors
193; Returns:
194; DX:AX: Number of cylinders
195; BH: Number of sectors per track (always 63)
196; BL: Number of heads (16, 32, 64, 128 or 255)
197; Corrupts registers:
198; CX
199;--------------------------------------------------------------------
200AccessDPT_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH:
201 push bp
202 push si
203
204 ; Value A = Total sector count / 63
205 xor cx, cx
206 push cx ; Push zero for bits 48...63
207 push bx
208 push dx
209 push ax ; 64-bit sector count now in stack
210 mov cl, LBA_ASSIST_SPT
211 mov bp, sp ; SS:BP now points sector count
212 call Math_DivQWatSSBPbyCX ; Temporary value A now in stack
213
214 ; BX = Number of heads = A / 1024
215 mov ax, [bp]
216 mov dx, [bp+2]
217 mov bx, [bp+4]
218 call Size_DivideSizeInBXDXAXby1024andIncrementMagnitudeInCX
219
220 ; Heads must be 16, 32, 64, 128 or 256 (round up)
221 mov bx, 256 ; Max number of heads
222 test dx, dx ; 65536 or more heads?
223 jnz SHORT .GetNumberOfCylinders
224 mov cx, 128 ; Half BX for rounding up
225.FindMostSignificantBitForHeadSize:
226 cmp ax, cx
227 jae SHORT .GetNumberOfCylinders
228 shr cx, 1
229 shr bx, 1 ; Halve number of heads
230 jmp SHORT .FindMostSignificantBitForHeadSize
231
232 ; DX:AX = Number of cylinders = A / number of heads
233.GetNumberOfCylinders:
234 mov cx, bx
235 call Math_DivQWatSSBPbyCX
236 mov ax, [bp]
237 mov dx, [bp+2] ; Cylinders now in DX:AX
238
239 ; Return LBA assisted CHS
240 add sp, BYTE 8 ; Clean stack
241 sub bl, bh ; Limit heads to 255
242 mov bh, LBA_ASSIST_SPT
243 pop si
244 pop bp
245 ret
Note: See TracBrowser for help on using the repository browser.