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

Last change on this file since 230 was 230, checked in by krille_n_@…, 11 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.