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

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

Changes to XTIDE Universal BIOS:

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