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

Last change on this file since 191 was 191, checked in by gregli@…, 12 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.