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

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

Added logic to skip scanning COM ports if a COM port was already found during the normal detection process, to avoid finding the same serial drive twice and preseting the OS with two drives which in reality point to the same physical file on the server. Also added logic to skip scanning for the slave serial drive if the master was not found. And various small optimizations.

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        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    eMOVZX  dx, BYTE [di+DPT.bHeads]
132    mul     dx                      ; DX:AX = cylToSeek*headsPerCyl
133
134    ; +=headToSeek (18-bit result)
135    add     al, bh                  ; Add Head number to DX:AX
136    adc     ah, dh                  ; DH = Zero after previous multiplication
137    adc     dl, dh
138
139    ; *=sectPerTrack (18-bit by 6-bit multiplication with 24-bit result)
140    mov     cx, LBA_ASSIST_SPT      ; Load Sectors per Track
141    xchg    ax, dx                  ; Hiword to AX, loword to DX
142    mul     cl                      ; AX = hiword * Sectors per Track
143    mov     bh, al                  ; Backup hiword * Sectors per Track
144    xchg    ax, dx                  ; Loword back to AX
145    mul     cx                      ; DX:AX = loword * Sectors per Track
146    add     dl, bh                  ; DX:AX = (cylToSeek*headsPerCyl+headToSeek)*sectPerTrack
147
148    ; +=sectToSeek-1 (24-bit result)
149    xor     bh, bh                  ; Sector number now in BX
150    dec     bx                      ; sectToSeek-=1
151    add     ax, bx                  ; Add to loword
152    adc     dl, bh                  ; Add possible carry to byte2, BH=zero
153
154    ; Copy DX:AX to proper return registers
155    xchg    bx, ax                  ; BL = Sector Number Register (LBA 7...0)
156    mov     cl, bh                  ; Low Cylinder Register (LBA 15...8)
157    mov     ch, dl                  ; High Cylinder Register (LBA 23...16)
158    mov     bh, dh                  ; Drive and Head Register (LBA 27...24)
159    ret
Note: See TracBrowser for help on using the repository browser.