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

Last change on this file since 120 was 99, checked in by Tomi Tilli, 14 years ago

Changes to XTIDE Universal BIOS:

  • Even more initialization code inlining.
File size: 8.3 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:
27 call FindDPT_ForNewDrive ; Get new DPT to DS:DI
[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:
[99]37; AX: Zero
[3]38; Corrupts registers:
39; Nothing
40;--------------------------------------------------------------------
[99]41.InitializeDPT:
42 xor ax, ax
[3]43 mov BYTE [di+DPT.bSize], DPT_size
[99]44 mov [di+DPT.wDrvNumAndFlags], ax
[3]45 mov BYTE [di+DPT.bReset], MASK_RESET_ALL
[99]46 mov [di+DPT.bIdeOff], bp
47 mov [di+DPT.bDrvSel], bh
48 ; Fall to .StoreDriveControlByte
[3]49
50;--------------------------------------------------------------------
[99]51; .StoreDriveControlByte
[3]52; Parameters:
[99]53; AX: Zero
[3]54; BH: Drive Select byte for Drive and Head Register
55; DS:DI: Ptr to Disk Parameter Table
56; ES:SI: Ptr to 512-byte ATA information read from the drive
57; CS:BP: Ptr to IDEVARS for the controller
58; Returns:
[99]59; Nothing
[3]60; Corrupts registers:
61; AX
62;--------------------------------------------------------------------
[99]63.StoreDriveControlByte:
64 cmp BYTE [cs:bp+IDEVARS.bIRQ], al ; Interrupts enabled?
[3]65 jne SHORT .CheckHeadCount
66 or al, FLG_IDE_CTRL_nIEN ; Disable interrupts
67.CheckHeadCount:
68 cmp BYTE [es:si+ATA1.wHeadCnt], 8 ; 1...8 heads?
[99]69 jbe SHORT .StoreDrvCtrlByteToDPT
[3]70 or al, FLG_IDE_CTRL_O8H ; Over 8 heads (pre-ATA)
[99]71.StoreDrvCtrlByteToDPT:
[3]72 mov [di+DPT.bDrvCtrl], al
[99]73 ; Fall to .StorePCHS
[3]74
75;--------------------------------------------------------------------
[99]76; .StorePCHS
[3]77; Parameters:
[99]78; AH: Zero
[3]79; BH: Drive Select byte for Drive and Head Register
80; DS:DI: Ptr to Disk Parameter Table
81; ES:SI: Ptr to 512-byte ATA information read from the drive
82; CS:BP: Ptr to IDEVARS for the controller
83; Returns:
[99]84; AX: P-CHS cylinders
85; BL: P-CHS heads
86; BH: P-CHS sectors
[3]87; Corrupts registers:
88; Nothing
89;--------------------------------------------------------------------
[99]90.StorePCHS:
91 mov al, FLG_DRVPARAMS_USERCHS ; User specified CHS?
[3]92 call AccessDPT_TestIdeVarsFlagsForMasterOrSlaveDrive
[99]93 jnz SHORT .GetUserSpecifiedPCHS
94 call AtaID_GetPCHS ; Get from ATA information
95 jmp SHORT .StorePCHStoDPT
[3]96
[99]97.GetUserSpecifiedPCHS:
[3]98 call AccessDPT_GetPointerToDRVPARAMStoCSBX
99 mov ax, [cs:bx+DRVPARAMS.wCylinders]
[99]100 mov bx, [cs:bx+DRVPARAMS.wHeadsAndSectors]
[3]101 or BYTE [di+DPT.bFlags], FLG_DPT_USERCHS
102
[99]103.StorePCHStoDPT:
104 mov [di+DPT.wPCyls], ax
105 mov [di+DPT.wHeadsAndSectors], bx
106 ; Fall to .StoreLCHS
[3]107
108;--------------------------------------------------------------------
[99]109; .StoreLCHS
[3]110; Parameters:
[99]111; AX: P-CHS cylinders
112; BL: P-CHS heads
[3]113; DS:DI: Ptr to Disk Parameter Table
114; ES:SI: Ptr to 512-byte ATA information read from the drive
115; Returns:
[99]116; Nothing
[3]117; Corrupts registers:
[99]118; AX, BX, CX
[3]119;--------------------------------------------------------------------
[99]120.StoreLCHS:
121 xor bh, bh ; BX = P-CHS Heads (1...16)
122 xor cx, cx
[3]123.ShiftLoop:
[99]124 cmp ax, 1024 ; Need to shift?
125 jbe SHORT .LimitHeadsTo255 ; If not, return
126 inc cx ; Increment shift count
127 shr ax, 1 ; Halve cylinders
128 shl bx, 1 ; Double heads
[3]129 jmp SHORT .ShiftLoop
130
[99]131.LimitHeadsTo255:
132 test bh, bh ; 256 heads?
133 jz SHORT .StoreLCHStoDPT ; If less, no correction needed
134 dec bx ; Limit to 255 heads since DOS does not support 256 heads
135.StoreLCHStoDPT:
136 mov [di+DPT.bShLtoP], cl
137 mov [di+DPT.wLHeads], bx
138 ; Fall to .StoreAddressing
[3]139
140;--------------------------------------------------------------------
[99]141; .StoreAddressing
[3]142; Parameters:
143; DS:DI: Ptr to Disk Parameter Table
144; ES:SI: Ptr to 512-byte ATA information read from the drive
145; Returns:
[99]146; Nothing
[3]147; Corrupts registers:
148; Nothing
149;--------------------------------------------------------------------
[99]150.StoreAddressing:
[3]151 cmp WORD [di+DPT.wPCyls], 1024 ; L-CHS possible? (no translation needed)
[99]152 jbe SHORT .StoreBlockMode ; If so, nothing needs to be changed
[3]153 test BYTE [di+DPT.bFlags], FLG_DPT_USERCHS
[99]154 jnz SHORT .StorePCHSaddressing ; Use user defined P-CHS
[3]155 test WORD [es:si+ATA1.wCaps], A2_wCaps_LBA
[99]156 jz SHORT .StorePCHSaddressing ; Use P-CHS since LBA not supported
[3]157 test WORD [es:si+ATA6.wSetSup83], A6_wSetSup83_LBA48
[99]158 jz SHORT .StoreLBA28addressing ; Use LBA-28 since LBA-48 not supported
[3]159 or BYTE [di+DPT.bFlags], ADDR_DPT_LBA48<<1
[99]160.StoreLBA28addressing:
[3]161 or BYTE [di+DPT.bFlags], ADDR_DPT_LBA28<<1
162 or BYTE [di+DPT.bDrvSel], FLG_IDE_DRVHD_LBA
[99]163 jmp SHORT .StoreBlockMode
164.StorePCHSaddressing:
[3]165 or BYTE [di+DPT.bFlags], ADDR_DPT_PCHS<<1
[99]166 ; Fall to .StoreBlockMode
[3]167
168;--------------------------------------------------------------------
[99]169; .StoreBlockMode
[3]170; Parameters:
171; DS:DI: Ptr to Disk Parameter Table
172; ES:SI: Ptr to 512-byte ATA information read from the drive
173; Returns:
[99]174; Nothing
[3]175; Corrupts registers:
[99]176; AX
[3]177;--------------------------------------------------------------------
[99]178.StoreBlockMode:
[3]179 mov al, 1 ; Minimum block size is 1 sector
180 mov ah, [es:si+ATA1.bBlckSize] ; Load max block size in sectors
181 mov [di+DPT.wSetAndMaxBlock], ax
[99]182 ; Fall to .StoreEBIOSSupport
[3]183
184;--------------------------------------------------------------------
[99]185; .StoreEBIOSSupport
[3]186; Parameters:
187; DS:DI: Ptr to Disk Parameter Table
188; ES:SI: Ptr to 512-byte ATA information read from the drive
189; Returns:
[99]190; Nothing
[3]191; Corrupts registers:
192; AX, BX, DX
193;--------------------------------------------------------------------
[99]194.StoreEBIOSSupport:
195 test BYTE [cs:ROMVARS.wFlags], FLG_ROMVARS_FULLMODE
196 jz SHORT .StoreDriveNumberAndUpdateDriveCount ; No EBIOS support since small DPTs needed
197
[3]198 mov bl, [di+DPT.bFlags]
[99]199 and bx, BYTE MASK_DPT_ADDR ; Addressing mode
200 jmp [cs:bx+.rgwAddrJmp] ; Jump to handle addressing mode
[3]201.rgwAddrJmp:
[99]202 dw .StoreDriveNumberAndUpdateDriveCount ; ADDR_DPT_LCHS
203 dw .StoreDriveNumberAndUpdateDriveCount ; ADDR_DPT_PCHS
204 dw .SupportForLBA28 ; ADDR_DPT_LBA28
205 dw .SupportForLBA48 ; ADDR_DPT_LBA48
206
[3]207.SupportForLBA28:
208 sub BYTE [di+DPT.bSize], 2 ; Only 4 bytes for sector count
209.SupportForLBA48:
210 add BYTE [di+DPT.bSize], EBDPT_size - DPT_size
211 or BYTE [di+DPT.bFlags], FLG_DPT_EBIOS
212 call AtaID_GetTotalSectorCount
213 mov [di+EBDPT.twCapacity], ax
214 mov [di+EBDPT.twCapacity+2], dx
215 mov [di+EBDPT.twCapacity+4], bx
[99]216 ; Fall to .StoreDriveNumberAndUpdateDriveCount
[3]217
218;--------------------------------------------------------------------
[99]219; .StoreDriveNumberAndUpdateDriveCount
[3]220; Parameters:
221; DS:DI: Ptr to Disk Parameter Table
222; ES:SI: Ptr to 512-byte ATA information read from the drive
223; ES: BDA Segment
224; Returns:
225; DL: Drive number for new drive
226; CF: Cleared if DPT parameters stored successfully
227; Set if any error
228; Corrupts registers:
229; Nothing
230;--------------------------------------------------------------------
[99]231.StoreDriveNumberAndUpdateDriveCount:
[3]232 ; Make sure that more drives can be accepted
233 mov dl, [es:BDA.bHDCount] ; Load number of hard disks
234 test dl, 80h ; Hard disks at maximum?
235 stc ; Assume error
236 jnz SHORT .TooManyDrives ; If so, return
237
238 ; Store drive number to DPT
239 or dl, 80h ; Set bit 7 since hard disk
240 mov [di+DPT.bDrvNum], dl ; Store drive number
241
242 ; Update BDA and RAMVARS
243 inc BYTE [es:BDA.bHDCount] ; Increment drive count to BDA
244 call RamVars_IncrementHardDiskCount
245 clc
246.TooManyDrives:
247 ret
Note: See TracBrowser for help on using the repository browser.