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

Last change on this file since 3 was 3, checked in by aitotat, 14 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.