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

Last change on this file since 605 was 605, checked in by krille_n_, 6 months ago

Changes:

  • The "Remove other hard drives" option in the Boot settings menu in XTIDECFG is now exposed in all BIOS builds. This is needed because the system BIOS in at least two Zenith computer models (Z-161 and Z-171) does not clear the BDA HD count which causes it to increment on warm boot. Running "Auto Configure" in XTIDECFG now also tries to identify these machines by doing a CRC check on the system BIOS and sets the option to YES if a match is found.
  • WORD_ALIGN is now 2 for XT builds. This should benefit XT class machines with 8086 and NEC V30 CPU:s and the cost is negligible (1 byte for the XT BIOS builds and 12 bytes for XTIDECFG.COM).
  • Other minor optimizations.
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     dl                      ; 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.