source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm@ 609

Last change on this file since 609 was 606, checked in by Krister Nordvall, 4 years ago

Changes:

  • RESERVE_DIAGNOSTIC_CYLINDER has been completely removed as it wasted hard drive space, caused a compatibility problem with 32-bit disk access drivers under Windows 3.x and most importantly, it was in fact not needed since the same thing can be accomplished using the "User specified CHS" feature in XTIDECFG which is better because that applies only to that specific drive instead of all drives under XUB control.
  • In BIOS builds containing MODULE_EBIOS (i.e. all official builds except the Tiny build), drives with a cylinder count less than or equal to 1024 had CHS translation applied to them unnecessarily if CHS translation method was set to Auto (which is the default). This bug has been present for a long time and, as a side effect, made RESERVE_DIAGNOSTIC_CYLINDER useless since the idea behind that was to provide compatibility with other old BIOSes using NORMAL addressing mode. WARNING! With this bug now being fixed, upgrading to this revision of the BIOS will require repartitioning and reformatting any drives affected by this (BIOSDRVS.COM can be helpful in determining which drives are affected).
File size: 9.7 KB
Line 
1; Project name : XTIDE Universal BIOS
2; Description : Functions for creating Disk Parameter Table.
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; Creates new Disk Parameter Table for detected hard disk.
25; Drive is then fully accessible using any BIOS function.
26;
27; CreateDPT_FromAtaInformation
28; Parameters:
29; BH: Drive Select byte for Drive and Head Register
30; DX: Autodetected port (for devices that support autodetection)
31; ES:SI: Ptr to 512-byte ATA information read from the drive
32; CS:BP: Ptr to IDEVARS for the controller
33; DS: RAMVARS segment
34; ES: BDA Segment
35; Returns:
36; DS:DI: Ptr to Disk Parameter Table
37; CF: Cleared
38; Corrupts registers:
39; AX, BX, CX, DX
40;--------------------------------------------------------------------
41CreateDPT_FromAtaInformation:
42 call FindDPT_ForNewDriveToDSDI
43 ; Fall to .InitializeDPT
44
45;--------------------------------------------------------------------
46; .InitializeDPT
47; Parameters:
48; BH: Drive Select byte for Drive and Head Register
49; DX: Autodetected port (for devices that support autodetection)
50; DS:DI: Ptr to Disk Parameter Table
51; CS:BP: Ptr to IDEVARS for the controller
52; Returns:
53; Nothing
54; Corrupts registers:
55; AX
56;--------------------------------------------------------------------
57.InitializeDPT:
58 call CreateDPT_StoreIdevarsOffsetAndBasePortFromCSBPtoDPTinDSDI
59 ; Fall to .StoreDriveSelectAndDriveControlByte
60
61;--------------------------------------------------------------------
62; .StoreDriveSelectAndDriveControlByte
63; Parameters:
64; BH: Drive Select byte for Drive and Head Register
65; DS:DI: Ptr to Disk Parameter Table
66; ES:SI: Ptr to 512-byte ATA information read from the drive
67; CS:BP: Ptr to IDEVARS for the controller
68; Returns:
69; Nothing
70; Corrupts registers:
71; AX
72;--------------------------------------------------------------------
73.StoreDriveSelectAndDriveControlByte:
74 mov al, bh
75 and ax, BYTE FLG_DRVNHEAD_DRV ; AL now has Master/Slave bit
76%ifdef MODULE_IRQ
77 cmp [cs:bp+IDEVARS.bIRQ], ah ; Interrupts enabled?
78 jz SHORT .StoreFlags ; If not, do not set interrupt flag
79 or al, FLGL_DPT_ENABLE_IRQ
80.StoreFlags:
81%endif
82 mov [di+DPT.wFlags], ax
83 ; Fall to .StoreCHSparametersAndAddressingMode
84
85;--------------------------------------------------------------------
86; .StoreCHSparametersAndAddressingMode
87; Parameters:
88; DS:DI: Ptr to Disk Parameter Table
89; ES:SI: Ptr to 512-byte ATA information read from the drive
90; CS:BP: Ptr to IDEVARS for the controller
91; Returns:
92; Nothing
93; Corrupts registers:
94; AX, BX, CX, DX
95;--------------------------------------------------------------------
96.StoreCHSparametersAndAddressingMode:
97 ; Apply any user limited values to ATA ID
98 call AtaID_ModifyESSIforUserDefinedLimitsAndReturnTranslateModeInDX
99
100 ; Translate P-CHS to L-CHS
101 call AtaGeometry_GetLCHStoAXBLBHfromAtaInfoInESSIwithTranslateModeInDX
102 mov [di+DPT.wLchsCylinders], ax
103 mov [di+DPT.wLchsHeadsAndSectors], bx
104 mov al, dl
105 eSHL_IM al, TRANSLATEMODE_FIELD_POSITION
106 or cl, al
107
108 ; Store P-CHS and flags
109 call AtaGeometry_GetPCHStoAXBLBHfromAtaInfoInESSI
110 dec dx ; Set ZF if TRANSLATEMODE_LARGE, SF if TRANSLATEMODE_NORMAL
111 jle SHORT .JumpOverSetBitForAssistedLBA
112
113 ; Set LBA bit for Assisted LBA
114 or cl, FLGL_DPT_LBA
115.JumpOverSetBitForAssistedLBA:
116 jnz SHORT .NothingToChange
117
118 ; We cannot have 16 P-Heads heads in Revised ECHS mode (8193 or more cylinders)
119 ; but 16 heads are allowed when there are 8192 or less cylinders (ECHS).
120 ; Both of these are LARGE modes so do not confuse with NORMAL mode.
121 call AtaGeometry_IsDriveSmallEnoughForECHS
122 adc bx, -1 ; Adjust 16 P-Heads to 15 if needed
123
124.NothingToChange:
125 or [di+DPT.bFlagsLow], cl ; Shift count and addressing mode
126 mov [di+DPT.wPchsHeadsAndSectors], bx
127%ifdef MODULE_COMPATIBLE_TABLES OR MODULE_EBIOS
128 ; Store P-Cylinders here for Compatible DPTs when FLGL_DPT_LBA is not set
129 ; or when drive has over 15,482,880 sectors
130 mov [di+DPT.wPchsCylinders], ax
131%endif
132
133%ifdef MODULE_EBIOS
134 test cl, FLGL_DPT_LBA
135 jz SHORT .NoLbaSoNoEBIOS
136
137 ; Store P-Cylinders but only if we have 15,482,880 or less sectors since
138 ; we only need P-Cylinders so we can return it from AH=48h
139 call AtaGeometry_GetLbaSectorCountToBXDXAXfromAtaInfoInESSI
140 sub ax, (MAX_SECTOR_COUNT_TO_RETURN_PCHS+1) & 0FFFFh
141 sbb dx, (MAX_SECTOR_COUNT_TO_RETURN_PCHS+1) >> 16
142 sbb bx, BYTE 0
143 jnc SHORT .StoreNumberOfLbaSectors
144
145 ; Since we might have altered the default P-CHS parameters to be
146 ; presented to the drive (AH=09h), we need to calculate new
147 ; P-Cylinders. It could be read from the ATA ID after
148 ; COMMAND_INITIALIZE_DEVICE_PARAMETERS but that is too much trouble.
149 ; P-Cyls = MIN(16383*16*63, LBA sector count) / (P-Heads * P-Sectors per track)
150 call AtaGeometry_GetLbaSectorCountToBXDXAXfromAtaInfoInESSI
151 xchg cx, ax ; Sector count to DX:CX
152 mov al, [di+DPT.bPchsHeads]
153 mul BYTE [di+DPT.bPchsSectorsPerTrack]
154 xchg cx, ax
155 div cx ; AX = new P-Cylinders
156
157 ; We could remove wPchsCylinders from DPT if we calculate it on AH=48h
158 ; (and for compatible DPTs) but that would require extra code so we save ROM space instead.
159 mov [di+DPT.wPchsCylinders], ax
160
161 ; Store CHS sector count as total sector count. We must not use
162 ; LBA sector count if it is 15,482,880 or less.
163 mul cx
164 xor bx, bx
165 jmp SHORT .StoreTotalSectorsFromBXDXAX
166
167
168;--------------------------------------------------------------------
169; .StoreNumberOfLbaSectors
170; Parameters:
171; DS:DI: Ptr to Disk Parameter Table
172; ES:SI: Ptr to 512-byte ATA information read from the drive
173; CS:BP: Ptr to IDEVARS for the controller
174; Returns:
175; Nothing
176; Corrupts registers:
177; AX, BX, CX, DX
178;--------------------------------------------------------------------
179.StoreNumberOfLbaSectors:
180 ; Store LBA 28/48 total sector count
181 call AtaGeometry_GetLbaSectorCountToBXDXAXfromAtaInfoInESSI
182 or [di+DPT.bFlagsLow], cl ; LBA48 flag
183.StoreTotalSectorsFromBXDXAX:
184 mov [di+DPT.twLbaSectors], ax
185 mov [di+DPT.twLbaSectors+2], dx
186 mov [di+DPT.twLbaSectors+4], bx
187.NoLbaSoNoEBIOS:
188%endif ; MODULE_EBIOS
189 ; Fall to .StoreDeviceSpecificParameters
190
191;--------------------------------------------------------------------
192; .StoreDeviceSpecificParameters
193; Parameters:
194; DS:DI: Ptr to Disk Parameter Table
195; ES:SI: Ptr to 512-byte ATA information read from the drive
196; CS:BP: Ptr to IDEVARS for the controller
197; Returns:
198; Nothing
199; Corrupts registers:
200; AX, BX, CX, DX
201;--------------------------------------------------------------------
202.StoreDeviceSpecificParameters:
203 call Device_FinalizeDPT
204
205;----------------------------------------------------------------------
206; Update drive counts (hard and floppy)
207;----------------------------------------------------------------------
208%ifdef MODULE_SERIAL
209; Device_FinalizeDPT returns with CF set only when a floppy was found which can't happen without MODULE_SERIAL
210%ifdef MODULE_SERIAL_FLOPPY
211;
212; These two instructions serve two purposes:
213; 1. If the drive is a floppy drive (CF set), then we effectively increment the counter.
214; 2. If this is a hard disk, and there have been any floppy drives previously added, then the hard disk is
215; effectively discarded. This is more of a safety check then code that should ever normally be hit (see below).
216; Since the floppy DPT's come after the hard disk DPT's, without expensive (code size) code to relocate a DPT,
217; this was necessary. Now, this situation shouldn't happen in normal operation, for a couple of reasons:
218; A. xtidecfg always puts configured serial ports at the end of the IDEVARS list
219; B. the auto serial code is always executed last
220; C. the serial server always returns floppy drives last
221;
222 adc BYTE [RAMVARS.xlateVars+XLATEVARS.bFlopCreateCnt], 0
223 jnz SHORT .AllDone
224%else ; ~MODULE_SERIAL_FLOPPY
225;
226; Even without floppy support enabled, we shouldn't try to mount a floppy image as a hard disk, which
227; could lead to unpredictable results since no MBR will be present, etc. The server doesn't know that
228; floppies are supported, so it is important to still fail here if a floppy is seen during the drive scan.
229;
230 jc SHORT .AllDone
231%endif ; MODULE_SERIAL_FLOPPY
232%endif ; MODULE_SERIAL
233
234 inc BYTE [RAMVARS.bDrvCnt] ; Increment drive count to RAMVARS
235
236%ifdef MODULE_SERIAL
237.AllDone:
238 clc
239%endif
240
241 ret
242
243
244;--------------------------------------------------------------------
245; CreateDPT_StoreIdevarsOffsetAndBasePortFromCSBPtoDPTinDSDI
246; Parameters:
247; DX: Autodetected port (for devices that support autodetection)
248; DS:DI: Ptr to Disk Parameter Table
249; CS:BP: Ptr to IDEVARS for the controller
250; Returns:
251; Nothing
252; Corrupts registers:
253; AX
254;--------------------------------------------------------------------
255CreateDPT_StoreIdevarsOffsetAndBasePortFromCSBPtoDPTinDSDI:
256 mov [di+DPT.bIdevarsOffset], bp ; IDEVARS must start in first 256 bytes of ROM
257 mov ax, [cs:bp+IDEVARS.wBasePort]
258 mov [di+DPT.wBasePort], ax
259 ret
Note: See TracBrowser for help on using the repository browser.