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

Last change on this file since 38 was 3, checked in by Tomi Tilli, 15 years ago
File size: 12.2 KB
Line 
1; File name : CreateDPT.asm
2; Project name : IDE BIOS
3; Created date : 12.3.2010
4; Last update : 26.4.2010
5; Author : Tomi Tilli
6; Description : Functions for creating Disk Parameter Table.
7
8; Section containing code
9SECTION .text
10
11;--------------------------------------------------------------------
12; Creates new Disk Parameter Table for detected hard disk.
13; Drive is then fully accessible using any BIOS function.
14;
15; CreateDPT_FromAtaInformation
16; Parameters:
17; BH: Drive Select byte for Drive and Head Register
18; ES:SI: Ptr to 512-byte ATA information read from the drive
19; CS:BP: Ptr to IDEVARS for the controller
20; DS: RAMVARS segment
21; ES: BDA Segment
22; Returns:
23; DL: Drive number for new drive
24; DS:DI: Ptr to Disk Parameter Table (if succesfull)
25; CF: Cleared if DPT created successfully
26; Set if any error
27; Corrupts registers:
28; AX, CX, BX, DH
29;--------------------------------------------------------------------
30ALIGN JUMP_ALIGN
31CreateDPT_FromAtaInformation:
32 call FindDPT_ForNewDrive ; Get new DPT to DS:DI
33 call CreateDPT_Initialize
34 call CreateDPT_StoreDriveControlByte
35 call CreateDPT_StorePCHS
36 call CreateDPT_StoreLCHS
37 call CreateDPT_StoreAddressing
38 call CreateDPT_StoreBlockMode
39 call CreateDPT_StoreEBIOSSupport
40 jmp CreateDPT_StoreDriveNumberAndUpdateDriveCount
41
42
43;--------------------------------------------------------------------
44; Initializes empty DPT by storing initial values that are not
45; read from ATA information.
46;
47; CreateDPT_Initialize
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:
53; CF: Cleared if DPT parameters stored successfully
54; Set if any error
55; Corrupts registers:
56; Nothing
57;--------------------------------------------------------------------
58ALIGN JUMP_ALIGN
59CreateDPT_Initialize:
60 xor ax, ax ; Clear AX and CF
61 mov BYTE [di+DPT.bSize], DPT_size
62 mov BYTE [di+DPT.bDrvNum], al
63 mov BYTE [di+DPT.bFlags], al
64 mov BYTE [di+DPT.bReset], MASK_RESET_ALL
65 mov WORD [di+DPT.bIdeOff], bp
66 mov BYTE [di+DPT.bDrvSel], bh
67 ret
68
69
70;--------------------------------------------------------------------
71; Stores Drive Control Byte for Device Control Register.
72;
73; CreateDPT_StoreDriveControlByte
74; Parameters:
75; BH: Drive Select byte for Drive and Head Register
76; DS:DI: Ptr to Disk Parameter Table
77; ES:SI: Ptr to 512-byte ATA information read from the drive
78; CS:BP: Ptr to IDEVARS for the controller
79; Returns:
80; CF: Cleared if DPT parameters stored successfully
81; Set if any error
82; Corrupts registers:
83; AX
84;--------------------------------------------------------------------
85ALIGN JUMP_ALIGN
86CreateDPT_StoreDriveControlByte:
87 xor ax, ax ; Zero AX
88 cmp BYTE [cs:bp+IDEVARS.bIRQ], 0 ; Interrupts enabled?
89 jne SHORT .CheckHeadCount
90 or al, FLG_IDE_CTRL_nIEN ; Disable interrupts
91ALIGN JUMP_ALIGN
92.CheckHeadCount:
93 cmp BYTE [es:si+ATA1.wHeadCnt], 8 ; 1...8 heads?
94 jbe SHORT .StoreDriveControlByte
95 or al, FLG_IDE_CTRL_O8H ; Over 8 heads (pre-ATA)
96ALIGN JUMP_ALIGN
97.StoreDriveControlByte:
98 mov [di+DPT.bDrvCtrl], al
99 clc
100 ret
101
102
103;--------------------------------------------------------------------
104; Stores P-CHS values from ATA information or user specified values to DPT.
105;
106; CreateDPT_StorePCHS
107; Parameters:
108; BH: Drive Select byte for Drive and Head Register
109; DS:DI: Ptr to Disk Parameter Table
110; ES:SI: Ptr to 512-byte ATA information read from the drive
111; CS:BP: Ptr to IDEVARS for the controller
112; Returns:
113; CF: Cleared if DPT parameters stored successfully
114; Set if any error
115; Corrupts registers:
116; AX, BX
117;--------------------------------------------------------------------
118ALIGN JUMP_ALIGN
119CreateDPT_StorePCHS:
120 call CreateDPT_GetUserOrAtaPCHS
121 mov [di+DPT.wPCyls], ax
122 mov [di+DPT.bPHeads], bh
123 mov [di+DPT.bPSect], bl
124 clc
125 ret
126
127;--------------------------------------------------------------------
128; Returns user specified P-CHS or values read from ATA information.
129;
130; CreateDPT_GetUserOrAtaPCHS
131; Parameters:
132; BH: Drive Select byte for Drive and Head Register
133; DS:DI: Ptr to Disk Parameter Table
134; ES:SI: Ptr to 512-byte ATA information read from the drive
135; CS:BP: Ptr to IDEVARS for the controller
136; Returns:
137; AX: Number of P-CHS cylinders
138; BL: Number of P-CHS sectors per track
139; BH: Number of P-CHS heads
140; Corrupts registers:
141; Nothing
142;--------------------------------------------------------------------
143ALIGN JUMP_ALIGN
144CreateDPT_GetUserOrAtaPCHS:
145 mov ax, FLG_DRVPARAMS_USERCHS ; User specified CHS?
146 call AccessDPT_TestIdeVarsFlagsForMasterOrSlaveDrive
147 jnz SHORT CreateDPT_GetUserSpecifiedPCHS
148 jmp AtaID_GetPCHS
149
150;--------------------------------------------------------------------
151; Returns user specified P-CHS values from ROMVARS.
152;
153; CreateDPT_GetUserSpecifiedPCHS
154; Parameters:
155; DS:DI: Ptr to Disk Parameter Table
156; CS:BP: Ptr to IDEVARS for the controller
157; Returns:
158; AX: Number of user specified P-CHS cylinders
159; BL: Number of user specified P-CHS sectors per track
160; BH: Number of user specified P-CHS heads
161; Corrupts registers:
162; Nothing
163;--------------------------------------------------------------------
164ALIGN JUMP_ALIGN
165CreateDPT_GetUserSpecifiedPCHS:
166 call AccessDPT_GetPointerToDRVPARAMStoCSBX
167 mov ax, [cs:bx+DRVPARAMS.wCylinders]
168 mov bx, [cs:bx+DRVPARAMS.wSectAndHeads]
169 or BYTE [di+DPT.bFlags], FLG_DPT_USERCHS
170 ret
171
172
173;--------------------------------------------------------------------
174; Stores L-CHS values by converting from P-CHS values if necessary.
175;
176; CreateDPT_StoreLCHS
177; Parameters:
178; DS:DI: Ptr to Disk Parameter Table
179; ES:SI: Ptr to 512-byte ATA information read from the drive
180; Returns:
181; CF: Cleared if DPT parameters stored successfully
182; Set if any error
183; Corrupts registers:
184; AX, CX, DX
185;--------------------------------------------------------------------
186ALIGN JUMP_ALIGN
187CreateDPT_StoreLCHS:
188 mov cx, [di+DPT.wPCyls] ; P-CHS Cylinders (1...16383)
189 eMOVZX dx, BYTE [di+DPT.bPHeads] ; P-CHS Heads (1...16)
190 call CreateDPT_ShiftPCHtoLCH
191 test dh, dh ; 256 heads?
192 jz SHORT .StoreToDPT ; If less, no correction needed
193 dec dx ; Limit to 255 heads since DOS does not support 256 heads
194ALIGN JUMP_ALIGN
195.StoreToDPT:
196 mov [di+DPT.bShLtoP], al
197 mov [di+DPT.wLHeads], dx
198 clc
199 ret
200
201;--------------------------------------------------------------------
202; Returns L-CHS values from P-CHS values.
203; Sectors per track is always the same for both addressing modes.
204;
205; CreateDPT_ShiftPCHtoLCH:
206; Parameters:
207; CX: Number of P-CHS cylinders (1...16383)
208; DX: Number of P-CHS heads (1...16)
209; Returns:
210; AL: Number of bits shifted
211; CX: Number of L-CHS cylinders (1...1024)
212; DX: Number of L-CHS heads (1...256)
213; Corrupts registers:
214; Nothing
215;--------------------------------------------------------------------
216ALIGN JUMP_ALIGN
217CreateDPT_ShiftPCHtoLCH:
218 xor al, al ; Zero AL
219ALIGN JUMP_ALIGN
220.ShiftLoop:
221 cmp cx, 1024 ; Need to shift?
222 jbe SHORT .Return ; If not, return
223 inc ax ; Increment shift count
224 shr cx, 1 ; Halve cylinders
225 shl dx, 1 ; Double heads
226 jmp SHORT .ShiftLoop
227ALIGN JUMP_ALIGN
228.Return:
229 ret
230
231
232;--------------------------------------------------------------------
233; Stores addressing information (L-CHS, P-CHS, LBA28 or LBA48).
234;
235; CreateDPT_StoreAddressing
236; Parameters:
237; DS:DI: Ptr to Disk Parameter Table
238; ES:SI: Ptr to 512-byte ATA information read from the drive
239; Returns:
240; CF: Cleared if DPT parameters stored successfully
241; Set if any error
242; Corrupts registers:
243; Nothing
244;--------------------------------------------------------------------
245ALIGN JUMP_ALIGN
246CreateDPT_StoreAddressing:
247 cmp WORD [di+DPT.wPCyls], 1024 ; L-CHS possible? (no translation needed)
248 jbe SHORT .Return ; If so, nothing needs to be changed
249 test BYTE [di+DPT.bFlags], FLG_DPT_USERCHS
250 jnz SHORT .StorePCHS ; Use user defined P-CHS
251 test WORD [es:si+ATA1.wCaps], A2_wCaps_LBA
252 jz SHORT .StorePCHS ; Use P-CHS since LBA not supported
253 test WORD [es:si+ATA6.wSetSup83], A6_wSetSup83_LBA48
254 jz SHORT .StoreLBA28 ; Use LBA-28 since LBA-48 not supported
255 or BYTE [di+DPT.bFlags], ADDR_DPT_LBA48<<1
256ALIGN JUMP_ALIGN
257.StoreLBA28:
258 or BYTE [di+DPT.bFlags], ADDR_DPT_LBA28<<1
259 or BYTE [di+DPT.bDrvSel], FLG_IDE_DRVHD_LBA
260 ret
261ALIGN JUMP_ALIGN
262.StorePCHS:
263 or BYTE [di+DPT.bFlags], ADDR_DPT_PCHS<<1
264ALIGN JUMP_ALIGN
265.Return:
266 clc
267 ret
268
269
270;--------------------------------------------------------------------
271; Stores Block Mode information.
272;
273; CreateDPT_StoreBlockMode
274; Parameters:
275; DS:DI: Ptr to Disk Parameter Table
276; ES:SI: Ptr to 512-byte ATA information read from the drive
277; Returns:
278; CF: Cleared if DPT parameters stored successfully
279; Set if any error
280; Corrupts registers:
281; Nothing
282;--------------------------------------------------------------------
283ALIGN JUMP_ALIGN
284CreateDPT_StoreBlockMode:
285 mov al, 1 ; Minimum block size is 1 sector
286 mov ah, [es:si+ATA1.bBlckSize] ; Load max block size in sectors
287 mov [di+DPT.wSetAndMaxBlock], ax
288 ret
289
290
291;--------------------------------------------------------------------
292; Stores variables required by EBIOS functions.
293;
294; CreateDPT_StoreEBIOSSupport
295; Parameters:
296; DS:DI: Ptr to Disk Parameter Table
297; ES:SI: Ptr to 512-byte ATA information read from the drive
298; Returns:
299; CF: Cleared if DPT parameters stored successfully
300; Set if any error
301; Corrupts registers:
302; AX, BX, DX
303;--------------------------------------------------------------------
304ALIGN JUMP_ALIGN
305CreateDPT_StoreEBIOSSupport:
306 test BYTE [cs:ROMVARS.wFlags], FLG_ROMVARS_FULLMODE ; (clears CF)
307 jz SHORT .DoNotSupportEBIOS ; No EBIOS support since small DPTs needed
308 mov bl, [di+DPT.bFlags]
309 and bx, BYTE MASK_DPT_ADDR ; Addressing mode (clears CF)
310 jmp [cs:bx+.rgwAddrJmp] ; Jump to handle addressing mode
311ALIGN WORD_ALIGN
312.rgwAddrJmp:
313 dw .DoNotSupportEBIOS ; ADDR_DPT_LCHS
314 dw .DoNotSupportEBIOS ; ADDR_DPT_PCHS
315 dw .SupportForLBA28 ; ADDR_DPT_LBA28
316 dw .SupportForLBA48 ; ADDR_DPT_LBA48
317ALIGN JUMP_ALIGN
318.DoNotSupportEBIOS:
319 ret
320ALIGN JUMP_ALIGN
321.SupportForLBA28:
322 sub BYTE [di+DPT.bSize], 2 ; Only 4 bytes for sector count
323ALIGN JUMP_ALIGN
324.SupportForLBA48:
325 add BYTE [di+DPT.bSize], EBDPT_size - DPT_size
326 or BYTE [di+DPT.bFlags], FLG_DPT_EBIOS
327 ; Fall to CreateDPT_StoreEbiosSectorCount
328
329;--------------------------------------------------------------------
330; Stores EBIOS total sector count for LBA addressing.
331;
332; CreateDPT_StoreEbiosSectorCount
333; Parameters:
334; DS:DI: Ptr to Disk Parameter Table
335; ES:SI: Ptr to 512-byte ATA information read from the drive
336; Returns:
337; CF: Cleared if DPT parameters stored successfully
338; Set if any error
339; Corrupts registers:
340; AX, BX, DX
341;--------------------------------------------------------------------
342;ALIGN JUMP_ALIGN
343CreateDPT_StoreEbiosSectorCount:
344 call AtaID_GetTotalSectorCount
345 mov [di+EBDPT.twCapacity], ax
346 mov [di+EBDPT.twCapacity+2], dx
347 mov [di+EBDPT.twCapacity+4], bx
348 clc
349 ret
350
351
352;--------------------------------------------------------------------
353; Stores number for drive and updates drive count.
354;
355; CreateDPT_StoreDriveNumberAndUpdateDriveCount
356; Parameters:
357; DS:DI: Ptr to Disk Parameter Table
358; ES:SI: Ptr to 512-byte ATA information read from the drive
359; ES: BDA Segment
360; Returns:
361; DL: Drive number for new drive
362; CF: Cleared if DPT parameters stored successfully
363; Set if any error
364; Corrupts registers:
365; Nothing
366;--------------------------------------------------------------------
367ALIGN JUMP_ALIGN
368CreateDPT_StoreDriveNumberAndUpdateDriveCount:
369 ; Make sure that more drives can be accepted
370 mov dl, [es:BDA.bHDCount] ; Load number of hard disks
371 test dl, 80h ; Hard disks at maximum?
372 stc ; Assume error
373 jnz SHORT .TooManyDrives ; If so, return
374
375 ; Store drive number to DPT
376 or dl, 80h ; Set bit 7 since hard disk
377 mov [di+DPT.bDrvNum], dl ; Store drive number
378
379 ; Update BDA and RAMVARS
380 inc BYTE [es:BDA.bHDCount] ; Increment drive count to BDA
381 call RamVars_IncrementHardDiskCount
382 clc
383.TooManyDrives:
384 ret
Note: See TracBrowser for help on using the repository browser.