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

Last change on this file since 193 was 193, checked in by gregli@…, 12 years ago

Space optimizations in AccessDPT.asm, transfer one routine to a macro (retaining some encapsulation), and transfer the unique part of another routine to the one place it was being called (which also makes what it was doing more transparent).

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