Changeset 421 in xtideuniversalbios for trunk/XTIDE_Universal_BIOS/Src


Ignore:
Timestamp:
May 9, 2012, 7:12:53 PM (13 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
Files:
17 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm

    r411 r421  
    7979    test    bh, FLG_DRVNHEAD_DRV
    8080    jnz     SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
    81     mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_BSY)
     81    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_DRDY)
    8282    call    IdeWait_PollStatusFlagInBLwithTimeoutInBH
    8383.SkipLongWaitSinceDriveIsNotPrimaryMaster:
     
    195195ALIGN JUMP_ALIGN
    196196IdeCommand_SelectDrive:
     197%if 0
    197198    ; Wait until neither Master or Slave Drive is busy
    198199    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_BSY, FLG_STATUS_BSY)
     
    200201    eCMOVE  bh, TIMEOUT_IDENTIFY_DEVICE
    201202    call    IdeWait_PollStatusFlagInBLwithTimeoutInBH
     203%endif
    202204
    203205    ; Select Master or Slave Drive
  • trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm

    r419 r421  
    119119    jc      SHORT ReturnWithTransferErrorInAH
    120120
    121     ; All rectors succesfully transferred
     121    ; All sectors succesfully transferred
    122122    add     cx, [bp+PIOVARS.bSectorsDone]       ; Never sets CF
    123123    ret
     
    371371    pop     ds
    372372    ret
    373 
    374373%endif  ; MODULE_8BIT_IDE
     374
    375375
    376376;--------------------------------------------------------------------
     
    395395    db      6Fh         ; OUTSW/OUTSD
    396396    ret
    397 %endif
     397%endif ; USE_AT
    398398
    399399
  • trunk/XTIDE_Universal_BIOS/Src/Device/Idepack.asm

    r376 r421  
    7070
    7171    and     ah, 0Fh                     ; Limit bits for LBA28
    72     call    AccessDPT_GetDriveSelectByteToAL
     72    call    AccessDPT_GetDriveSelectByteForEbiosToAL
    7373    or      al, ah
    7474    mov     [bp+IDEPACK.bDrvAndHead], al
     
    8383    and     si, BYTE 0Fh                        ; Offset normalized
    8484    jmp     SHORT GetDeviceControlByteToIdepackAndStartTransfer
    85 %endif
     85%endif ; MODULE_EBIOS
    8686
    8787
     
    114114    push    bx
    115115    call    Address_OldInt13hAddressToIdeAddress
    116     call    AccessDPT_GetDriveSelectByteToAL
     116    call    AccessDPT_GetDriveSelectByteForOldInt13hToAL
    117117    or      al, bh          ; AL now has Drive and Head Select Byte
    118118    mov     [bp+IDEPACK.bDrvAndHead], al
     
    156156    ; Drive and Head select byte
    157157    and     ah, MASK_DRVNHEAD_HEAD      ; Keep head bits only
    158     call    AccessDPT_GetDriveSelectByteToAL
     158    call    AccessDPT_GetDriveSelectByteForOldInt13hToAL
    159159    or      al, ah
    160160    mov     [bp+IDEPACK.bDrvAndHead], al
  • trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h.asm

    r417 r421  
    115115ALIGN JUMP_ALIGN
    116116.JumpToEbiosFunction:
    117     test    BYTE [di+DPT.bFlagsLow], FLG_DRVNHEAD_LBA
     117    test    BYTE [di+DPT.bFlagsLow], FLGL_DPT_LBA_AND_EBIOS_SUPPORTED
    118118    jz      SHORT UnsupportedFunction   ; No eINT 13h for CHS drives
    119119    sub     bl, 41h<<1                  ; BX = Offset to eINT 13h jump table
  • trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH8h_HParams.asm

    r376 r421  
    101101AH8h_GetDriveParameters:
    102102    call    AccessDPT_GetLCHStoAXBLBH
     103%ifdef RESERVE_DIAGNOSTIC_CYLINDER
     104    dec     ax
     105%endif
     106    MIN_U   ax, MAX_LCHS_CYLINDERS
    103107    ; Fall to .PackReturnValues
    104108
  • trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm

    r410 r421  
    9999;;; SelectDrive
    100100    ; Try to select drive and wait until ready
    101     call    AccessDPT_GetDriveSelectByteToAL
     101    call    AccessDPT_GetDriveSelectByteForOldInt13hToAL
    102102    mov     [bp+IDEPACK.bDrvAndHead], al
    103103    call    Device_SelectDrive
     
    109109
    110110;;; InitializeDeviceParameters
    111     ; Initialize CHS parameters if LBA is not used
    112     test    BYTE [di+DPT.bFlagsLow], FLG_DRVNHEAD_LBA
     111    ; Initialize CHS parameters if LBA is not used and
     112    ; user has specified P-CHS parameters
     113    test    BYTE [di+DPT.bFlagsLow], FLGL_DPT_ASSISTED_LBA
    113114    jnz     SHORT .SkipInitializeDeviceParameters       ; No need to initialize CHS parameters if LBA mode enabled
     115    call    AccessDPT_GetPointerToDRVPARAMStoCSBX
     116    test    BYTE [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERCHS    ; User specified P-CHS?
     117    jz      SHORT .SkipInitializeDeviceParameters
    114118
    115119    ; Initialize Logical Sectors per Track and Max Head number
    116     mov     ah, [di+DPT.bPchsHeads]
    117     dec     ah                          ; Max Head number
    118     mov     dl, [di+DPT.bPchsSectors]   ; Sectors per Track
     120    mov     ax, [cs:bx+DRVPARAMS.wHeadsAndSectors]
     121    dec     ax                          ; Max Head number
     122    xchg    al, ah                      ; Heads now in AH
     123    mov     dx, ax                      ; Sectors per Track now in DL
    119124    mov     al, COMMAND_INITIALIZE_DEVICE_PARAMETERS
    120125    mov     bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_BSY, FLG_STATUS_BSY)
  • trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm

    r376 r421  
    3838;--------------------------------------------------------------------
    3939AH48h_HandlerForGetExtendedDriveParameters:
    40     call    AccessDPT_GetPointerToDRVPARAMStoCSBX
    41     push    bx
    4240    call    AccessDPT_GetLbaSectorCountToBXDXAX
    43     pop     di          ; CS:DI now points to DRVPARAMS
    4441
    4542    ; Point DS:SI to Extended Drive Information Table to fill
     43    push    ds
     44    pop     es          ; DPT now in ES:DI
    4645    mov     ds, [bp+IDEPACK.intpack+INTPACK.ds]
    4746    mov     cx, MINIMUM_EDRIVEINFO_SIZE
     
    5150
    5251    ; We do not support EDD Configuration Parameters so set to FFFF:FFFFh
    53     mov     cx, -1      ; FFFFh
     52    sub     cx, BYTE MINIMUM_EDRIVEINFO_SIZE+1  ; CX => FFFFh
    5453    mov     [si+EDRIVE_INFO.fpEDDparams], cx
    5554    mov     [si+EDRIVE_INFO.fpEDDparams+2], cx
     
    5958.SkipEddConfigurationParameters:
    6059    mov     [si+EDRIVE_INFO.wSize], cx
    61     mov     WORD [si+EDRIVE_INFO.wFlags], FLG_DMA_BOUNDARY_ERRORS_HANDLED_BY_BIOS
     60    mov     WORD [si+EDRIVE_INFO.wFlags], FLG_DMA_BOUNDARY_ERRORS_HANDLED_BY_BIOS | FLG_CHS_INFORMATION_IS_VALID
    6261
    6362    ; Store total sector count
     
    6968    mov     WORD [si+EDRIVE_INFO.wSectorSize], 512
    7069
     70    ; Store P-CHS
     71    eMOVZX  dx, BYTE [es:di+DPT.bPchsHeads]
     72    xor     ax, ax                                  ; Also a return code
     73    mov     [si+EDRIVE_INFO.dwHeads], dx
     74    mov     [si+EDRIVE_INFO.dwHeads+2], ax
     75
     76    mov     dl, [es:di+DPT.bPchsSectorsPerTrack]
     77    mov     [si+EDRIVE_INFO.dwSectorsPerTrack], dx
     78    mov     [si+EDRIVE_INFO.dwSectorsPerTrack+2], ax
     79
     80    mov     dx, [es:di+DPT.wPchsCylinders]
     81    mov     [si+EDRIVE_INFO.dwCylinders], dx
     82    mov     [si+EDRIVE_INFO.dwCylinders+2], ax
     83
    7184.ReturnWithError:
    7285    jmp     Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
  • trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Address.asm

    r376 r421  
    4747
    4848;---------------------------------------------------------------------
    49 ; Converts LCHS parameters to IDE P-CHS parameters.
     49; Converts LARGE addressing mode LCHS parameters to IDE P-CHS parameters.
    5050; PCylinder = (LCylinder << n) + (LHead / PHeadCount)
    5151; PHead     = LHead % PHeadCount
    5252; PSector   = LSector
    5353;
    54 ; Address_ConvertLCHStoPCHS:
     54; ConvertLargeModeLCHStoPCHS:
    5555;   Parameters:
    5656;       BL:     Sector number (1...63)
    57 ;       BH:     Head number (0...255)
     57;       BH:     Head number (0...239)
    5858;       CX:     Cylinder number (0...1023)
    5959;       DS:DI:  Ptr to Disk Parameter Table
     
    6666;--------------------------------------------------------------------
    6767ALIGN JUMP_ALIGN
    68 ConvertLCHStoPCHS:
     68ConvertLargeModeLCHStoPCHS:
    6969    ; LHead / PHeadCount and LHead % PHeadCount
    7070    eMOVZX  ax, bh                  ; Copy L-CHS Head number to AX
     
    8282DoNotConvertLCHS:
    8383    ret
     84
    8485
    8586;--------------------------------------------------------------------
     
    102103Address_OldInt13hAddressToIdeAddress:
    103104        call    Address_ExtractLCHSparametersFromOldInt13hAddress
     105        ACCESSDPT__GET_UNSHIFTED_ADDRESS_MODE_TO_AXZF
    104106
    105         AccessDPT_GetUnshiftedAddressModeToALZF
     107;;; 0: ADDRESSING_MODE_NORMAL
     108        jz      SHORT DoNotConvertLCHS
    106109
    107 ;;; 0: ADDR_DPT_LCHS
    108         jz      DoNotConvertLCHS
     110;;; 1: ADDRESSING_MODE_LARGE
     111        test    al, FLGL_DPT_ASSISTED_LBA
     112        jz      SHORT ConvertLargeModeLCHStoPCHS
    109113
    110 ;;; 1: ADDR_DPT_PCHS
    111         ;
    112         ; Since we are only checking for zero, we can do our math in the high order bits,
    113         ; in this case effectively subtracting 1 from the address mode.
    114         ;
    115         sub     al,(1<<ADDRESSING_MODE_FIELD_POSITION)
    116         jz      ConvertLCHStoPCHS
     114;;; 2: ADDRESSING_MODE_ASSISTED_LBA
     115        ; Fall through to ConvertAssistedLBAModeLCHStoLBARegisterValues
    117116
    118 ;;; 2: ADDR_DPT_LBA28 and 3: ADDR_DPT_LBA48
    119         ; Fall through to ConvertLCHStoLBARegisterValues
    120117
    121118;---------------------------------------------------------------------
     
    125122;
    126123; Returned address is in same registers that
    127 ; Address_DoNotConvertLCHS and Address_ConvertLCHStoPCHS returns.
     124; DoNotConvertLCHS and ConvertLargeModeLCHStoPCHS returns.
    128125;
    129 ; ConvertLCHStoLBARegisterValues:
     126; ConvertAssistedLBAModeLCHStoLBARegisterValues:
    130127;   Parameters:
    131128;       BL:     Sector number (1...63)
    132 ;       BH:     Head number (0...255)
     129;       BH:     Head number (0...254)
    133130;       CX:     Cylinder number (0...1023)
    134131;       DS:DI:  Ptr to Disk Parameter Table
     
    141138;       AX, DX
    142139;--------------------------------------------------------------------
    143 ALIGN JUMP_ALIGN
    144 ConvertLCHStoLBARegisterValues:
     140ConvertAssistedLBAModeLCHStoLBARegisterValues:
    145141    ; cylToSeek*headsPerCyl (18-bit result)
     142    ; Max = 1023 * 255 = 260,865 = 3FB01h
    146143    mov     ax, LBA_ASSIST_SPT      ; Load Sectors per Track
    147144    xchg    cx, ax                  ; Cylinder number to AX, Sectors per Track to CX
    148 
    149145%ifdef USE_386
    150     movzx   dx, [di+DPT.bLbaHeads]
     146    movzx   dx, [di+DPT.bLchsHeads]
    151147%else
    152148    cwd
    153     mov     dl, [di+DPT.bLbaHeads]
     149    mov     dl, [di+DPT.bLchsHeads]
    154150%endif
    155151    mul     dx                      ; DX:AX = cylToSeek*headsPerCyl
    156152
    157153    ; +=headToSeek (18-bit result)
     154    ; Max = 260,865 + 254 = 261,119 = 3FBFFh
    158155    add     al, bh                  ; Add Head number to DX:AX
    159156    adc     ah, dh                  ; DH = Zero after previous multiplication
     
    161158
    162159    ; *=sectPerTrack (18-bit by 6-bit multiplication with 24-bit result)
     160    ; Max = 261,119 * 63 = 16,450,497 = FB03C1h
    163161    xchg    ax, dx                  ; Hiword to AX, loword to DX
    164162    mul     cl                      ; AX = hiword * Sectors per Track
     
    169167
    170168    ; +=sectToSeek-1 (24-bit result)
     169    ; Max = 16,450,497 + 63 - 1 = 16,450,559 = FB03FFh
    171170    xor     bh, bh                  ; Sector number now in BX
    172171    dec     bx                      ; sectToSeek-=1
  • trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Prepare.asm

    r413 r421  
    5353    ; Get EBIOS command index to BX
    5454    ; LBA28 or LBA48 command
    55     cwd
    56     mov     al, [es:si+DAP.qwLBA+3] ; Load LBA48 byte 3 (bits 24...31)
    57     and     al, 0F0h                ; Clear LBA28 bits 24...27
    58     or      ax, [es:si+DAP.qwLBA+4] ; Set bits from LBA bytes 4 and 5
    59     cmp     dx, ax                  ; Set CF if any of bits 28...47 set
    60     rcl     dx, 1                   ; DX = 0 for LBA28, DX = 1 for LBA48
    6155    call    Prepare_GetOldInt13hCommandIndexToBX
    62     or      bx, dx                  ; Set block mode / single sector bit
     56    mov     al, [di+DPT.bFlagsLow]
     57    shl     al, 1                   ; Set CF if LBA48 supported
     58    adc     bl, bh                  ; LBA48 EXT commands
    6359    ret
    64 %endif
     60%endif ; MODULE_EBIOS
    6561
    6662
     
    116112;       Nothing
    117113;--------------------------------------------------------------------
    118 ALIGN JUMP_ALIGN
    119114Prepare_ByValidatingSectorsInALforOldInt13h:
    120115    test    al, al
  • trunk/XTIDE_Universal_BIOS/Src/Initialization/AtaID.asm

    r411 r421  
    2121; Section containing code
    2222SECTION .text
    23 
    24 ;--------------------------------------------------------------------
    25 ; AtaID_GetPCHStoAXBLBHfromAtaInfoInESSI
    26 ;   Parameters:
    27 ;       ES:SI:  Ptr to 512-byte ATA information read from the drive
    28 ;   Returns:
    29 ;       AX:     Number of user specified P-CHS cylinders
    30 ;       BH:     Number of user specified P-CHS sectors per track
    31 ;       BL:     Number of user specified P-CHS heads
    32 ;   Corrupts registers:
    33 ;       Nothing
    34 ;--------------------------------------------------------------------
    35 AtaID_GetPCHStoAXBLBHfromAtaInfoInESSI:
    36     mov     ax, [es:si+ATA1.wCylCnt]    ; Cylinders (1...16383)
    37     mov     bl, [es:si+ATA1.wHeadCnt]   ; Heads (1...16)
    38     mov     bh, [es:si+ATA1.wSPT]       ; Sectors per Track (1...63)
    39     ret
    40 
    41 
    42 ;--------------------------------------------------------------------
    43 ; AtaID_GetTotalSectorCountToBXDXAXfromAtaInfoInESSI
    44 ;   Parameters:
    45 ;       ES:SI:  Ptr to 512-byte ATA information read from the drive
    46 ;   Returns:
    47 ;       BX:DX:AX:   48-bit sector count
    48 ;   Corrupts registers:
    49 ;       Nothing
    50 ;--------------------------------------------------------------------
    51 AtaID_GetTotalSectorCountToBXDXAXfromAtaInfoInESSI:
    52     mov     bx, Registers_ExchangeDSSIwithESDI
    53     call    bx  ; ATA info now in DS:DI
    54     push    bx  ; We will return via Registers_ExchangeDSSIwithESDI
    55     xor     bx, bx
    56     test    BYTE [di+ATA1.wCaps+1], A1_wCaps_LBA>>8
    57     jz      SHORT .GetChsSectorCount
    58     ; Fall to .GetLbaSectorCount
    59 
    60 ;--------------------------------------------------------------------
    61 ; .GetLbaSectorCount
    62 ; .GetLba28SectorCount
    63 ; .GetChsSectorCount
    64 ;   Parameters:
    65 ;       BX:     Zero
    66 ;       DS:DI:  Ptr to 512-byte ATA information read from the drive
    67 ;   Returns:
    68 ;       BX:DX:AX:   48-bit sector count
    69 ;   Corrupts registers:
    70 ;       Nothing
    71 ;--------------------------------------------------------------------
    72 .GetLbaSectorCount:
    73 %ifdef MODULE_EBIOS
    74     test    BYTE [di+ATA6.wSetSup83+1], A6_wSetSup83_LBA48>>8
    75     jz      SHORT .GetLba28SectorCount
    76 
    77     ; Get LBA48 sector count
    78     mov     ax, [di+ATA6.qwLBACnt]
    79     mov     dx, [di+ATA6.qwLBACnt+2]
    80     mov     bx, [di+ATA6.qwLBACnt+4]
    81     ret
    82 %endif
    83 
    84 .GetLba28SectorCount:
    85     mov     ax, [di+ATA1.dwLBACnt]
    86     mov     dx, [di+ATA1.dwLBACnt+2]
    87     ret
    88 
    89 .GetChsSectorCount:
    90     mov     al, [di+ATA1.wSPT]      ; AL=Sectors per track
    91     mul     BYTE [di+ATA1.wHeadCnt] ; AX=Sectors per track * number of heads
    92     mul     WORD [di+ATA1.wCylCnt]  ; DX:AX=Sectors per track * number of heads * number of cylinders
    93     ret
    94 
    9523
    9624%ifdef MODULE_ADVANCED_ATA
  • trunk/XTIDE_Universal_BIOS/Src/Main.asm

    r400 r421  
    186186    %include "FindDPT.asm"          ; For finding DPTs
    187187    %include "AccessDPT.asm"        ; For accessing DPTs
    188     %include "LbaAssist.asm"        ; For generating L-CHS parameters to LBA drives
     188    %include "AtaGeometry.asm"      ; For generating L-CHS parameters
    189189    %include "DrvDetectInfo.asm"    ; For creating DRVDETECTINFO structs
    190190    %include "AtaID.asm"            ; For ATA Identify Device information
  • trunk/XTIDE_Universal_BIOS/Src/Menus/BootMenu/BootMenuPrint.asm

    r399 r421  
    202202    push    dx                      ; Magnitude character
    203203
    204     test    di, di
     204    test    di, di                  ; Zero if foreign drive
    205205    jz      SHORT BootMenuPrint_RefreshInformation.FormatRelay
    206206
     
    229229;       CX
    230230;--------------------------------------------------------------------
    231 GetTotalSectorCount:
    232     test    BYTE [di+DPT.bFlagsLow], FLG_DRVNHEAD_LBA
    233     jnz     SHORT .ReturnFullCapacity
    234     jmp     AH15h_GetSectorCountToBXDXAX
    235 .ReturnFullCapacity:
    236     jmp     AccessDPT_GetLbaSectorCountToBXDXAX
     231%ifdef MODULE_EBIOS
     232GetTotalSectorCount     EQU     AccessDPT_GetLbaSectorCountToBXDXAX
     233%else
     234GetTotalSectorCount     EQU     AH15h_GetSectorCountToBXDXAX
     235%endif
  • trunk/XTIDE_Universal_BIOS/Src/Menus/BootMenu/BootMenuPrintCfg.asm

    r400 r421  
    4343    eMOVZX  ax, [di+DPT.bIdevarsOffset]
    4444    xchg    bx, ax                      ; CS:BX now points to IDEVARS
    45     ; Fall to .PushAndFormatCfgString
     45    ; Fall to .PushAddressingMode
    4646
    4747;--------------------------------------------------------------------
    48 ; PushAddressingMode
     48; .PushAddressingMode
    4949;   Parameters:
    5050;       DS:DI:  Ptr to DPT
     
    5353;       Nothing (jumps to next push below)
    5454;   Corrupts registers:
    55 ;       AX, CX
     55;       AX, CX, DX
    5656;--------------------------------------------------------------------
    5757.PushAddressingMode:
    58     AccessDPT_GetUnshiftedAddressModeToALZF
     58    ACCESSDPT__GET_UNSHIFTED_ADDRESS_MODE_TO_AXZF
    5959    ;;
    6060    ;; This multiply both shifts the addressing mode bits down to low order bits, and
     
    6262    ;; with AL clear, and so we exchange AL and AH after the multiply for the final result.
    6363    ;;
    64     mov     cl,(1<<(8-ADDRESSING_MODE_FIELD_POSITION)) * g_szAddressingModes_Displacement
    65     mul     cl
    66     xchg    al,ah
    67     add     ax,g_szAddressingModes
     64    mov     cx, g_szAddressingModes_Displacement << (8-ADDRESSING_MODE_FIELD_POSITION)
     65    mul     cx
     66    xchg    al, ah      ; AL = always zero after above multiplication
     67    add     ax, g_szAddressingModes
    6868    push    ax
     69    ; Fall to .PushBlockMode
    6970
    7071;--------------------------------------------------------------------
    71 ; PushBlockMode
     72; .PushBlockMode
    7273;   Parameters:
    7374;       DS:DI:  Ptr to DPT
  • trunk/XTIDE_Universal_BIOS/Src/Strings.asm

    r417 r421  
    9797
    9898g_szAddressingModes:
    99 g_szLCHS:       db  "L-CHS",NULL
    100 g_szPCHS:       db  "P-CHS",NULL
    101 g_szLBA28:      db  "LBA28",NULL
    102 g_szLBA48:      db  "LBA48",NULL
    103 g_szAddressingModes_Displacement equ (g_szPCHS - g_szAddressingModes)
     99g_szNORMAL:     db  "NORMAL",NULL
     100g_szLARGE:      db  "LARGE ",NULL
     101g_szLBA:        db  "LBA   ",NULL
     102wantToRemoveThis:   db  "4",NULL    ; String compression want '4' somewhere
     103g_szAddressingModes_Displacement equ (g_szLARGE - g_szAddressingModes)
    104104;
    105105; Ensure that addressing modes are correctly spaced in memory
    106106;
    107107%ifndef CHECK_FOR_UNUSED_ENTRYPOINTS
    108     %if g_szLCHS <> g_szAddressingModes
     108    %if g_szNORMAL <> g_szAddressingModes
    109109        %error "g_szAddressingModes Displacement Incorrect 1"
    110110    %endif
    111     %if g_szPCHS <> g_szLCHS + g_szAddressingModes_Displacement
     111    %if g_szLARGE <> g_szNORMAL + g_szAddressingModes_Displacement
    112112        %error "g_szAddressingModes Displacement Incorrect 2"
    113113    %endif
    114     %if g_szLBA28 <> g_szPCHS + g_szAddressingModes_Displacement
     114    %if g_szLBA <> g_szLARGE + g_szAddressingModes_Displacement
    115115        %error "g_szAddressingModes Displacement Incorrect 3"
    116     %endif
    117     %if g_szLBA48 <> g_szLBA28 + g_szAddressingModes_Displacement
    118         %error "g_szAddressingModes Displacement Incorrect 4"
    119116    %endif
    120117%endif
     
    166163g_szCapacityNum:        db  "%5-u.%u %ciB",NULL
    167164g_szInformation:        db  "%s",LF,CR
    168     db  "Addr.",SINGLE_VERTICAL,"Block",SINGLE_VERTICAL,"Bus",SINGLE_VERTICAL,  "IRQ",SINGLE_VERTICAL,"Reset",LF,CR
     165    db  "Addr. ",SINGLE_VERTICAL,"Block",SINGLE_VERTICAL,"Bus",SINGLE_VERTICAL,  "IRQ",SINGLE_VERTICAL,"Reset",LF,CR
    169166    db     "%s",SINGLE_VERTICAL, "%5-u",SINGLE_VERTICAL, "%s",SINGLE_VERTICAL," %2-I",SINGLE_VERTICAL,"%5-x" ,NULL
    170167
     
    211208;$translate{ord('2')} = 12;
    212209;$translate{ord('3')} = 13;
    213 ;$translate{ord('4')} = 14;
     210;$translate{ord('4')} = 14; ; Not used at the moment
    214211;$translate{ord('5')} = 15;
    215212;$translate{ord('6')} = 16;
  • trunk/XTIDE_Universal_BIOS/Src/StringsCompressed.asm

    r417 r421  
    185185
    186186g_szAddressingModes:
    187 g_szLCHS:       ; db    "L-CHS",NULL
    188                 ; db     4ch,  2dh,  43h,  48h,  53h,  00h    ; uncompressed
    189                   db     52h,  28h,  49h,  4eh,  99h          ; compressed
    190 
    191 g_szPCHS:       ; db    "P-CHS",NULL
    192                 ; db     50h,  2dh,  43h,  48h,  53h,  00h    ; uncompressed
    193                   db     56h,  28h,  49h,  4eh,  99h          ; compressed
    194 
    195 g_szLBA28:      ; db    "LBA28",NULL
    196                 ; db     4ch,  42h,  41h,  32h,  38h,  00h    ; uncompressed
    197                   db     52h,  48h,  47h,  2ch,  11h          ; compressed
    198 
    199 g_szLBA48:      ; db    "LBA48",NULL
    200                 ; db     4ch,  42h,  41h,  34h,  38h,  00h    ; uncompressed
    201                   db     52h,  48h,  47h,  2eh,  11h          ; compressed
    202 
    203 g_szAddressingModes_Displacement equ (g_szPCHS - g_szAddressingModes)
     187g_szNORMAL:     ; db    "NORMAL",NULL
     188                ; db     4eh,  4fh,  52h,  4dh,  41h,  4ch,  00h    ; uncompressed
     189                  db     54h,  55h,  58h,  53h,  47h,  92h          ; compressed
     190
     191g_szLARGE:      ; db    "LARGE ",NULL
     192                ; db     4ch,  41h,  52h,  47h,  45h,  20h,  00h    ; uncompressed
     193                  db     52h,  47h,  58h,  4dh,  4bh,  00h          ; compressed
     194
     195g_szLBA:        ; db    "LBA   ",NULL
     196                ; db     4ch,  42h,  41h,  20h,  20h,  20h,  00h    ; uncompressed
     197                  db     52h,  48h, 0c7h,  20h,  00h                ; compressed
     198
     199wantToRemoveThis:   ; db    "4",NULL    ; String compression want '4' somewhere
     200                    ; db     34h,  00h    ; uncompressed
     201                      db     0eh          ; compressed
     202
     203g_szAddressingModes_Displacement equ (g_szLARGE - g_szAddressingModes)
    204204;
    205205; Ensure that addressing modes are correctly spaced in memory
    206206;
    207207%ifndef CHECK_FOR_UNUSED_ENTRYPOINTS
    208 %if g_szLCHS <> g_szAddressingModes
     208%if g_szNORMAL <> g_szAddressingModes
    209209%error "g_szAddressingModes Displacement Incorrect 1"
    210210%endif
    211 %if g_szPCHS <> g_szLCHS + g_szAddressingModes_Displacement
     211%if g_szLARGE <> g_szNORMAL + g_szAddressingModes_Displacement
    212212%error "g_szAddressingModes Displacement Incorrect 2"
    213213%endif
    214 %if g_szLBA28 <> g_szPCHS + g_szAddressingModes_Displacement
     214%if g_szLBA <> g_szLARGE + g_szAddressingModes_Displacement
    215215%error "g_szAddressingModes Displacement Incorrect 3"
    216 %endif
    217 %if g_szLBA48 <> g_szLBA28 + g_szAddressingModes_Displacement
    218 %error "g_szAddressingModes Displacement Incorrect 4"
    219216%endif
    220217%endif
     
    299296                          db     3eh,  3bh                ; compressed
    300297
    301     ; db    "Addr.",SINGLE_VERTICAL,"Block",SINGLE_VERTICAL,"Bus",SINGLE_VERTICAL,  "IRQ",SINGLE_VERTICAL,"Reset",LF,CR
    302     ; db     41h,  64h,  64h,  72h,  2eh, 0b3h,  42h,  6ch,  6fh,  63h,  6bh, 0b3h,  42h,  75h,  73h, 0b3h,  49h,  52h,  51h, 0b3h,  52h,  65h,  73h,  65h,  74h,  0ah,  0dh    ; uncompressed
    303       db     47h,  6ah,  6ah,  78h,  29h,  23h,  48h,  72h,  75h,  69h,  71h,  23h,  48h,  7bh,  79h,  23h,  4fh,  58h,  57h,  23h,  58h,  6bh,  79h,  6bh,  7ah,  3bh          ; compressed
     298    ; db    "Addr. ",SINGLE_VERTICAL,"Block",SINGLE_VERTICAL,"Bus",SINGLE_VERTICAL,  "IRQ",SINGLE_VERTICAL,"Reset",LF,CR
     299    ; db     41h,  64h,  64h,  72h,  2eh,  20h, 0b3h,  42h,  6ch,  6fh,  63h,  6bh, 0b3h,  42h,  75h,  73h, 0b3h,  49h,  52h,  51h, 0b3h,  52h,  65h,  73h,  65h,  74h,  0ah,  0dh    ; uncompressed
     300      db     47h,  6ah,  6ah,  78h,  29h,  20h,  23h,  48h,  72h,  75h,  69h,  71h,  23h,  48h,  7bh,  79h,  23h,  4fh,  58h,  57h,  23h,  58h,  6bh,  79h,  6bh,  7ah,  3bh          ; compressed
    304301
    305302    ; db       "%s",SINGLE_VERTICAL, "%5-u",SINGLE_VERTICAL, "%s",SINGLE_VERTICAL," %2-I",SINGLE_VERTICAL,"%5-x" ,NULL
     
    362359;$translate{ord('2')} = 12;    [StringsCompress Processed]
    363360;$translate{ord('3')} = 13;    [StringsCompress Processed]
    364 ;$translate{ord('4')} = 14;    [StringsCompress Processed]
     361;$translate{ord('4')} = 14; ; Not used at the moment    [StringsCompress Processed]
    365362;$translate{ord('5')} = 15;    [StringsCompress Processed]
    366363;$translate{ord('6')} = 16;    [StringsCompress Processed]
     
    478475;; translated usage stats
    479476;; 33:1
    480 ;; 32:22
     477;; 32:26
    481478;; 181:1
    482479;; 53:2
     
    486483;; 179:8
    487484;; 44:1
    488 ;; 50:3
     485;; 50:2
    489486;; 51:3
    490487;; 47:2
     
    493490;; 34:3
    494491;; 49:1
    495 ;; 56:6
    496 ;; 45:3
     492;; 56:4
     493;; 45:1
    497494;; 175:1
    498495;; 171:2
     
    522519;; 63,?:
    523520;; 64,@:1
    524 ;; 65,A:3
    525 ;; 66,B:9
    526 ;; 67,C:4
     521;; 65,A:4
     522;; 66,B:8
     523;; 67,C:2
    527524;; 68,D:10
    528 ;; 69,E:2
     525;; 69,E:3
    529526;; 70,F:4
    530 ;; 71,G:2
    531 ;; 72,H:4
     527;; 71,G:3
     528;; 72,H:2
    532529;; 73,I:1
    533530;; 74,J:
    534531;; 75,K:1
    535532;; 76,L:4
    536 ;; 77,M:4
    537 ;; 78,N:1
    538 ;; 79,O:1
    539 ;; 80,P:2
     533;; 77,M:5
     534;; 78,N:2
     535;; 79,O:2
     536;; 80,P:1
    540537;; 81,Q:1
    541 ;; 82,R:5
    542 ;; 83,S:5
     538;; 82,R:7
     539;; 83,S:3
    543540;; 84,T:
    544541;; 85,U:2
  • 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.