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

Last change on this file since 412 was 411, checked in by aitotat@…, 13 years ago

Changes to XTIDE Universal BIOS:

  • Moved some IRQ and LBA48 code to related modules.
File size: 10.8 KB
RevLine 
[99]1; Project name : XTIDE Universal BIOS
[3]2; Description : Functions for creating Disk Parameter Table.
3
[376]4;
5; XTIDE Universal BIOS and Associated Tools
6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2012 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
[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
30; ES:SI: Ptr to 512-byte ATA information read from the drive
31; CS:BP: Ptr to IDEVARS for the controller
32; DS: RAMVARS segment
33; ES: BDA Segment
34; Returns:
35; DL: Drive number for new drive
[294]36; DS:DI: Ptr to Disk Parameter Table (if successful)
[3]37; CF: Cleared if DPT created successfully
38; Set if any error
39; Corrupts registers:
[99]40; AX, BX, CX, DH
[3]41;--------------------------------------------------------------------
42CreateDPT_FromAtaInformation:
[150]43 call FindDPT_ForNewDriveToDSDI
[99]44 ; Fall to .InitializeDPT
[3]45
46;--------------------------------------------------------------------
[99]47; .InitializeDPT
[3]48; Parameters:
49; BH: Drive Select byte for Drive and Head Register
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:
[150]58 mov [di+DPT.bIdevarsOffset], bp ; IDEVARS must start in first 256 bytes of ROM
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
[173]83 ; Fall to .StoreAddressing
[3]84
85;--------------------------------------------------------------------
[173]86; .StoreAddressing
[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;--------------------------------------------------------------------
[173]96.StoreAddressing:
97 ; Check if CHS defined in ROMVARS
[193]98 call AccessDPT_GetPointerToDRVPARAMStoCSBX
99 test byte [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERCHS ; User specified CHS?
[227]100 jnz SHORT .StoreUserDefinedPCHS
[173]101
102 ; Check if LBA supported
[169]103 call AtaID_GetPCHStoAXBLBHfromAtaInfoInESSI
[173]104 test BYTE [es:si+ATA1.wCaps+1], A1_wCaps_LBA>>8
[227]105 jz SHORT .StoreCHSfromAXBHBL ; Small old drive with CHS addressing only
[3]106
[324]107 ; Store LBA 28/48 addressing and total sector count
[173]108 call AtaID_GetTotalSectorCountToBXDXAXfromAtaInfoInESSI
[324]109 call StoreLbaAddressingAndTotalSectorCountFromBXDXAX
110
111 ; Replace sector count with user defined if necessary
112 call AccessDPT_GetPointerToDRVPARAMStoCSBX
113 test BYTE [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERLBA
114 jz SHORT .KeepTotalSectorsFromAtaID
115 mov ax, [cs:bx+DRVPARAMS.dwMaximumLBA]
116 mov dx, [cs:bx+DRVPARAMS.dwMaximumLBA+2]
117 xor bx, bx
118
119 ; Compare user defined and ATA-ID sector count and select smaller
120 cmp bx, [di+DPT.twLbaSectors+4]
121 jb SHORT .StoreUserDefinedSectorCountToDPT
122 cmp dx, [di+DPT.twLbaSectors+2]
123 jb SHORT .StoreUserDefinedSectorCountToDPT
124 ja SHORT .KeepTotalSectorsFromAtaID
125 cmp ax, [di+DPT.twLbaSectors]
126 jae SHORT .KeepTotalSectorsFromAtaID
127.StoreUserDefinedSectorCountToDPT:
128 call StoreLbaAddressingAndTotalSectorCountFromBXDXAX
129
130 ; Calculate L-CHS for old INT 13h
131.KeepTotalSectorsFromAtaID:
132 mov bx, [di+DPT.twLbaSectors+4] ; Restore BX
[358]133 call LbaAssist_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH
[227]134 mov [di+DPT.bLbaHeads], bl
135 jmp SHORT .StoreBlockMode
[173]136
[227]137;--------------------------------------------------------------------
138; .StoreUserDefinedPCHS
139; Parameters:
140; DS:DI: Ptr to Disk Parameter Table
141; ES:SI: Ptr to 512-byte ATA information read from the drive
142; CS:BP: Ptr to IDEVARS for the controller
143; Returns:
144; AX: Number of P-CHS cylinders
145; BH: Number of P-CHS sectors per track
146; BL: Number of P-CHS heads
147; Corrupts registers:
148; Nothing
149;--------------------------------------------------------------------
150.StoreUserDefinedPCHS:
[3]151 call AccessDPT_GetPointerToDRVPARAMStoCSBX
152 mov ax, [cs:bx+DRVPARAMS.wCylinders]
[99]153 mov bx, [cs:bx+DRVPARAMS.wHeadsAndSectors]
[227]154 ; Fall to .StoreCHSfromAXBHBL
[3]155
[227]156;--------------------------------------------------------------------
157; .StoreCHSfromAXBHBL
158; Parameters:
159; AX: Number of P-CHS cylinders
160; BH: Number of P-CHS sectors per track
161; BL: Number of P-CHS heads
162; DS:DI: Ptr to Disk Parameter Table
163; ES:SI: Ptr to 512-byte ATA information read from the drive
164; CS:BP: Ptr to IDEVARS for the controller
165; Returns:
166; AX: Number of P-CHS cylinders
167; BH: Number of P-CHS sectors per track
168; BL: Number of P-CHS heads
169; Corrupts registers:
170; CX
171;--------------------------------------------------------------------
172.StoreCHSfromAXBHBL:
[173]173 push ax
[227]174 push bx
175 call AccessDPT_ShiftPCHinAXBLtoLCH ; Get number of bits to shift
176 pop bx
[173]177 pop ax
[227]178 jcxz .StorePCHSfromAXDX ; Small drive so use L-CHS addressing
[3]179
[227]180 ; Store P-CHS addressing mode and number of bits to shift in L-CHS to P-CHS translation
181 or cl, ADDRESSING_MODE_PCHS<<ADDRESSING_MODE_FIELD_POSITION
182 or [di+DPT.bFlagsLow], cl
183 ; Fall to .StoreChsFromAXBLBH
184
[3]185;--------------------------------------------------------------------
[227]186; .StoreChsFromAXBLBH
[3]187; Parameters:
[227]188; AX: Number of P-CHS cylinders
189; BH: Number of P-CHS sectors per track
190; BL: Number of P-CHS heads
[3]191; DS:DI: Ptr to Disk Parameter Table
192; ES:SI: Ptr to 512-byte ATA information read from the drive
[160]193; CS:BP: Ptr to IDEVARS for the controller
[3]194; Returns:
[99]195; Nothing
[3]196; Corrupts registers:
[227]197; Nothing
[3]198;--------------------------------------------------------------------
[227]199.StorePCHSfromAXDX:
200 mov [di+DPT.wPchsCylinders], ax
201 mov [di+DPT.wPchsHeadsAndSectors], bx
[99]202 ; Fall to .StoreBlockMode
[3]203
204;--------------------------------------------------------------------
[99]205; .StoreBlockMode
[3]206; Parameters:
207; DS:DI: Ptr to Disk Parameter Table
208; ES:SI: Ptr to 512-byte ATA information read from the drive
[160]209; CS:BP: Ptr to IDEVARS for the controller
[3]210; Returns:
[99]211; Nothing
[3]212; Corrupts registers:
[150]213; Nothing
[3]214;--------------------------------------------------------------------
[99]215.StoreBlockMode:
[150]216 cmp BYTE [es:si+ATA1.bBlckSize], 1 ; Max block size in sectors
217 jbe SHORT .BlockModeTransfersNotSupported
[158]218 or BYTE [di+DPT.bFlagsHigh], FLGH_DPT_BLOCK_MODE_SUPPORTED
[150]219.BlockModeTransfersNotSupported:
220 ; Fall to .StoreDeviceSpecificParameters
[3]221
222;--------------------------------------------------------------------
[150]223; .StoreDeviceSpecificParameters
[3]224; Parameters:
225; DS:DI: Ptr to Disk Parameter Table
226; ES:SI: Ptr to 512-byte ATA information read from the drive
[160]227; CS:BP: Ptr to IDEVARS for the controller
[3]228; Returns:
[99]229; Nothing
[3]230; Corrupts registers:
[150]231; AX, BX, CX, DX
[3]232;--------------------------------------------------------------------
[150]233.StoreDeviceSpecificParameters:
234 call Device_FinalizeDPT
[258]235
[262]236;----------------------------------------------------------------------
237; Update drive counts (hard and floppy)
[294]238;----------------------------------------------------------------------
239
[258]240%ifdef MODULE_SERIAL_FLOPPY
241;
242; These two instructions serve two purposes:
243; 1. If the drive is a floppy drive (CF set), then we effectively increment the counter.
[294]244; 2. If this is a hard disk, and there have been any floppy drives previously added, then the hard disk is
[258]245; effectively discarded. This is more of a safety check then code that should ever normally be hit (see below).
[294]246; Since the floppy DPT's come after the hard disk DPT's, without expensive (code size) code to relocate a DPT,
[258]247; this was necessary. Now, this situation shouldn't happen in normal operation, for a couple of reasons:
[294]248; A. xtidecfg always puts configured serial ports at the end of the IDEVARS list
[258]249; B. the auto serial code is always executed last
250; C. the serial server always returns floppy drives last
251;
252 adc byte [RAMVARS.xlateVars+XLATEVARS.bFlopCreateCnt], 0
[294]253 jnz .AllDone
[258]254%else
255;
256; Even without floppy support enabled, we shouldn't try to mount a floppy image as a hard disk, which
[294]257; could lead to unpredictable results since no MBR will be present, etc. The server doesn't know that
[258]258; floppies are supported, so it is important to still fail here if a floppy is seen during the drive scan.
259;
260 jc .AllDone
261%endif
262
[150]263 inc BYTE [RAMVARS.bDrvCnt] ; Increment drive count to RAMVARS
[294]264
265.AllDone:
[162]266 clc
[3]267 ret
[258]268
[324]269
270;--------------------------------------------------------------------
271; StoreLbaAddressingAndTotalSectorCountFromBXDXAX
272; Parameters:
273; BX:DX:AX: Total Sector Count
274; DS:DI: Ptr to Disk Parameter Table
275; Returns:
276; Nothing
277; Corrupts registers:
278; CX
279;--------------------------------------------------------------------
280StoreLbaAddressingAndTotalSectorCountFromBXDXAX:
281 mov [di+DPT.twLbaSectors], ax
282 mov [di+DPT.twLbaSectors+2], dx
283 mov [di+DPT.twLbaSectors+4], bx
284
[411]285%ifdef MODULE_EBIOS
[324]286 and BYTE [di+DPT.bFlagsLow], ~MASKL_DPT_ADDRESSING_MODE
287 test bx, bx
[346]288 jnz SHORT .SetLba48AddressingToDPT ; Must be LBA48
289
290 ; Drives can report at most 0FFF FFFFh LBA28 sectors according to ATA specification.
291 ; That is (2^28)-1 so we can simply check if DH is zero or not.
292 test dh, dh
[324]293 jz SHORT .SetLba28AddressingToDPT
294.SetLba48AddressingToDPT:
295 or BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA48<<ADDRESSING_MODE_FIELD_POSITION
296.SetLba28AddressingToDPT:
[411]297%endif
[324]298 or BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA28<<ADDRESSING_MODE_FIELD_POSITION
299 ret
Note: See TracBrowser for help on using the repository browser.