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

Last change on this file since 288 was 262, checked in by gregli@…, 13 years ago

More optimizations. Merged RamVars_IsFunction/DriveHandledByThisBIOS in with FindDPT_ForDriveNumber, since they are often used together, making a returned NULL DI pointer indicate a foreign drive in many places. Revamped the iteration done in the handlers for int13/0dh and int13h/0h. Added serial specific print string during drive detection.

File size: 8.4 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
20; DS:DI: Ptr to Disk Parameter Table (if succesfull)
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
[173]89 ; Check if 48-bit LBA supported
90 test BYTE [es:si+ATA6.wSetSup83+1], A6_wSetSup83_LBA48>>8
91 jz SHORT .StoreLBA28addressing
92 or BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA48<<ADDRESSING_MODE_FIELD_POSITION
93.StoreLBA28addressing:
94 or BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA28<<ADDRESSING_MODE_FIELD_POSITION
95 call AtaID_GetTotalSectorCountToBXDXAXfromAtaInfoInESSI
[227]96 mov [di+DPT.twLbaSectors], ax
97 mov [di+DPT.twLbaSectors+2], dx
98 mov [di+DPT.twLbaSectors+4], bx
[173]99 call AtaID_GetLbaAssistedCHStoDXAXBLBH
[227]100 mov [di+DPT.bLbaHeads], bl
101 jmp SHORT .StoreBlockMode
[173]102
[227]103;--------------------------------------------------------------------
104; .StoreUserDefinedPCHS
105; Parameters:
106; DS:DI: Ptr to Disk Parameter Table
107; ES:SI: Ptr to 512-byte ATA information read from the drive
108; CS:BP: Ptr to IDEVARS for the controller
109; Returns:
110; AX: Number of P-CHS cylinders
111; BH: Number of P-CHS sectors per track
112; BL: Number of P-CHS heads
113; Corrupts registers:
114; Nothing
115;--------------------------------------------------------------------
116.StoreUserDefinedPCHS:
[3]117 call AccessDPT_GetPointerToDRVPARAMStoCSBX
118 mov ax, [cs:bx+DRVPARAMS.wCylinders]
[99]119 mov bx, [cs:bx+DRVPARAMS.wHeadsAndSectors]
[227]120 ; Fall to .StoreCHSfromAXBHBL
[3]121
[227]122;--------------------------------------------------------------------
123; .StoreCHSfromAXBHBL
124; Parameters:
125; AX: Number of P-CHS cylinders
126; BH: Number of P-CHS sectors per track
127; BL: Number of P-CHS heads
128; DS:DI: Ptr to Disk Parameter Table
129; ES:SI: Ptr to 512-byte ATA information read from the drive
130; CS:BP: Ptr to IDEVARS for the controller
131; Returns:
132; AX: Number of P-CHS cylinders
133; BH: Number of P-CHS sectors per track
134; BL: Number of P-CHS heads
135; Corrupts registers:
136; CX
137;--------------------------------------------------------------------
138.StoreCHSfromAXBHBL:
[173]139 push ax
[227]140 push bx
141 call AccessDPT_ShiftPCHinAXBLtoLCH ; Get number of bits to shift
142 pop bx
[173]143 pop ax
[227]144 jcxz .StorePCHSfromAXDX ; Small drive so use L-CHS addressing
[3]145
[227]146 ; Store P-CHS addressing mode and number of bits to shift in L-CHS to P-CHS translation
147 or cl, ADDRESSING_MODE_PCHS<<ADDRESSING_MODE_FIELD_POSITION
148 or [di+DPT.bFlagsLow], cl
149 ; Fall to .StoreChsFromAXBLBH
150
[3]151;--------------------------------------------------------------------
[227]152; .StoreChsFromAXBLBH
[3]153; Parameters:
[227]154; AX: Number of P-CHS cylinders
155; BH: Number of P-CHS sectors per track
156; BL: Number of P-CHS heads
[3]157; DS:DI: Ptr to Disk Parameter Table
158; ES:SI: Ptr to 512-byte ATA information read from the drive
[160]159; CS:BP: Ptr to IDEVARS for the controller
[3]160; Returns:
[99]161; Nothing
[3]162; Corrupts registers:
[227]163; Nothing
[3]164;--------------------------------------------------------------------
[227]165.StorePCHSfromAXDX:
166 mov [di+DPT.wPchsCylinders], ax
167 mov [di+DPT.wPchsHeadsAndSectors], bx
[99]168 ; Fall to .StoreBlockMode
[3]169
170;--------------------------------------------------------------------
[99]171; .StoreBlockMode
[3]172; Parameters:
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:
[150]179; Nothing
[3]180;--------------------------------------------------------------------
[99]181.StoreBlockMode:
[150]182 cmp BYTE [es:si+ATA1.bBlckSize], 1 ; Max block size in sectors
183 jbe SHORT .BlockModeTransfersNotSupported
[158]184 or BYTE [di+DPT.bFlagsHigh], FLGH_DPT_BLOCK_MODE_SUPPORTED
[150]185.BlockModeTransfersNotSupported:
186 ; Fall to .StoreDeviceSpecificParameters
[3]187
188;--------------------------------------------------------------------
[150]189; .StoreDeviceSpecificParameters
[3]190; Parameters:
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:
[150]197; AX, BX, CX, DX
[3]198;--------------------------------------------------------------------
[150]199.StoreDeviceSpecificParameters:
200 call Device_FinalizeDPT
[258]201
[262]202;----------------------------------------------------------------------
203; Update drive counts (hard and floppy)
204;----------------------------------------------------------------------
205
[258]206%ifdef MODULE_SERIAL_FLOPPY
207;
208; These two instructions serve two purposes:
209; 1. If the drive is a floppy drive (CF set), then we effectively increment the counter.
210; 2. If this is a hard disk, and there have been any floppy drives previously added, then the hard disk is
211; effectively discarded. This is more of a safety check then code that should ever normally be hit (see below).
212; Since the floppy DPT's come after the hard disk DPT's, without expensive (code size) code to relocate a DPT,
213; this was necessary. Now, this situation shouldn't happen in normal operation, for a couple of reasons:
214; A. xtidecfg always puts configured serial ports at the end fo the IDEVARS list
215; B. the auto serial code is always executed last
216; C. the serial server always returns floppy drives last
217;
218 adc byte [RAMVARS.xlateVars+XLATEVARS.bFlopCreateCnt], 0
219 jnz .AllDone
220%else
221;
222; Even without floppy support enabled, we shouldn't try to mount a floppy image as a hard disk, which
223; could lead to unpredictable results since no MBR will be present, etc. The server doesn't know that
224; floppies are supported, so it is important to still fail here if a floppy is seen during the drive scan.
225;
226 jc .AllDone
227%endif
228
[150]229 inc BYTE [RAMVARS.bDrvCnt] ; Increment drive count to RAMVARS
[262]230
231.AllDone:
[162]232 clc
[3]233 ret
[258]234
Note: See TracBrowser for help on using the repository browser.