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_, 3 years 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
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
[547]110    dec     dl                      ; 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.