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

Last change on this file since 533 was 533, checked in by aitotat@…, 10 years ago

Changes to XTIDE Universal BIOS:

  • P-Cylinders returned by AH=48h are now calculated from L-CHS capacity when RESERVE_DIAGNOSTIC_CYLINDER is defined.
  • Total sector count returned by AH=48h is now always P-Cylinders * P-Heads * P-Sectors per track for drives with less than or equal 15,482,880 LBA sectors.
File size: 11.9 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 (if successful)
37;       CF:     Cleared if DPT created successfully
38;               Set if any error
39;   Corrupts registers:
40;       AX, BX, CX, DH
41;--------------------------------------------------------------------
42CreateDPT_FromAtaInformation:
43    call    FindDPT_ForNewDriveToDSDI
44    ; Fall to .InitializeDPT
45
46;--------------------------------------------------------------------
47; .InitializeDPT
48;   Parameters:
49;       BH:     Drive Select byte for Drive and Head Register
50;       DX:     Autodetected port (for devices that support autodetection)
51;       DS:DI:  Ptr to Disk Parameter Table
52;       CS:BP:  Ptr to IDEVARS for the controller
53;   Returns:
54;       Nothing
55;   Corrupts registers:
56;       AX
57;--------------------------------------------------------------------
58.InitializeDPT:
59    call    CreateDPT_StoreIdevarsOffsetAndBasePortFromCSBPtoDPTinDSDI
60    ; Fall to .StoreDriveSelectAndDriveControlByte
61
62;--------------------------------------------------------------------
63; .StoreDriveSelectAndDriveControlByte
64;   Parameters:
65;       BH:     Drive Select byte for Drive and Head Register
66;       DS:DI:  Ptr to Disk Parameter Table
67;       ES:SI:  Ptr to 512-byte ATA information read from the drive
68;       CS:BP:  Ptr to IDEVARS for the controller
69;   Returns:
70;       Nothing
71;   Corrupts registers:
72;       AX
73;--------------------------------------------------------------------
74.StoreDriveSelectAndDriveControlByte:
75    mov     al, bh
76    and     ax, BYTE FLG_DRVNHEAD_DRV       ; AL now has Master/Slave bit
77%ifdef MODULE_IRQ
78    cmp     [cs:bp+IDEVARS.bIRQ], ah        ; Interrupts enabled?
79    jz      SHORT .StoreFlags               ;  If not, do not set interrupt flag
80    or      al, FLGL_DPT_ENABLE_IRQ
81.StoreFlags:
82%endif
83    mov     [di+DPT.wFlags], ax
84    ; Fall to .StoreCHSparametersAndAddressingMode
85
86;--------------------------------------------------------------------
87; .StoreCHSparametersAndAddressingMode
88;   Parameters:
89;       DS:DI:  Ptr to Disk Parameter Table
90;       ES:SI:  Ptr to 512-byte ATA information read from the drive
91;       CS:BP:  Ptr to IDEVARS for the controller
92;   Returns:
93;       Nothing
94;   Corrupts registers:
95;       AX, BX, CX, DX
96;--------------------------------------------------------------------
97.StoreCHSparametersAndAddressingMode:
98    ; Check if CHS defined in ROMVARS
99    call    GetUserDefinedCapacityToBXAXandFlagsToCXandModeToDXfromROMVARS
100    test    cl, FLG_DRVPARAMS_USERCHS
101    jz      SHORT .AutodetectPCHSvalues
102
103    ; Translate P-CHS to L-CHS
104    call    AtaGeometry_GetLCHStoAXBLBHfromPCHSinAXBLBHandTranslateModeInDX
105    jmp     SHORT .StoreLCHStoDPT
106.AutodetectPCHSvalues:
107    call    AtaGeometry_GetLCHStoAXBLBHfromAtaInfoInESSIandTranslateModeInDX
108
109.StoreLCHStoDPT:
110    eSHL_IM dl, TRANSLATEMODE_FIELD_POSITION
111    or      cl, dl
112    or      [di+DPT.bFlagsLow], cl      ; Shift count and addressing mode
113    mov     [di+DPT.wLchsCylinders], ax
114    mov     [di+DPT.wLchsHeadsAndSectors], bx
115
116    ; Store P-CHS to DPT
117    call    AtaGeometry_GetPCHStoAXBLBHfromAtaInfoInESSI
118    mov     [di+DPT.bPchsHeads], bl
119%ifdef MODULE_EBIOS
120    mov     [di+DPT.bPchsSectorsPerTrack], bh
121
122%ifdef RESERVE_DIAGNOSTIC_CYLINDER
123    ; Do not store P-Cylinders, instead calculate it from L-CHS total sector count.
124    ; Read AH=48h_GetExtendedDriveParameters.asm for more info.
125    xchg    ax, bx
126    mul     ah
127    push    ax                          ; P-Heads * P-Sectors per track
128    call    AH15h_GetSectorCountToBXDXAX
129    pop     bx
130    div     bx                          ; AX = Calculated cylinders
131%endif ; RESERVE_DIAGNOSTIC_CYLINDER
132
133    mov     [di+DPT.wPchsCylinders], ax
134    ; Fall to .StoreNumberOfLbaSectors
135
136;--------------------------------------------------------------------
137; .StoreNumberOfLbaSectors
138;   Parameters:
139;       DS:DI:  Ptr to Disk Parameter Table
140;       ES:SI:  Ptr to 512-byte ATA information read from the drive
141;       CS:BP:  Ptr to IDEVARS for the controller
142;   Returns:
143;       Nothing
144;   Corrupts registers:
145;       AX, BX, CX, DX
146;--------------------------------------------------------------------
147    ; Check if LBA supported
148    test    BYTE [es:si+ATA1.wCaps+1], A1_wCaps_LBA>>8
149    jz      SHORT .NoLbaSupportedSoNoEBIOS
150
151    ; Store LBA 28/48 total sector count
152    call    AtaGeometry_GetLbaSectorCountToBXDXAXfromAtaInfoInESSI
153    call    StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX
154
155    ; If we have 15,482,880 or less sectors, we multiply P-CHS values
156    ; and use that as total sector count.
157    ; Read AH=48h_GetExtendedDriveParameters.asm for more info.
158    sub     ax, 4001h
159    sbb     dx, 0ECh
160    sbb     bx, BYTE 0
161    jnc     SHORT .NoNeedToUseCHSsectorCount    ; More than EC4000h
162
163    mov     al, [di+DPT.bPchsHeads]
164    mul     BYTE [di+DPT.bPchsSectorsPerTrack]
165    mul     WORD [di+DPT.wPchsCylinders]
166    xor     bx, bx
167    call    StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX
168
169    ; Load user defined LBA
170.NoNeedToUseCHSsectorCount:
171    call    GetUserDefinedCapacityToBXAXandFlagsToCXandModeToDXfromROMVARS
172    test    cl, FLG_DRVPARAMS_USERLBA
173    jz      SHORT .KeepTotalSectorsFromAtaID
174
175    ; Compare user defined and ATA-ID sector count and select smaller
176    mov     dx, bx
177    xor     bx, bx      ; User defined LBA now in BX:DX:AX
178    cmp     bx, [di+DPT.twLbaSectors+4]
179    jb      SHORT .StoreUserDefinedSectorCountToDPT
180    cmp     dx, [di+DPT.twLbaSectors+2]
181    jb      SHORT .StoreUserDefinedSectorCountToDPT
182    ja      SHORT .KeepTotalSectorsFromAtaID
183    cmp     ax, [di+DPT.twLbaSectors]
184    jae     SHORT .KeepTotalSectorsFromAtaID
185.StoreUserDefinedSectorCountToDPT:
186    ; CL bit FLGL_DPT_LBA48 is clear at this point
187    call    StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX
188
189.KeepTotalSectorsFromAtaID:
190.NoLbaSupportedSoNoEBIOS:
191%endif ; MODULE_EBIOS
192    ; Fall to .StoreBlockMode
193
194;--------------------------------------------------------------------
195; .StoreBlockMode
196;   Parameters:
197;       DS:DI:  Ptr to Disk Parameter Table
198;       ES:SI:  Ptr to 512-byte ATA information read from the drive
199;       CS:BP:  Ptr to IDEVARS for the controller
200;   Returns:
201;       Nothing
202;   Corrupts registers:
203;       Nothing
204;--------------------------------------------------------------------
205.StoreBlockMode:
206    cmp     BYTE [es:si+ATA1.bBlckSize], 1  ; Max block size in sectors
207    jbe     SHORT .BlockModeTransfersNotSupported
208    or      BYTE [di+DPT.bFlagsHigh], FLGH_DPT_BLOCK_MODE_SUPPORTED
209.BlockModeTransfersNotSupported:
210    ; Fall to .StoreDeviceSpecificParameters
211
212;--------------------------------------------------------------------
213; .StoreDeviceSpecificParameters
214;   Parameters:
215;       DS:DI:  Ptr to Disk Parameter Table
216;       ES:SI:  Ptr to 512-byte ATA information read from the drive
217;       CS:BP:  Ptr to IDEVARS for the controller
218;   Returns:
219;       Nothing
220;   Corrupts registers:
221;       AX, BX, CX, DX
222;--------------------------------------------------------------------
223.StoreDeviceSpecificParameters:
224    call    Device_FinalizeDPT
225
226;----------------------------------------------------------------------
227; Update drive counts (hard and floppy)
228;----------------------------------------------------------------------
229
230%ifdef MODULE_SERIAL_FLOPPY
231;
232; These two instructions serve two purposes:
233; 1. If the drive is a floppy drive (CF set), then we effectively increment the counter.
234; 2. If this is a hard disk, and there have been any floppy drives previously added, then the hard disk is
235;    effectively discarded.  This is more of a safety check then code that should ever normally be hit (see below).
236;    Since the floppy DPT's come after the hard disk DPT's, without expensive (code size) code to relocate a DPT,
237;    this was necessary.  Now, this situation shouldn't happen in normal operation, for a couple of reasons:
238;       A. xtidecfg always puts configured serial ports at the end of the IDEVARS list
239;       B. the auto serial code is always executed last
240;       C. the serial server always returns floppy drives last
241;
242    adc     byte [RAMVARS.xlateVars+XLATEVARS.bFlopCreateCnt], 0
243    jnz     .AllDone
244%else
245;
246; Even without floppy support enabled, we shouldn't try to mount a floppy image as a hard disk, which
247; could lead to unpredictable results since no MBR will be present, etc.  The server doesn't know that
248; floppies are supported, so it is important to still fail here if a floppy is seen during the drive scan.
249;
250    jc      .AllDone
251%endif
252
253    inc     BYTE [RAMVARS.bDrvCnt]      ; Increment drive count to RAMVARS
254
255.AllDone:
256    clc
257    ret
258
259
260;--------------------------------------------------------------------
261; CreateDPT_StoreIdevarsOffsetAndBasePortFromCSBPtoDPTinDSDI
262;   Parameters:
263;       DX:     Autodetected port (for devices that support autodetection)
264;       DS:DI:  Ptr to Disk Parameter Table
265;       CS:BP:  Ptr to IDEVARS for the controller
266;   Returns:
267;       Nothing
268;   Corrupts registers:
269;       AX
270;--------------------------------------------------------------------
271CreateDPT_StoreIdevarsOffsetAndBasePortFromCSBPtoDPTinDSDI:
272    mov     [di+DPT.bIdevarsOffset], bp     ; IDEVARS must start in first 256 bytes of ROM
273
274%ifdef MODULE_8BIT_IDE_ADVANCED
275    call    DetectDrives_DoesIdevarsInCSBPbelongToXTCF
276    jne     SHORT .DeviceUsesPortSpecifiedInIDEVARS
277    mov     [di+DPT.wBasePort], dx
278    ret
279.DeviceUsesPortSpecifiedInIDEVARS:
280%endif ; MODULE_8BIT_IDE_ADVANCED
281
282    mov     ax, [cs:bp+IDEVARS.wBasePort]
283    mov     [di+DPT.wBasePort], ax
284    ret
285
286
287;--------------------------------------------------------------------
288; GetUserDefinedCapacityToBXAXandFlagsToCXandModeToDXfromROMVARS
289;   Parameters:
290;       DS:DI:      Ptr to Disk Parameter Table
291;   Returns:
292;       AX:         User defined P-CHS Cylinders or LBA low word
293;       BX:         User defined P-CHS Heads and Sectors or LBA high word
294;       DX:         Translate mode or TRANSLATEMODE_AUTO
295;       CX:         FLG_DRVPARAMS_USERCHS if user defined CHS in BX:AX
296;                   FLG_DRVPARAMS_USERLBA if user defined LBA in BX:AX
297;                   Zero if user has not defined capacity
298;   Corrupts registers:
299;       Nothing
300;--------------------------------------------------------------------
301GetUserDefinedCapacityToBXAXandFlagsToCXandModeToDXfromROMVARS:
302    call    AccessDPT_GetPointerToDRVPARAMStoCSBX
303
304    ; Get settings
305    mov     cx, [cs:bx+DRVPARAMS.wFlags]
306    mov     dx, cx
307    and     cx, BYTE FLG_DRVPARAMS_USERCHS | FLG_DRVPARAMS_USERLBA
308    and     dx, BYTE MASK_DRVPARAMS_TRANSLATEMODE
309    eSHR_IM dx, TRANSLATEMODE_FIELD_POSITION
310
311    ; Get capacity
312    mov     ax, [cs:bx+DRVPARAMS.wCylinders]        ; Or .dwMaximumLBA
313    mov     bx, [cs:bx+DRVPARAMS.wHeadsAndSectors]  ; Or .dwMaximumLBA+2
314    ret
315
316
317%ifdef MODULE_EBIOS
318;--------------------------------------------------------------------
319; StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX
320;   Parameters:
321;       BX:DX:AX:   Total Sector Count
322;       CL:         FLGL_DPT_LBA48 if LBA48 supported
323;       DS:DI:      Ptr to Disk Parameter Table
324;   Returns:
325;       Nothing
326;   Corrupts registers:
327;       CL
328;--------------------------------------------------------------------
329StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX:
330    or      cl, FLGL_DPT_LBA_AND_EBIOS_SUPPORTED
331    and     BYTE [di+DPT.bFlagsLow], ~FLGL_DPT_LBA48
332    or      [di+DPT.bFlagsLow], cl
333    mov     [di+DPT.twLbaSectors], ax
334    mov     [di+DPT.twLbaSectors+2], dx
335    mov     [di+DPT.twLbaSectors+4], bx
336    ret
337%endif ; MODULE_EBIOS
Note: See TracBrowser for help on using the repository browser.