source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HAddress.asm @ 150

Last change on this file since 150 was 150, checked in by aitotat, 13 years ago

Changes to XTIDE Universal BIOS:

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