Changeset 173 in xtideuniversalbios for trunk/XTIDE_Universal_BIOS/Src/Initialization
- Timestamp:
- Sep 18, 2011, 11:41:29 AM (13 years ago)
- google:author:
- aitotat@gmail.com
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/XTIDE_Universal_BIOS/Src/Initialization/AtaID.asm
r169 r173 5 5 ; Section containing code 6 6 SECTION .text 7 8 ;-------------------------------------------------------------------- 9 ; LBA assist calculation: 10 ; this is how to fit a big drive into INT13's skimpy size requirements, 11 ; with a maximum of 8.4G available. 12 ; 13 ; total LBAs (as obtained by words 60+61) 14 ; divided by 63 (sectors per track) (save as value A) 15 ; Sub 1 from A 16 ; divide A by 1024 + truncate. 17 ; == total number of heads to use. 18 ; add 1 19 ; this value must be either 16, 32, 64, 128, or 256 (round up) 20 ; then take the value A above and divide by # of heads 21 ; to get the # of cylinders to use. 22 ; 23 ; 24 ; so a LBA28 drive will have 268,435,456 as maximum LBAs 25 ; 26 ; 10000000h / 63 = 410410h (total cylinders or tracks) 27 ; 410410h / 1024 = 1041h, which is way more than 256 heads, but 256 is max. 28 ; 410410h / 256 = 4104h cylinders 29 ; 30 ; there's a wealth of information at: http://www.mossywell.com/boot-sequence 31 ; they show a slightly different approach to LBA assist calulations, but 32 ; the method here provides compatibility with phoenix BIOS 33 ; 34 ; we're using the values from 60+61 here because we're topping out at 8.4G 35 ; anyway, so there's no need to use the 48bit LBA values. 36 ; 37 ; AtaID_GetLbaAssistedCHStoAXBLBH: 38 ; Parameters: 39 ; BX:DX:AX: Total number of sectors 40 ; Returns: 41 ; DX:AX: Number of cylinders 42 ; BH: Number of sectors per track (always 63) 43 ; BL: Number of heads (16, 32, 64, 128 or 255) 44 ; Corrupts registers: 45 ; CX 46 ;-------------------------------------------------------------------- 47 AtaID_GetLbaAssistedCHStoDXAXBLBH: 48 push bp 49 push si 50 51 ; Value A = Total sector count / 63 52 xor cx, cx 53 push cx ; Push zero for bits 48...63 54 push bx 55 push dx 56 push ax ; 64-bit sector count now in stack 57 mov cl, LBA_ASSIST_SPT 58 mov bp, sp ; SS:BP now points sector count 59 call Math_DivQWatSSBPbyCX ; Temporary value A now in stack 60 61 ; BX = Number of heads = A / 1024 62 mov ax, [bp] 63 mov dx, [bp+2] 64 mov bx, [bp+4] 65 call Size_DivideSizeInBXDXAXby1024andIncrementMagnitudeInCX 66 67 ; Heads must be 16, 32, 64, 128 or 256 (round up) 68 mov bx, 256 ; Max number of heads 69 test dx, dx ; 65536 or more heads? 70 jnz SHORT .GetNumberOfCylinders 71 mov cx, 128 ; Half BX for rounding up 72 .FindMostSignificantBitForHeadSize: 73 cmp ax, cx 74 jae SHORT .GetNumberOfCylinders 75 shr cx, 1 76 shr bx, 1 ; Halve number of heads 77 jmp SHORT .FindMostSignificantBitForHeadSize 78 79 ; DX:AX = Number of cylinders = A / number of heads 80 .GetNumberOfCylinders: 81 mov cx, bx 82 call Math_DivQWatSSBPbyCX 83 mov ax, [bp] 84 mov dx, [bp+2] ; Cylinders now in DX:AX 85 86 ; Return LBA assisted CHS 87 add sp, BYTE 8 ; Clean stack 88 sub bl, bh ; Limit heads to 255 89 mov bh, LBA_ASSIST_SPT 90 pop si 91 pop bp 92 ret 93 7 94 8 95 ;-------------------------------------------------------------------- … … 34 121 ;-------------------------------------------------------------------- 35 122 AtaID_GetTotalSectorCountToBXDXAXfromAtaInfoInESSI: 36 push ds 37 38 push es 39 pop ds 123 call Registers_ExchangeDSSIwithESDI ; ATA info now in DSDI 40 124 xor bx, bx 41 test WORD [si+ATA1.wCaps], A1_wCaps_LBA125 test BYTE [di+ATA1.wCaps+1], A1_wCaps_LBA>>8 42 126 jz SHORT .GetChsSectorCount 43 127 ; Fall to .GetLbaSectorCount … … 45 129 ;-------------------------------------------------------------------- 46 130 ; .GetLbaSectorCount 131 ; .GetLba28SectorCount 132 ; .GetChsSectorCount 47 133 ; Parameters: 48 134 ; BX: Zero … … 54 140 ;-------------------------------------------------------------------- 55 141 .GetLbaSectorCount: 56 test WORD [si+ATA6.wSetSup83], A6_wSetSup83_LBA48142 test BYTE [di+ATA6.wSetSup83+1], A6_wSetSup83_LBA48>>8 57 143 jz SHORT .GetLba28SectorCount 58 mov ax, [ si+ATA6.qwLBACnt]59 mov dx, [ si+ATA6.qwLBACnt+2]60 mov bx, [ si+ATA6.qwLBACnt+4]61 pop ds62 ret 144 mov ax, [di+ATA6.qwLBACnt] 145 mov dx, [di+ATA6.qwLBACnt+2] 146 mov bx, [di+ATA6.qwLBACnt+4] 147 jmp SHORT .ExchangePtrAndReturn 148 63 149 .GetLba28SectorCount: 64 mov ax, [si+ATA1.dwLBACnt] 65 mov dx, [si+ATA1.dwLBACnt+2] 66 pop ds 67 ret 150 mov ax, [di+ATA1.dwLBACnt] 151 mov dx, [di+ATA1.dwLBACnt+2] 152 jmp SHORT .ExchangePtrAndReturn 68 153 69 ;--------------------------------------------------------------------70 ; .GetChsSectorCount71 ; Parameters:72 ; DS:SI: Ptr to 512-byte ATA information read from the drive73 ; Returns:74 ; DX:AX: 24-bit sector count75 ; Corrupts registers:76 ; Nothing77 ;--------------------------------------------------------------------78 154 .GetChsSectorCount: 79 mov al, [ si+ATA1.wSPT] ; AL=Sectors per track80 mul BYTE [ si+ATA1.wHeadCnt] ; AX=Sectors per track * number of heads81 mul WORD [ si+ATA1.wCylCnt] ; DX:AX=Sectors per track * number of heads * number of cylinders82 pop ds 83 ret155 mov al, [di+ATA1.wSPT] ; AL=Sectors per track 156 mul BYTE [di+ATA1.wHeadCnt] ; AX=Sectors per track * number of heads 157 mul WORD [di+ATA1.wCylCnt] ; DX:AX=Sectors per track * number of heads * number of cylinders 158 .ExchangePtrAndReturn: 159 jmp Registers_ExchangeDSSIwithESDI
Note:
See TracChangeset
for help on using the changeset viewer.