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 Krister Nordvall, 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.