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

Last change on this file since 592 was 592, checked in by krille_n_, 6 years ago

Changes:

  • The problem with NASM in the previous revision (r591) has been fixed.
  • The colors used by the boot menu and hotkey bar can now be customized by selecting one of a number of pre-defined color themes. Suggestions for additional themes are more than welcome!
  • Large builds are now 10 KB. Small builds are still 8 KB with the exception of the Tiny build which is now 4 KB. In other words, builds are now as small as possible to make it easier to combine them with other BIOSes.
  • Added code to the library to improve drive error handling. XTIDECFG can now handle "Drive Not Ready" errors.
  • Fixed a couple of potential bugs in AtaID.asm (AtaID_GetMaxPioModeToAXandMinCycleTimeToCX); 1) ATA1.bPioMode was treated as a WORD variable. 2) ATA2.bPIOSupp was assumed to be non-zero which would result in PIO mode 3 being returned if the assumption was wrong.
  • Made the same changes in the equivalent function used by BIOSDRVS (DisplayPioModeInformationUsingAtaInfoFromDSBX in AtaInfo.asm).
  • Fixed a bug from r587 in PDC20x30.asm in PDC20x30_GetMaxPioModeToALandMinPioCycleTimeToBX.
  • Fixed a bug from r523 in XTIDECFG where Auto Configure would only set the IRQ on one IDE interface on AT-builds.
  • XTIDECFG will now restore the default settings for the "Serial port virtual device" when reselecting it in the list of device types. This makes it behave consistently for all device types.
  • The eAAM macro is now used regardless if USE_UNDOC_INTEL is defined or not because it is apparently supported on all processors including the NEC V20/V30 CPUs.
  • Renamed the EXCLUDE_FROM_XTIDE_UNIVERSAL_BIOS define to EXCLUDE_FROM_XUB.
  • Added a define to exclude unused library code from BIOSDRVS (EXCLUDE_FROM_BIOSDRVS). This makes it a lot smaller than in previous revisions.
  • All unnecessary CLD-instructions are now under a new define 'CLD_NEEDED' which is only enabled for the BIOS. It is disabled for XTIDECFG and BIOSDRVS but can be enabled if needed by adding this define to the respective makefile. This change was made because these unnecessary instructions are wasteful and should never be needed. In fact, they only serve to hide bugs (in other peoples code) which I strongly believe should be avoided. I recommend people making their own BIOSes from source to not use this define as it's extremely unlikely to be needed.
  • Updated the copyright info in SerDrive and changed an URL to point to the new site.
  • Updated the copyright info and version number in BIOSDRVS.
  • Updated the copyright info in XTIDECFG.
  • Optimizations in general.
File size: 6.8 KB
Line 
1; Project name  :   XTIDE Universal BIOS
2; Description   :   Functions for address translations.
3
4;
5; XTIDE Universal BIOS and Associated Tools
6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
7;
8; This program is free software; you can redistribute it and/or modify
9; it under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2 of the License, or
11; (at your option) any later version.
12;
13; This program is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16; GNU General Public License for more details.
17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18;
19
20; Section containing code
21SECTION .text
22
23;---------------------------------------------------------------------
24; Address_ExtractLCHSparametersFromOldInt13hAddress
25;   Parameters:
26;       CH:     Cylinder number, bits 7...0
27;       CL:     Bits 7...6: Cylinder number bits 9 and 8
28;               Bits 5...0: Sector number
29;       DH:     Head number
30;   Returns:
31;       BL:     Sector number (1...63)
32;       BH:     Head number (0...255)
33;       CX:     Cylinder number (0...1023)
34;   Corrupts registers:
35;       Nothing
36;--------------------------------------------------------------------
37ALIGN JUMP_ALIGN
38Address_ExtractLCHSparametersFromOldInt13hAddress:
39    mov     bl, 3Fh             ; Load sector number mask
40    and     bl, cl              ; Sector number now in BL
41    sub     cl, bl              ; Remove from cylinder number high
42    eROL_IM cl, 2               ; High bits to beginning
43    mov     bh, dh              ; Copy Head number
44    xchg    cl, ch              ; Cylinder number now in CX
45    ret
46
47
48;---------------------------------------------------------------------
49; Converts LARGE addressing mode LCHS parameters to IDE P-CHS parameters.
50; PCylinder = (LCylinder << n) + (LHead / PHeadCount)
51; PHead     = LHead % PHeadCount
52; PSector   = LSector
53;
54; ConvertLargeModeLCHStoPCHS:
55;   Parameters:
56;       BL:     Sector number (1...63)
57;       BH:     Head number (0...239)
58;       CX:     Cylinder number (0...1023)
59;       DS:DI:  Ptr to Disk Parameter Table
60;   Returns:
61;       BL:     Sector number (1...63)
62;       BH:     Head number (0...15)
63;       CX:     Cylinder number (0...16382)
64;   Corrupts registers:
65;       AX, DX
66;--------------------------------------------------------------------
67ALIGN JUMP_ALIGN
68ConvertLargeModeLCHStoPCHS:
69    ; LHead / PHeadCount and LHead % PHeadCount
70    eMOVZX  ax, bh                  ; Copy L-CHS Head number to AX
71    div     BYTE [di+DPT.bPchsHeads]; AL = LHead / PHeadCount, AH = LHead % PHeadCount
72    mov     bh, ah                  ; Copy P-CHS Head number to BH
73    xor     ah, ah                  ; AX = LHead / PHeadCount
74
75    ; (LCylinder << n) + (LHead / PHeadCount)
76    mov     dx, cx                  ; Copy L-CHS Cylinder number to DX
77    mov     cl, MASKL_DPT_CHS_SHIFT_COUNT   ; Load shift count mask
78    and     cl, [di+DPT.bFlagsLow]  ; Shift count now in CL
79    shl     dx, cl                  ; DX = LCylinder << n
80    add     ax, dx                  ; AX = P-CHS Cylinder number
81    xchg    cx, ax                  ; Move P-CHS Cylinder number to CX
82DoNotConvertLCHS:
83    ret
84
85; *FIXME* The above function description doesn't match the code.
86; If CX has a maximum value of 1023 on entry then there is no way CX can be 16382 on return.
87; 1023 SHL 3 (MASKL_DPT_CHS_SHIFT_COUNT) is 8184. With the addition of AX (at most 255?)
88; the result is 8439.
89
90;--------------------------------------------------------------------
91; Address_OldInt13hAddressToIdeAddress
92;   Parameters:
93;       CH:     Cylinder number, bits 7...0
94;       CL:     Bits 7...6: Cylinder number bits 9 and 8
95;               Bits 5...0: Starting sector number (1...63)
96;       DH:     Starting head number (0...255)
97;       DS:DI:  Ptr to DPT
98;   Returns:
99;       BL:     LBA Low Register / Sector Number Register (LBA 7...0)
100;       CL:     LBA Mid Register / Low Cylinder Register (LBA 15...8)
101;       CH:     LBA High Register / High Cylinder Register (LBA 23...16)
102;       BH:     Drive and Head Register (LBA 27...24)
103;   Corrupts registers:
104;       AX, DX
105;--------------------------------------------------------------------
106ALIGN JUMP_ALIGN
107Address_OldInt13hAddressToIdeAddress:
108    call    Address_ExtractLCHSparametersFromOldInt13hAddress
109    mov     al, [di+DPT.bFlagsLow]
110    and     al, MASKL_DPT_TRANSLATEMODE
111
112;;; 0: TRANSLATEMODE_NORMAL
113    jz      SHORT DoNotConvertLCHS
114
115;;; 1: TRANSLATEMODE_LARGE
116    test    al, FLGL_DPT_ASSISTED_LBA
117    jz      SHORT ConvertLargeModeLCHStoPCHS
118
119;;; 2: TRANSLATEMODE_ASSISTED_LBA
120    ; Fall to ConvertAssistedLBAModeLCHStoLBARegisterValues
121
122
123;---------------------------------------------------------------------
124; Converts LCHS parameters to 28-bit LBA address.
125; Only 24-bits are used since LHCS to LBA28 conversion has 8.4GB limit.
126; LBA = ((cylToSeek*headsPerCyl+headToSeek)*sectPerTrack)+sectToSeek-1
127; headsPerCyl and sectPerTrack are the current translation values (L-CHS).
128;
129; Returned address is in same registers that
130; DoNotConvertLCHS and ConvertLargeModeLCHStoPCHS returns.
131;
132; ConvertAssistedLBAModeLCHStoLBARegisterValues:
133;   Parameters:
134;       BL:     Sector number (1...63)
135;       BH:     Head number (0...254)
136;       CX:     Cylinder number (0...1023)
137;       DS:DI:  Ptr to Disk Parameter Table
138;   Returns:
139;       BL:     LBA Low Register / Sector Number Register (LBA 7...0)
140;       CL:     LBA Mid Register / Low Cylinder Register (LBA 15...8)
141;       CH:     LBA High Register / High Cylinder Register (LBA 23...16)
142;       BH:     Drive and Head Register (LBA 27...24)
143;   Corrupts registers:
144;       AX, DX
145;--------------------------------------------------------------------
146ConvertAssistedLBAModeLCHStoLBARegisterValues:
147    ; cylToSeek*headsPerCyl (18-bit result)
148    ; Max = 1023 * 255 = 260,865 = 3FB01h
149    mov     ax, LBA_ASSIST_SPT      ; Load Sectors per Track
150    xchg    cx, ax                  ; Cylinder number to AX, Sectors per Track to CX
151%ifdef USE_386
152    movzx   dx, [di+DPT.bLchsHeads]
153%else
154    cwd
155    mov     dl, [di+DPT.bLchsHeads]
156%endif
157    mul     dx                      ; DX:AX = cylToSeek*headsPerCyl
158
159    ; +=headToSeek (18-bit result)
160    ; Max = 260,865 + 254 = 261,119 = 3FBFFh
161    add     al, bh                  ; Add Head number to DX:AX
162    adc     ah, dh                  ; DH = Zero after previous multiplication
163    adc     dl, dh
164
165    ; *=sectPerTrack (18-bit by 6-bit multiplication with 24-bit result)
166    ; Max = 261,119 * 63 = 16,450,497 = FB03C1h
167    xchg    ax, dx                  ; Hiword to AX, loword to DX
168    mul     cl                      ; AX = hiword * Sectors per Track
169    mov     bh, al                  ; Backup hiword * Sectors per Track
170    xchg    ax, dx                  ; Loword back to AX
171    mul     cx                      ; DX:AX = loword * Sectors per Track
172    add     dl, bh                  ; DX:AX = (cylToSeek*headsPerCyl+headToSeek)*sectPerTrack
173
174    ; +=sectToSeek-1 (24-bit result)
175    ; Max = 16,450,497 + 63 - 1 = 16,450,559 = FB03FFh
176    mov     bh, ch                  ; Sector number now in BX, CH=zero
177    dec     bx                      ; sectToSeek-=1
178    add     bx, ax                  ; Add loword to BX (BL = Sector Number Register (LBA 7...0))
179    adc     ch, dl                  ; Add possible carry to byte2 (CH = High Cylinder Register (LBA 23...16))
180    mov     cl, bh                  ; CL = Low Cylinder Register (LBA 15...8)
181    mov     bh, dh                  ; BH = Drive and Head Register (LBA 27...24)
182    ret
Note: See TracBrowser for help on using the repository browser.