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

Last change on this file since 192 was 191, checked in by gregli@…, 13 years ago

Space optimization in Address.asm, includes bug fix for BootMenuPrintCfg.asm (was using a word index instead of a byte index).

File size: 5.4 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.bHeads] ; 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 call AccessDPT_GetAddressingModeToAXZF
89 jz DoNotConvertLCHS ; 0, ADDR_DPT_LCHS
90 dec ax
91 jz ConvertLCHStoPCHS ; 1, ADDR_DPT_PCHS
92;; Fall-through ; 2, ADDR_DPT_LBA28 and 3, ADDR_DPT_LBA48
93
94;---------------------------------------------------------------------
95; Converts LCHS parameters to 28-bit LBA address.
96; Only 24-bits are used since LHCS to LBA28 conversion has 8.4GB limit.
97; LBA = ((cylToSeek*headsPerCyl+headToSeek)*sectPerTrack)+sectToSeek-1
98;
99; Returned address is in same registers that
100; Address_DoNotConvertLCHS and Address_ConvertLCHStoPCHS returns.
101;
102; ConvertLCHStoLBARegisterValues:
103; Parameters:
104; BL: Sector number (1...63)
105; BH: Head number (0...255)
106; CX: Cylinder number (0...1023)
107; DS:DI: Ptr to Disk Parameter Table
108; Returns:
109; BL: LBA Low Register / Sector Number Register (LBA 7...0)
110; CL: LBA Mid Register / Low Cylinder Register (LBA 15...8)
111; CH: LBA High Register / High Cylinder Register (LBA 23...16)
112; BH: Drive and Head Register (LBA 27...24)
113; Corrupts registers:
114; AX, DX
115;--------------------------------------------------------------------
116ALIGN JUMP_ALIGN
117ConvertLCHStoLBARegisterValues:
118 ; cylToSeek*headsPerCyl (18-bit result)
119 mov ax, cx ; Copy Cylinder number to AX
120 eMOVZX dx, BYTE [di+DPT.bHeads]
121 mul dx ; DX:AX = cylToSeek*headsPerCyl
122
123 ; +=headToSeek (18-bit result)
124 add al, bh ; Add Head number to DX:AX
125 adc ah, dh ; DH = Zero after previous multiplication
126 adc dl, dh
127
128 ; *=sectPerTrack (18-bit by 6-bit multiplication with 24-bit result)
129 mov cx, LBA_ASSIST_SPT ; Load Sectors per Track
130 xchg ax, dx ; Hiword to AX, loword to DX
131 mul cl ; AX = hiword * Sectors per Track
132 mov bh, al ; Backup hiword * Sectors per Track
133 xchg ax, dx ; Loword back to AX
134 mul cx ; DX:AX = loword * Sectors per Track
135 add dl, bh ; DX:AX = (cylToSeek*headsPerCyl+headToSeek)*sectPerTrack
136
137 ; +=sectToSeek-1 (24-bit result)
138 xor bh, bh ; Sector number now in BX
139 dec bx ; sectToSeek-=1
140 add ax, bx ; Add to loword
141 adc dl, bh ; Add possible carry to byte2, BH=zero
142
143 ; Copy DX:AX to proper return registers
144 xchg bx, ax ; BL = Sector Number Register (LBA 7...0)
145 mov cl, bh ; Low Cylinder Register (LBA 15...8)
146 mov ch, dl ; High Cylinder Register (LBA 23...16)
147 mov bh, dh ; Drive and Head Register (LBA 27...24)
148 ret
Note: See TracBrowser for help on using the repository browser.