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

Last change on this file since 128 was 128, checked in by krille_n_@…, 13 years ago

Changes to the XTIDE Universal BIOS:

  • Size optimizations in various files.
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
[128]234    test    dl, dl                  ; Hard disks at maximum?
[3]235    stc                             ; Assume error
[128]236    js      SHORT .TooManyDrives    ;  If so, return
[3]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.