source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Address.asm@ 276

Last change on this file since 276 was 230, checked in by krille_n_@…, 13 years ago

Changes to XTIDE Universal BIOS:

  • Some small optimizations
File size: 5.7 KB
Line 
1; Project name : XTIDE Universal BIOS
2; Description : Functions for address translations.
3
4; Section containing code
5SECTION .text
6
7;---------------------------------------------------------------------
8; Address_ExtractLCHSparametersFromOldInt13hAddress
9; Parameters:
10; CH: Cylinder number, bits 7...0
11; CL: Bits 7...6: Cylinder number bits 9 and 8
12; Bits 5...0: Sector number
13; DH: Head number
14; Returns:
15; BL: Sector number (1...63)
16; BH: Head number (0...255)
17; CX: Cylinder number (0...1023)
18; Corrupts registers:
19; Nothing
20;--------------------------------------------------------------------
21ALIGN JUMP_ALIGN
22Address_ExtractLCHSparametersFromOldInt13hAddress:
23 mov bl, cl ; Copy sector number...
24 and bl, 3Fh ; ...and limit to 1...63
25 sub cl, bl ; Remove from cylinder number high
26 eROL_IM cl, 2 ; High bits to beginning
27 mov bh, dh ; Copy Head number
28 xchg cl, ch ; Cylinder number now in CX
29 ret
30
31
32;---------------------------------------------------------------------
33; Converts LCHS parameters to IDE P-CHS parameters.
34; PCylinder = (LCylinder << n) + (LHead / PHeadCount)
35; PHead = LHead % PHeadCount
36; PSector = LSector
37;
38; Address_ConvertLCHStoPCHS:
39; Parameters:
40; BL: Sector number (1...63)
41; BH: Head number (0...255)
42; CX: Cylinder number (0...1023)
43; DS:DI: Ptr to Disk Parameter Table
44; Returns:
45; BL: Sector number (1...63)
46; BH: Head number (0...15)
47; CX: Cylinder number (0...16382)
48; Corrupts registers:
49; AX, DX
50;--------------------------------------------------------------------
51ALIGN JUMP_ALIGN
52ConvertLCHStoPCHS:
53 ; LHead / PHeadCount and LHead % PHeadCount
54 eMOVZX ax, bh ; Copy L-CHS Head number to AX
55 div BYTE [di+DPT.bPchsHeads]; AL = LHead / PHeadCount, AH = LHead % PHeadCount
56 mov bh, ah ; Copy P-CHS Head number to BH
57 xor ah, ah ; AX = LHead / PHeadCount
58
59 ; (LCylinder << n) + (LHead / PHeadCount)
60 mov dx, cx ; Copy L-CHS Cylinder number to DX
61 mov cl, [di+DPT.bFlagsLow] ; Load shift count
62 and cl, MASKL_DPT_CHS_SHIFT_COUNT
63 shl dx, cl ; DX = LCylinder << n
64 add ax, dx ; AX = P-CHS Cylinder number
65 xchg cx, ax ; Move P-CHS Cylinder number to CX
66DoNotConvertLCHS:
67 ret
68
69;--------------------------------------------------------------------
70; Address_OldInt13hAddressToIdeAddress
71; Parameters:
72; CH: Cylinder number, bits 7...0
73; CL: Bits 7...6: Cylinder number bits 9 and 8
74; Bits 5...0: Starting sector number (1...63)
75; DH: Starting head number (0...255)
76; DS:DI: Ptr to DPT
77; Returns:
78; BL: LBA Low Register / Sector Number Register (LBA 7...0)
79; CL: LBA Mid Register / Low Cylinder Register (LBA 15...8)
80; CH: LBA High Register / High Cylinder Register (LBA 23...16)
81; BH: Drive and Head Register (LBA 27...24)
82; Corrupts registers:
83; AX, DX
84;--------------------------------------------------------------------
85ALIGN JUMP_ALIGN
86Address_OldInt13hAddressToIdeAddress:
87 call Address_ExtractLCHSparametersFromOldInt13hAddress
88
89 AccessDPT_GetUnshiftedAddressModeToALZF
90
91;;; 0: ADDR_DPT_LCHS
92 jz DoNotConvertLCHS
93
94;;; 1: ADDR_DPT_PCHS
95 ;
96 ; Since we are only checking for zero, we can do our math in the high order bits,
97 ; in this case effectively subtracting 1 from the address mode.
98 ;
99 sub al,(1<<ADDRESSING_MODE_FIELD_POSITION)
100 jz ConvertLCHStoPCHS
101
102;;; 2: ADDR_DPT_LBA28 and 3: ADDR_DPT_LBA48
103 ; Fall through to ConvertLCHStoLBARegisterValues
104
105;---------------------------------------------------------------------
106; Converts LCHS parameters to 28-bit LBA address.
107; Only 24-bits are used since LHCS to LBA28 conversion has 8.4GB limit.
108; LBA = ((cylToSeek*headsPerCyl+headToSeek)*sectPerTrack)+sectToSeek-1
109;
110; Returned address is in same registers that
111; Address_DoNotConvertLCHS and Address_ConvertLCHStoPCHS returns.
112;
113; ConvertLCHStoLBARegisterValues:
114; Parameters:
115; BL: Sector number (1...63)
116; BH: Head number (0...255)
117; CX: Cylinder number (0...1023)
118; DS:DI: Ptr to Disk Parameter Table
119; Returns:
120; BL: LBA Low Register / Sector Number Register (LBA 7...0)
121; CL: LBA Mid Register / Low Cylinder Register (LBA 15...8)
122; CH: LBA High Register / High Cylinder Register (LBA 23...16)
123; BH: Drive and Head Register (LBA 27...24)
124; Corrupts registers:
125; AX, DX
126;--------------------------------------------------------------------
127ALIGN JUMP_ALIGN
128ConvertLCHStoLBARegisterValues:
129 ; cylToSeek*headsPerCyl (18-bit result)
130 mov ax, cx ; Copy Cylinder number to AX
131 ; We could save a byte here by using CWD instead of the XOR DH, DH in eMOVZX
132 ; but I'm not sure how that would affect speed.
133
134 eMOVZX dx, BYTE [di+DPT.bLbaHeads]
135 mul dx ; DX:AX = cylToSeek*headsPerCyl
136
137 ; +=headToSeek (18-bit result)
138 add al, bh ; Add Head number to DX:AX
139 adc ah, dh ; DH = Zero after previous multiplication
140 adc dl, dh
141
142 ; *=sectPerTrack (18-bit by 6-bit multiplication with 24-bit result)
143 mov cx, LBA_ASSIST_SPT ; Load Sectors per Track
144 xchg ax, dx ; Hiword to AX, loword to DX
145 mul cl ; AX = hiword * Sectors per Track
146 mov bh, al ; Backup hiword * Sectors per Track
147 xchg ax, dx ; Loword back to AX
148 mul cx ; DX:AX = loword * Sectors per Track
149 add dl, bh ; DX:AX = (cylToSeek*headsPerCyl+headToSeek)*sectPerTrack
150
151 ; +=sectToSeek-1 (24-bit result)
152 xor bh, bh ; Sector number now in BX
153 dec bx ; sectToSeek-=1
154 add ax, bx ; Add to loword
155 adc dl, bh ; Add possible carry to byte2, BH=zero
156
157 ; Copy DX:AX to proper return registers
158 xchg bx, ax ; BL = Sector Number Register (LBA 7...0)
159 mov cl, bh ; Low Cylinder Register (LBA 15...8)
160 mov ch, dl ; High Cylinder Register (LBA 23...16)
161 mov bh, dh ; Drive and Head Register (LBA 27...24)
162 ret
Note: See TracBrowser for help on using the repository browser.