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

Last change on this file since 619 was 606, checked in by Krister Nordvall, 3 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
RevLine 
[99]1; Project name : XTIDE Universal BIOS
[3]2; Description : Functions for creating Disk Parameter Table.
3
[376]4;
[445]5; XTIDE Universal BIOS and Associated Tools
[526]6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
[376]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.
[445]12;
[376]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
[445]16; GNU General Public License for more details.
[376]17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
[445]18;
[376]19
[3]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
[473]30; DX: Autodetected port (for devices that support autodetection)
[3]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:
[558]36; DS:DI: Ptr to Disk Parameter Table
37; CF: Cleared
[3]38; Corrupts registers:
[542]39; AX, BX, CX, DX
[3]40;--------------------------------------------------------------------
41CreateDPT_FromAtaInformation:
[150]42 call FindDPT_ForNewDriveToDSDI
[99]43 ; Fall to .InitializeDPT
[3]44
45;--------------------------------------------------------------------
[99]46; .InitializeDPT
[3]47; Parameters:
48; BH: Drive Select byte for Drive and Head Register
[473]49; DX: Autodetected port (for devices that support autodetection)
[3]50; DS:DI: Ptr to Disk Parameter Table
51; CS:BP: Ptr to IDEVARS for the controller
52; Returns:
[150]53; Nothing
[3]54; Corrupts registers:
[150]55; AX
[3]56;--------------------------------------------------------------------
[99]57.InitializeDPT:
[473]58 call CreateDPT_StoreIdevarsOffsetAndBasePortFromCSBPtoDPTinDSDI
[150]59 ; Fall to .StoreDriveSelectAndDriveControlByte
[3]60
61;--------------------------------------------------------------------
[150]62; .StoreDriveSelectAndDriveControlByte
[3]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:
[99]69; Nothing
[3]70; Corrupts registers:
71; AX
72;--------------------------------------------------------------------
[150]73.StoreDriveSelectAndDriveControlByte:
74 mov al, bh
75 and ax, BYTE FLG_DRVNHEAD_DRV ; AL now has Master/Slave bit
[411]76%ifdef MODULE_IRQ
[150]77 cmp [cs:bp+IDEVARS.bIRQ], ah ; Interrupts enabled?
78 jz SHORT .StoreFlags ; If not, do not set interrupt flag
[158]79 or al, FLGL_DPT_ENABLE_IRQ
[150]80.StoreFlags:
[411]81%endif
[150]82 mov [di+DPT.wFlags], ax
[421]83 ; Fall to .StoreCHSparametersAndAddressingMode
[3]84
85;--------------------------------------------------------------------
[421]86; .StoreCHSparametersAndAddressingMode
[3]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:
[227]92; Nothing
[3]93; Corrupts registers:
[227]94; AX, BX, CX, DX
[3]95;--------------------------------------------------------------------
[421]96.StoreCHSparametersAndAddressingMode:
[542]97 ; Apply any user limited values to ATA ID
98 call AtaID_ModifyESSIforUserDefinedLimitsAndReturnTranslateModeInDX
[173]99
[422]100 ; Translate P-CHS to L-CHS
[549]101 call AtaGeometry_GetLCHStoAXBLBHfromAtaInfoInESSIwithTranslateModeInDX
[421]102 mov [di+DPT.wLchsCylinders], ax
103 mov [di+DPT.wLchsHeadsAndSectors], bx
[542]104 mov al, dl
105 eSHL_IM al, TRANSLATEMODE_FIELD_POSITION
106 or cl, al
[421]107
[542]108 ; Store P-CHS and flags
[421]109 call AtaGeometry_GetPCHStoAXBLBHfromAtaInfoInESSI
[606]110 dec dx ; Set ZF if TRANSLATEMODE_LARGE, SF if TRANSLATEMODE_NORMAL
[567]111 jle SHORT .JumpOverSetBitForAssistedLBA
[542]112
[549]113 ; Set LBA bit for Assisted LBA
114 or cl, FLGL_DPT_LBA
[567]115.JumpOverSetBitForAssistedLBA:
116 jnz SHORT .NothingToChange
[549]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
[568]122 adc bx, -1 ; Adjust 16 P-Heads to 15 if needed
[549]123
[542]124.NothingToChange:
125 or [di+DPT.bFlagsLow], cl ; Shift count and addressing mode
126 mov [di+DPT.wPchsHeadsAndSectors], bx
[550]127%ifdef MODULE_COMPATIBLE_TABLES OR MODULE_EBIOS
[544]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
[550]131%endif
132
133%ifdef MODULE_EBIOS
[542]134 test cl, FLGL_DPT_LBA
135 jz SHORT .NoLbaSoNoEBIOS
[533]136
[542]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
[544]140 sub ax, (MAX_SECTOR_COUNT_TO_RETURN_PCHS+1) & 0FFFFh
141 sbb dx, (MAX_SECTOR_COUNT_TO_RETURN_PCHS+1) >> 16
[542]142 sbb bx, BYTE 0
[544]143 jnc SHORT .StoreNumberOfLbaSectors
[533]144
[542]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
[543]156
157 ; We could remove wPchsCylinders from DPT if we calculate it on AH=48h
[544]158 ; (and for compatible DPTs) but that would require extra code so we save ROM space instead.
[421]159 mov [di+DPT.wPchsCylinders], ax
[542]160
[543]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.
[542]163 mul cx
164 xor bx, bx
[543]165 jmp SHORT .StoreTotalSectorsFromBXDXAX
[421]166
[558]167
[421]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;--------------------------------------------------------------------
[542]179.StoreNumberOfLbaSectors:
[421]180 ; Store LBA 28/48 total sector count
181 call AtaGeometry_GetLbaSectorCountToBXDXAXfromAtaInfoInESSI
[543]182 or [di+DPT.bFlagsLow], cl ; LBA48 flag
183.StoreTotalSectorsFromBXDXAX:
[542]184 mov [di+DPT.twLbaSectors], ax
185 mov [di+DPT.twLbaSectors+2], dx
186 mov [di+DPT.twLbaSectors+4], bx
187.NoLbaSoNoEBIOS:
[421]188%endif ; MODULE_EBIOS
[150]189 ; Fall to .StoreDeviceSpecificParameters
[3]190
191;--------------------------------------------------------------------
[150]192; .StoreDeviceSpecificParameters
[3]193; Parameters:
194; DS:DI: Ptr to Disk Parameter Table
195; ES:SI: Ptr to 512-byte ATA information read from the drive
[160]196; CS:BP: Ptr to IDEVARS for the controller
[3]197; Returns:
[99]198; Nothing
[3]199; Corrupts registers:
[150]200; AX, BX, CX, DX
[3]201;--------------------------------------------------------------------
[150]202.StoreDeviceSpecificParameters:
203 call Device_FinalizeDPT
[258]204
[262]205;----------------------------------------------------------------------
206; Update drive counts (hard and floppy)
[294]207;----------------------------------------------------------------------
[558]208%ifdef MODULE_SERIAL
209; Device_FinalizeDPT returns with CF set only when a floppy was found which can't happen without MODULE_SERIAL
[258]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.
[294]214; 2. If this is a hard disk, and there have been any floppy drives previously added, then the hard disk is
[258]215; effectively discarded. This is more of a safety check then code that should ever normally be hit (see below).
[294]216; Since the floppy DPT's come after the hard disk DPT's, without expensive (code size) code to relocate a DPT,
[258]217; this was necessary. Now, this situation shouldn't happen in normal operation, for a couple of reasons:
[567]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
[258]221;
[605]222 adc BYTE [RAMVARS.xlateVars+XLATEVARS.bFlopCreateCnt], 0
223 jnz SHORT .AllDone
[558]224%else ; ~MODULE_SERIAL_FLOPPY
[258]225;
226; Even without floppy support enabled, we shouldn't try to mount a floppy image as a hard disk, which
[294]227; could lead to unpredictable results since no MBR will be present, etc. The server doesn't know that
[258]228; floppies are supported, so it is important to still fail here if a floppy is seen during the drive scan.
229;
[605]230 jc SHORT .AllDone
[558]231%endif ; MODULE_SERIAL_FLOPPY
232%endif ; MODULE_SERIAL
[258]233
[150]234 inc BYTE [RAMVARS.bDrvCnt] ; Increment drive count to RAMVARS
[294]235
[558]236%ifdef MODULE_SERIAL
[294]237.AllDone:
[162]238 clc
[558]239%endif
240
[3]241 ret
[258]242
[324]243
[422]244;--------------------------------------------------------------------
[473]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.