Changeset 421 in xtideuniversalbios for trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs


Ignore:
Timestamp:
May 9, 2012, 7:12:53 PM (12 years ago)
Author:
aitotat@…
google:author:
aitotat@gmail.com
Message:

Changes to XTIDE Universal BIOS:

  • Addressing modes are now NORMAL, LARGE and LBA.
  • L-CHS parameters are now generated differently for drives with 8192 or less cylinders.
Location:
trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs
Files:
2 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm

    r411 r421  
    3636    mov     bx, [cs:bx+IDEVARS.wPort]
    3737    ret
    38 
    39 %endif
     38%endif  ; MODULE_ADVANCED_ATA
    4039
    4140
    4241;--------------------------------------------------------------------
    43 ; AccessDPT_GetDriveSelectByteToAL
     42; AccessDPT_GetDriveSelectByteForOldInt13hToAL
     43; AccessDPT_GetDriveSelectByteForEbiosToAL
    4444;   Parameters:
    4545;       DS:DI:  Ptr to Disk Parameter Table
     
    5050;--------------------------------------------------------------------
    5151ALIGN JUMP_ALIGN
    52 AccessDPT_GetDriveSelectByteToAL:
     52AccessDPT_GetDriveSelectByteForOldInt13hToAL:
     53    mov     al, [di+DPT.bFlagsLow]
     54    test    al, FLGL_DPT_ASSISTED_LBA
     55    jnz     SHORT GetDriveSelectByteForAssistedLBAtoAL
     56
     57    and     al, FLG_DRVNHEAD_DRV    ; Clear all but drive select bit
     58    or      al, MASK_DRVNHEAD_SET   ; Bits set to 1 for old drives
     59    ret
     60
     61%ifdef MODULE_EBIOS
     62ALIGN JUMP_ALIGN
     63AccessDPT_GetDriveSelectByteForEbiosToAL:
    5364    mov     al, [di+DPT.wFlags]
    54     and     al, FLG_DRVNHEAD_LBA | FLG_DRVNHEAD_DRV
    55     or      al, MASK_DRVNHEAD_SET   ; Bits set to 1 for old drives
     65    ; Fall to GetDriveSelectByteForAssistedLBAtoAL
     66%endif ; MODULE_EBIOS
     67
     68ALIGN JUMP_ALIGN
     69GetDriveSelectByteForAssistedLBAtoAL:
     70    and     al, FLG_DRVNHEAD_DRV    ; Master / Slave select
     71    or      al, FLG_DRVNHEAD_LBA | MASK_DRVNHEAD_SET
    5672    ret
    5773
     
    89105;       BH:     Number of L-CHS sectors per track
    90106;   Corrupts registers:
    91 ;       CX, DX
     107;       Nothing
    92108;--------------------------------------------------------------------
    93109AccessDPT_GetLCHStoAXBLBH:
    94     ; Return LBA-assisted CHS if LBA addressing used
    95     test    BYTE [di+DPT.bFlagsLow], FLG_DRVNHEAD_LBA
    96     jz      SHORT .ConvertPchsToLchs
    97 
    98     call    AccessDPT_GetLbaSectorCountToBXDXAX
    99     call    LbaAssist_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH
    100     LIMIT_LBA_CYLINDERS_IN_DXAX_TO_LCHS_CYLINDERS
    101     ret
    102 
    103 .ConvertPchsToLchs:
    104     mov     ax, [di+DPT.wPchsCylinders]
    105     mov     bx, [di+DPT.wPchsHeadsAndSectors]
    106     ; Fall to AccessDPT_ShiftPCHinAXBLtoLCH
    107 
    108 
    109 ;--------------------------------------------------------------------
    110 ; AccessDPT_ShiftPCHinAXBLtoLCH
    111 ;   Parameters:
    112 ;       AX:     P-CHS cylinders (1...16383)
    113 ;       BL:     P-CHS heads (1...16)
    114 ;   Returns:
    115 ;       AX:     Number of L-CHS cylinders (1...1024)
    116 ;       BL:     Number of L-CHS heads (1...255)
    117 ;       CX:     Number of bits shifted (4 at most)
    118 ;   Corrupts registers:
    119 ;       Nothing
    120 ;--------------------------------------------------------------------
    121 AccessDPT_ShiftPCHinAXBLtoLCH:
    122     xor     cx, cx
    123 .ShiftLoop:
    124     cmp     ax, MAX_LCHS_CYLINDERS      ; Need to shift?
    125     jbe     SHORT .Return               ;  If not, return
    126     inc     cx                          ; Increment shift count
    127     shr     ax, 1                       ; Halve cylinders
    128     shl     bl, 1                       ; Double heads
    129     jnz     SHORT .ShiftLoop            ; Falls through only on the last (4th) iteration and only if BL was 16 on entry
    130     dec     bl                          ; DOS doesn't support drives with 256 heads so we limit heads to 255
    131     ; We can save a byte here by using DEC BX if we don't care about BH
    132 .Return:
     110    mov     ax, [di+DPT.wLchsCylinders]
     111    mov     bx, [di+DPT.wLchsHeadsAndSectors]
    133112    ret
    134113
    135114
     115%ifdef MODULE_EBIOS
    136116;--------------------------------------------------------------------
    137117; AccessDPT_GetLbaSectorCountToBXDXAX
     
    148128    mov     bx, [di+DPT.twLbaSectors+4]
    149129    ret
     130%endif ; MODULE_EBIOS
    150131
    151132
     
    171152    ret
    172153
     154
    173155;--------------------------------------------------------------------
    174 ; AccessDPT_GetUnshiftedAddressModeToALZF
     156; ACCESSDPT__GET_UNSHIFTED_ADDRESS_MODE_TO_AXZF
    175157;   Parameters:
    176158;       DS:DI:  Ptr to Disk Parameter Table
    177159;   Returns:
    178 ;       AL:     Addressing Mode (L-CHS, P-CHS, LBA28, LBA48)
     160;       AX:     Addressing Mode (ADDRESSING_MODE_NORMAL, ADDRESSING_MODE_LARGE or ADDRESSING_MODE_ASSISTED_LBA)
    179161;               unshifted (still shifted where it is in bFlagsLow)
    180162;       ZF:     Set based on value in AL
    181163;   Corrupts registers:
    182 ;       AL
     164;       Nothing
    183165;--------------------------------------------------------------------
    184166;
     
    186168; is not worth it for these two instructions (4 bytes total)
    187169;
    188 %macro AccessDPT_GetUnshiftedAddressModeToALZF 0
     170%macro ACCESSDPT__GET_UNSHIFTED_ADDRESS_MODE_TO_AXZF 0
    189171    mov     al, [di+DPT.bFlagsLow]
    190     and     al, MASKL_DPT_ADDRESSING_MODE
     172    and     ax, BYTE MASKL_DPT_ADDRESSING_MODE
    191173%endmacro
  • trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AtaGeometry.asm

    r419 r421  
    11; Project name  :   XTIDE Universal BIOS
    22; Description   :   Functions for generating L-CHS parameters for
    3 ;                   LBA drives.
     3;                   drives with more than 1024 cylinders.
     4;
     5;                   These algorithms are taken from: http://www.mossywell.com/boot-sequence
     6;                   Take a look at it for more detailed information.       
    47;
    58;                   This file is shared with BIOS Drive Information Tool.
     
    2427SECTION .text
    2528
    26 ;--------------------------------------------------------------------
    27 ; LBA assist calculation:
    28 ; this is how to fit a big drive into INT13's skimpy size requirements,
    29 ; with a maximum of 8.4G available.
    30 ;
     29%ifdef MODULE_EBIOS
     30;--------------------------------------------------------------------
     31; AtaGeometry_GetLbaSectorCountToBXDXAXfromAtaInfoInESSI
     32;   Parameters:
     33;       ES:SI:  Ptr to 512-byte ATA information read from the drive
     34;   Returns:
     35;       BX:DX:AX:   48-bit sector count
     36;       CL:         FLGL_DPT_LBA48 if LBA48 supported, zero otherwise
     37;   Corrupts registers:
     38;       Nothing
     39;--------------------------------------------------------------------
     40AtaGeometry_GetLbaSectorCountToBXDXAXfromAtaInfoInESSI:
     41    mov     bx, Registers_ExchangeDSSIwithESDI
     42    call    bx  ; ATA info now in DS:DI
     43    push    bx  ; We will return via Registers_ExchangeDSSIwithESDI
     44
     45    ; Check if LBA48 supported
     46    test    BYTE [di+ATA6.wSetSup83+1], A6_wSetSup83_LBA48>>8
     47    jz      SHORT .GetLba28SectorCount
     48
     49    ; Get LBA48 sector count
     50    mov     cl, FLGL_DPT_LBA48
     51    mov     ax, [di+ATA6.qwLBACnt]
     52    mov     dx, [di+ATA6.qwLBACnt+2]
     53    mov     bx, [di+ATA6.qwLBACnt+4]
     54    ret
     55
     56.GetLba28SectorCount:
     57    xor     cl, cl
     58    xor     bx, bx
     59    mov     ax, [di+ATA1.dwLBACnt]
     60    mov     dx, [di+ATA1.dwLBACnt+2]
     61    ret
     62%endif  ; MODULE_EBIOS
     63
     64
     65;--------------------------------------------------------------------
     66; AtaGeometry_GetLCHStoAXBLBHfromAtaInfoInESSI:
     67;   Parameters:
     68;       ES:SI:  Ptr to 512-byte ATA information read from the drive
     69;   Returns:
     70;       AX:     Number of L-CHS cylinders (1...1027, yes 1027)
     71;       BL:     Number of L-CHS heads (1...255)
     72;       BH:     Number of L-CHS sectors per track (1...63)
     73;       CX:     Number of bits shifted (0...3)
     74;       DL:     Addressing mode
     75;   Corrupts registers:
     76;       DH
     77;--------------------------------------------------------------------
     78AtaGeometry_GetLCHStoAXBLBHfromAtaInfoInESSI:
     79    call    AtaGeometry_GetPCHStoAXBLBHfromAtaInfoInESSI
     80    ; Fall to AtaGeometry_GetLCHStoAXBLBHfromPCHSinAXBLBH
     81
     82AtaGeometry_GetLCHStoAXBLBHfromPCHSinAXBLBH:
     83    ; Generate L-CHS using simple bit shift algorithm (ECHS) if
     84    ; 8192 or less cylinders.
     85    cmp     ax, 8192
     86    jbe     SHORT ConvertPCHfromAXBXtoEnhancedCHinAXBX
     87
     88    ; We have 8193 or more cylinders so two algorithms are available:
     89    ; Revised ECHS or Assisted LBA. The Assisted LBA provides larger
     90    ; capacity but requires LBA support from drive (drives this large
     91    ; always support LBA but we may have intentionally cleared the LBA
     92    ; bit to force CHS addressing).
     93    test    BYTE [es:si+ATA1.wCaps+1], A1_wCaps_LBA>>8
     94    jz      SHORT ConvertPCHfromAXBXtoRevisedEnhancedCHinAXBX
     95
     96    ; Drive supports LBA
     97    call    AtaGeometry_GetSectorCountToDXAXfromCHSinAXBLBH
     98    call    ConvertChsSectorCountFromDXAXtoLbaAssistedLCHSinAXBLBH
     99    xor     cx, cx      ; No bits to shift
     100    mov     dl, ADDRESSING_MODE_ASSISTED_LBA
     101    ret
     102
     103
     104;--------------------------------------------------------------------
     105; AtaGeometry_GetPCHStoAXBLBHfromAtaInfoInESSI
     106;   Parameters:
     107;       ES:SI:  Ptr to 512-byte ATA information read from the drive
     108;   Returns:
     109;       AX:     Number of P-CHS cylinders (1...16383)
     110;       BL:     Number of P-CHS heads (1...16)
     111;       BH:     Number of P-CHS sectors per track (1...63)
     112;   Corrupts registers:
     113;       Nothing
     114;--------------------------------------------------------------------
     115AtaGeometry_GetPCHStoAXBLBHfromAtaInfoInESSI:
     116    mov     ax, [es:si+ATA1.wCylCnt]    ; Cylinders (1...16383)
     117    mov     bl, [es:si+ATA1.wHeadCnt]   ; Heads (1...16)
     118    mov     bh, [es:si+ATA1.wSPT]       ; Sectors per Track (1...63)
     119    ret
     120
     121
     122;--------------------------------------------------------------------
     123; AtaGeometry_GetSectorCountToDXAXfromCHSinAXBLBH
     124;   Parameters:
     125;       ES:SI:  Ptr to 512-byte ATA information read from the drive
     126;       AX:     Number of cylinders (1...16383)
     127;       BL:     Number of heads (1...255)
     128;       BH:     Number of sectors per track (1...63)
     129;   Returns:
     130;       DX:AX:  Total number of CHS addressable sectors
     131;   Corrupts registers:
     132;       BX
     133;--------------------------------------------------------------------
     134AtaGeometry_GetSectorCountToDXAXfromCHSinAXBLBH:
     135    xchg    ax, bx
     136    mul     ah          ; AX = Heads * Sectors per track
     137    mul     bx
     138    ret
     139
     140
     141;--------------------------------------------------------------------
     142; Revised Enhanced CHS calculation (Revised ECHS)
     143;
     144; This algorithm translates P-CHS sector count to L-CHS sector count
     145; with bit shift algorithm. Since 256 heads are not allowed
     146; (DOS limit), this algorithm makes translations so that maximum of
     147; 240 L-CHS heads can be used. This makes the maximum addressable capacity
     148; to 7,927,234,560 bytes ~ 7.38 GiB. LBA addressing needs to be used to
     149; get more capacity.
     150;
     151; L-CHS parameters generated here require the drive to use CHS addressing.
     152;
     153; Here is the algorithm:
     154; If cylinders > 8192 and heads = 16
     155;  Heads = 15
     156;  Cylinders = cylinders * 16 / 15 (losing the fraction component)
     157;  Do a standard ECHS translation
     158;
     159; ConvertPCHfromAXBXtoRevisedEnhancedCHinAXBX:
     160;   Parameters:
     161;       AX:     Number of P-CHS cylinders (8193...16383)
     162;       BL:     Number of P-CHS heads (1...16)
     163;   Returns:
     164;       AX:     Number of L-CHS cylinders (?...1024)
     165;       BL:     Number of L-CHS heads (?...240)
     166;       CX:     Number of bits shifted (0...3)
     167;       DL:     ADDRESSING_MODE_NORMAL or ADDRESSING_MODE_LARGE
     168;   Corrupts registers:
     169;       Nothing
     170;--------------------------------------------------------------------
     171ConvertPCHfromAXBXtoRevisedEnhancedCHinAXBX:
     172    cmp     bl, 16  ; Drives with 8193 or more cylinders can report 15 heads
     173    jb      SHORT ConvertPCHfromAXBXtoEnhancedCHinAXBX
     174
     175    eMOVZX  cx, bl  ; CX = 16
     176    dec     bx      ; Heads = 15
     177    mul     cx      ; DX:AX = Cylinders * 16
     178    dec     cx      ; CX = 15
     179    div     cx      ; AX = (Cylinders * 16) / 15
     180    ; Fall to ConvertPCHfromAXBXtoEnhancedCHinAXBX
     181
     182
     183;--------------------------------------------------------------------
     184; Enhanced CHS calculation (ECHS)
     185;
     186; This algorithm translates P-CHS sector count to L-CHS sector count
     187; with simple bit shift algorithm. Since 256 heads are not allowed
     188; (DOS limit), this algorithm require that there are at most 8192
     189; P-CHS cylinders. This makes the maximum addressable capacity
     190; to 4,227,858,432 bytes ~ 3.94 GiB. Use Revised ECHS or Assisted LBA
     191; algorithms if there are more than 8192 P-CHS cylinders.
     192;
     193; L-CHS parameters generated here require the drive to use CHS addressing.
     194;
     195; Here is the algorithm:
     196;  Multiplier = 1
     197;  Cylinder = Cylinder - 1
     198;  Is Cylinder < 1024? If not:
     199;  Do a right bitwise rotation on the cylinder (i.e., divide by 2)
     200;  Do a left bitwise rotation on the multiplier (i.e., multiply by 2)
     201;  Use the multiplier on the Cylinder and Head values to obtain the translated values.
     202;
     203; ConvertPCHfromAXBXtoEnhancedCHinAXBX:
     204;   Parameters:
     205;       AX:     Number of P-CHS cylinders (1...8192)
     206;       BL:     Number of P-CHS heads (1...16)
     207;   Returns:
     208;       AX:     Number of L-CHS cylinders (?...1024)
     209;       BL:     Number of L-CHS heads (?...128)
     210;       CX:     Number of bits shifted (0...3)
     211;       DL:     ADDRESSING_MODE_NORMAL or ADDRESSING_MODE_LARGE
     212;   Corrupts registers:
     213;       Nothing
     214;--------------------------------------------------------------------
     215ConvertPCHfromAXBXtoEnhancedCHinAXBX:
     216    xor     cx, cx      ; No bits to shift initially
     217    xor     dl, dl      ; Assume ADDRESSING_MODE_NORMAL
     218.ShiftIfMoreThan1024Cylinder:
     219    cmp     ax, MAX_LCHS_CYLINDERS
     220    jbe     SHORT ReturnLCHSinAXBLBH
     221    shr     ax, 1
     222    shl     bl, 1
     223    inc     cx          ; Increment bit shift count
     224    mov     dl, ADDRESSING_MODE_LARGE
     225    jmp     SHORT .ShiftIfMoreThan1024Cylinder
     226
     227
     228;--------------------------------------------------------------------
     229; LBA assist calculation (or Assisted LBA)
     230;
     231; This algorithm translates P-CHS sector count up to largest possible
     232; L-CHS sector count (1024, 255, 63). Note that INT 13h interface allows
     233; 256 heads but DOS supports up to 255 head. That is why BIOSes never
     234; use 256 heads.
     235;
     236; L-CHS parameters generated here require the drive to use LBA addressing.
     237;
     238; Here is the algorithm:
    31239; If cylinders > 8192
    32 ;  Variable CH = Total Sectors / 63
    33 ;  Divide (CH – 1) by 1024 (as an assembler bitwise right shift) and add 1
     240;  Variable CH = Total CHS Sectors / 63
     241;  Divide (CH – 1) by 1024 and add 1
    34242;  Round the result up to the nearest of 16, 32, 64, 128 and 255. This is the value to be used for the number of heads.
    35243;  Divide CH by the number of heads. This is the value to be used for the number of cylinders.
    36244;
    37 ; There's a wealth of information at: http://www.mossywell.com/boot-sequence
    38 ; they show a slightly different approach to LBA assist calulations, but
    39 ; the method here provides compatibility with phoenix BIOS.
    40 ;
    41 ; LbaAssist_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH:
    42 ;   Parameters:
    43 ;       BX:DX:AX:   Total number of sectors
    44 ;   Returns:
    45 ;       DX:AX:  Number of cylinders
     245; ConvertChsSectorCountFromDXAXtoLbaAssistedLCHSinAXBLBH:
     246;   Parameters:
     247;       DX:AX:  Total number of P-CHS sectors for CHS addressing
     248;               (max = 16383 * 16 * 63 = 16,514,064)
     249;   Returns:
     250;       AX:     Number of cylinders (?...1027)
     251;       BL:     Number of heads (16, 32, 64, 128 or 255)
    46252;       BH:     Number of sectors per track (always 63)
    47 ;       BL:     Number of heads (16, 32, 64, 128 or 255)
    48 ;   Corrupts registers:
    49 ;       CX
    50 ;--------------------------------------------------------------------
    51 LbaAssist_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH:
    52     push    bp
     253;   Corrupts registers:
     254;       CX, DX
     255;--------------------------------------------------------------------
     256ConvertChsSectorCountFromDXAXtoLbaAssistedLCHSinAXBLBH:
     257    ; Value CH = Total sector count / 63
     258    ; Max = 16,514,064 / 63 = 262128
     259    mov     cx, LBA_ASSIST_SPT          ; CX = 63
     260    call    Math_DivDXAXbyCX
     261    push    dx
     262    push    ax                          ; Value CH stored for later use
     263
     264    ; BX:DX:AX = Value CH - 1
     265    ; Max = 262128 - 1 = 262127
     266    xor     bx, bx
     267    sub     ax, BYTE 1
     268    sbb     dx, bx
     269
     270    ; AX = Number of heads = ((Value CH - 1) / 1024) + 1
     271    ; Max = (262127 / 1024) + 1 = 256
    53272    push    si
    54 
    55     ; Value CH = Total sector count / 63
    56     xor     cx, cx
    57     push    cx                          ; Push zero for bits 48...63
    58     push    bx
    59     push    dx
    60     push    ax                          ; 64-bit sector count now in stack
    61     mov     cl, LBA_ASSIST_SPT
    62     mov     bp, sp                      ; SS:BP now points sector count
    63     call    Math_DivQWatSSBPbyCX        ; Temporary value A now in stack
    64 
    65     ; BX:DX:AX = Value CH - 1
    66     mov     ax, [bp]
    67     mov     dx, [bp+2]
    68     mov     bx, [bp+4]
    69     sub     ax, BYTE 1                  ; Subtract 1
    70     sbb     dx, BYTE 0
    71     sbb     bx, BYTE 0
    72 
    73     ; DX:AX = Number of heads = ((Value CH - 1) / 1024) + 1
    74273    call    Size_DivideSizeInBXDXAXby1024andIncrementMagnitudeInCX
    75     add     ax, BYTE 1                  ; Add 1
    76     adc     dx, bx                      ; BX = 0
     274    pop     si
     275    inc     ax                          ; + 1
    77276
    78277    ; Heads must be 16, 32, 64, 128 or 255 (round up to the nearest)
    79     test    dx, dx                      ; 65536 or more heads?
    80     jnz     SHORT .LimitHeadsTo255
     278    ; Max = 255
    81279    mov     cx, 16                      ; Min number of heads
    82280.CompareNextValidNumberOfHeads:
     
    85283    shl     cx, 1                       ; Double number of heads
    86284    test    ch, ch                      ; Reached 256 heads?
    87     jnz     SHORT .CompareNextValidNumberOfHeads
    88 .LimitHeadsTo255:
    89     mov     cx, 255
     285    jz      SHORT .CompareNextValidNumberOfHeads
     286    dec     cx                          ;  If so, limit heads to 255
    90287.NumberOfHeadsNowInCX:
    91288    mov     bx, cx                      ; Number of heads are returned in BL
     
    93290
    94291    ; DX:AX = Number of cylinders = Value CH (without - 1) / number of heads
    95     call    Math_DivQWatSSBPbyCX
    96     mov     ax, [bp]
    97     mov     dx, [bp+2]                  ; Cylinders now in DX:AX
    98 
    99     ; Return LBA assisted CHS
    100     add     sp, BYTE 8                  ; Clean stack
    101     pop     si
    102     pop     bp
    103     ret
     292    ; Max = 262128 / 255 = 1027
     293    pop     ax
     294    pop     dx                          ; Value CH back to DX:AX
     295    div     cx
     296
     297    ; Return L-CHS
     298ReturnLCHSinAXBLBH:
     299    ret
  • trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm

    r411 r421  
    3333;       ES:     BDA Segment
    3434;   Returns:
    35 ;       DL:     Drive number for new drive
    3635;       DS:DI:  Ptr to Disk Parameter Table (if successful)
    3736;       CF:     Cleared if DPT created successfully
     
    8180%endif
    8281    mov     [di+DPT.wFlags], ax
    83     ; Fall to .StoreAddressing
    84 
    85 ;--------------------------------------------------------------------
    86 ; .StoreAddressing
     82    ; Fall to .StoreCHSparametersAndAddressingMode
     83
     84;--------------------------------------------------------------------
     85; .StoreCHSparametersAndAddressingMode
    8786;   Parameters:
    8887;       DS:DI:  Ptr to Disk Parameter Table
     
    9493;       AX, BX, CX, DX
    9594;--------------------------------------------------------------------
    96 .StoreAddressing:
     95.StoreCHSparametersAndAddressingMode:
    9796    ; Check if CHS defined in ROMVARS
    9897    call    AccessDPT_GetPointerToDRVPARAMStoCSBX
    99     test    byte [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERCHS    ; User specified CHS?
    100     jnz     SHORT .StoreUserDefinedPCHS
    101 
     98    test    byte [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERCHS    ; User specified P-CHS?
     99    jz      SHORT .AutodetectPCHSvalues
     100
     101    ; Use DRVPARAMS P-CHS values instead of autodetected
     102    mov     ax, [cs:bx+DRVPARAMS.wCylinders]
     103    mov     bx, [cs:bx+DRVPARAMS.wHeadsAndSectors]
     104    call    AtaGeometry_GetLCHStoAXBLBHfromPCHSinAXBLBH
     105    jmp     SHORT .StoreLCHStoDPT
     106
     107    ; Get L-CHS parameters and addressing mode
     108.AutodetectPCHSvalues:
     109    call    AtaGeometry_GetLCHStoAXBLBHfromAtaInfoInESSI
     110
     111.StoreLCHStoDPT:
     112    eSHL_IM dl, ADDRESSING_MODE_FIELD_POSITION
     113    or      cl, dl
     114    or      [di+DPT.bFlagsLow], cl      ; Shift count and addressing mode
     115    mov     [di+DPT.wLchsCylinders], ax
     116    mov     [di+DPT.wLchsHeadsAndSectors], bx
     117
     118    ; Store P-CHS to DPT
     119    call    AtaGeometry_GetPCHStoAXBLBHfromAtaInfoInESSI
     120    mov     [di+DPT.bPchsHeads], bl
     121%ifdef MODULE_EBIOS
     122    mov     [di+DPT.wPchsCylinders], ax
     123    mov     [di+DPT.bPchsSectorsPerTrack], bh
     124    ; Fall to .StoreNumberOfLbaSectors
     125
     126;--------------------------------------------------------------------
     127; .StoreNumberOfLbaSectors
     128;   Parameters:
     129;       DS:DI:  Ptr to Disk Parameter Table
     130;       ES:SI:  Ptr to 512-byte ATA information read from the drive
     131;       CS:BP:  Ptr to IDEVARS for the controller
     132;   Returns:
     133;       Nothing
     134;   Corrupts registers:
     135;       AX, BX, CX, DX
     136;--------------------------------------------------------------------
    102137    ; Check if LBA supported
    103     call    AtaID_GetPCHStoAXBLBHfromAtaInfoInESSI
    104138    test    BYTE [es:si+ATA1.wCaps+1], A1_wCaps_LBA>>8
    105     jz      SHORT .StoreCHSfromAXBHBL       ; Small old drive with CHS addressing only
    106 
    107     ; Store LBA 28/48 addressing and total sector count
    108     call    AtaID_GetTotalSectorCountToBXDXAXfromAtaInfoInESSI
    109     call    StoreLbaAddressingAndTotalSectorCountFromBXDXAX
    110 
    111     ; Replace sector count with user defined if necessary
     139    jz      SHORT .NoLbaSupportedSoNoEBIOS
     140
     141    ; Store LBA 28/48 total sector count
     142    call    AtaGeometry_GetLbaSectorCountToBXDXAXfromAtaInfoInESSI
     143    call    StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX
     144
     145    ; Load user defined LBA
    112146    call    AccessDPT_GetPointerToDRVPARAMStoCSBX
    113147    test    BYTE [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERLBA
     
    126160    jae     SHORT .KeepTotalSectorsFromAtaID
    127161.StoreUserDefinedSectorCountToDPT:
    128     call    StoreLbaAddressingAndTotalSectorCountFromBXDXAX
    129 
    130     ; Calculate L-CHS for old INT 13h
     162    xor     cx, cx      ; Always LBA28 for user defined values
     163    call    StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX
     164
    131165.KeepTotalSectorsFromAtaID:
    132     mov     bx, [di+DPT.twLbaSectors+4]     ; Restore BX
    133     call    LbaAssist_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH
    134     mov     [di+DPT.bLbaHeads], bl
    135     jmp     SHORT .StoreBlockMode
    136 
    137 ;--------------------------------------------------------------------
    138 ; .StoreUserDefinedPCHS
    139 ;   Parameters:
    140 ;       DS:DI:  Ptr to Disk Parameter Table
    141 ;       ES:SI:  Ptr to 512-byte ATA information read from the drive
    142 ;       CS:BP:  Ptr to IDEVARS for the controller
    143 ;   Returns:
    144 ;       AX:     Number of P-CHS cylinders
    145 ;       BH:     Number of P-CHS sectors per track
    146 ;       BL:     Number of P-CHS heads
    147 ;   Corrupts registers:
    148 ;       Nothing
    149 ;--------------------------------------------------------------------
    150 .StoreUserDefinedPCHS:
    151     call    AccessDPT_GetPointerToDRVPARAMStoCSBX
    152     mov     ax, [cs:bx+DRVPARAMS.wCylinders]
    153     mov     bx, [cs:bx+DRVPARAMS.wHeadsAndSectors]
    154     ; Fall to .StoreCHSfromAXBHBL
    155 
    156 ;--------------------------------------------------------------------
    157 ; .StoreCHSfromAXBHBL
    158 ;   Parameters:
    159 ;       AX:     Number of P-CHS cylinders
    160 ;       BH:     Number of P-CHS sectors per track
    161 ;       BL:     Number of P-CHS heads
    162 ;       DS:DI:  Ptr to Disk Parameter Table
    163 ;       ES:SI:  Ptr to 512-byte ATA information read from the drive
    164 ;       CS:BP:  Ptr to IDEVARS for the controller
    165 ;   Returns:
    166 ;       AX:     Number of P-CHS cylinders
    167 ;       BH:     Number of P-CHS sectors per track
    168 ;       BL:     Number of P-CHS heads
    169 ;   Corrupts registers:
    170 ;       CX
    171 ;--------------------------------------------------------------------
    172 .StoreCHSfromAXBHBL:
    173     push    ax
    174     push    bx
    175     call    AccessDPT_ShiftPCHinAXBLtoLCH   ; Get number of bits to shift
    176     pop     bx
    177     pop     ax
    178     jcxz    .StorePCHSfromAXDX              ; Small drive so use L-CHS addressing
    179 
    180     ; Store P-CHS addressing mode and number of bits to shift in L-CHS to P-CHS translation
    181     or      cl, ADDRESSING_MODE_PCHS<<ADDRESSING_MODE_FIELD_POSITION
    182     or      [di+DPT.bFlagsLow], cl
    183     ; Fall to .StoreChsFromAXBLBH
    184 
    185 ;--------------------------------------------------------------------
    186 ; .StoreChsFromAXBLBH
    187 ;   Parameters:
    188 ;       AX:     Number of P-CHS cylinders
    189 ;       BH:     Number of P-CHS sectors per track
    190 ;       BL:     Number of P-CHS heads
    191 ;       DS:DI:  Ptr to Disk Parameter Table
    192 ;       ES:SI:  Ptr to 512-byte ATA information read from the drive
    193 ;       CS:BP:  Ptr to IDEVARS for the controller
    194 ;   Returns:
    195 ;       Nothing
    196 ;   Corrupts registers:
    197 ;       Nothing
    198 ;--------------------------------------------------------------------
    199 .StorePCHSfromAXDX:
    200     mov     [di+DPT.wPchsCylinders], ax
    201     mov     [di+DPT.wPchsHeadsAndSectors], bx
     166.NoLbaSupportedSoNoEBIOS:
     167%endif ; MODULE_EBIOS
    202168    ; Fall to .StoreBlockMode
    203169
     
    268234
    269235
    270 ;--------------------------------------------------------------------
    271 ; StoreLbaAddressingAndTotalSectorCountFromBXDXAX
     236%ifdef MODULE_EBIOS
     237;--------------------------------------------------------------------
     238; StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX
    272239;   Parameters:
    273240;       BX:DX:AX:   Total Sector Count
     241;       CL:         FLGL_DPT_LBA48 if LBA48 supported
    274242;       DS:DI:      Ptr to Disk Parameter Table
    275243;   Returns:
    276244;       Nothing
    277245;   Corrupts registers:
    278 ;       CX
    279 ;--------------------------------------------------------------------
    280 StoreLbaAddressingAndTotalSectorCountFromBXDXAX:
     246;       CL
     247;--------------------------------------------------------------------
     248StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX:
     249    or      cl, FLGL_DPT_LBA_AND_EBIOS_SUPPORTED
     250    and     BYTE [di+DPT.bFlagsLow], ~FLGL_DPT_LBA48
     251    or      [di+DPT.bFlagsLow], cl
    281252    mov     [di+DPT.twLbaSectors], ax
    282253    mov     [di+DPT.twLbaSectors+2], dx
    283254    mov     [di+DPT.twLbaSectors+4], bx
    284 
    285 %ifdef MODULE_EBIOS
    286     and     BYTE [di+DPT.bFlagsLow], ~MASKL_DPT_ADDRESSING_MODE
    287     test    bx, bx
    288     jnz     SHORT .SetLba48AddressingToDPT  ; Must be LBA48
    289 
    290     ; Drives can report at most 0FFF FFFFh LBA28 sectors according to ATA specification.
    291     ; That is (2^28)-1 so we can simply check if DH is zero or not.
    292     test    dh, dh
    293     jz      SHORT .SetLba28AddressingToDPT
    294 .SetLba48AddressingToDPT:
    295     or      BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA48<<ADDRESSING_MODE_FIELD_POSITION
    296 .SetLba28AddressingToDPT:
    297 %endif
    298     or      BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA28<<ADDRESSING_MODE_FIELD_POSITION
    299255    ret
     256%endif ; MODULE_EBIOS
Note: See TracChangeset for help on using the changeset viewer.