[165] | 1 | ; Project name : XTIDE Universal BIOS |
---|
| 2 | ; Description : Int 13h function AH=48h, Get Extended Drive Parameters. |
---|
| 3 | |
---|
[376] | 4 | ; |
---|
[526] | 5 | ; XTIDE Universal BIOS and Associated Tools |
---|
| 6 | ; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team. |
---|
[376] | 7 | ; |
---|
| 8 | ; This program is free software; you can redistribute it and/or modify |
---|
| 9 | ; it under the terms of the GNU General Public License as published by |
---|
| 10 | ; the Free Software Foundation; either version 2 of the License, or |
---|
| 11 | ; (at your option) any later version. |
---|
[526] | 12 | ; |
---|
[376] | 13 | ; This program is distributed in the hope that it will be useful, |
---|
| 14 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 15 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 16 | ; GNU General Public License for more details. |
---|
[526] | 17 | ; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
---|
| 18 | ; |
---|
[376] | 19 | |
---|
[165] | 20 | ; Section containing code |
---|
| 21 | SECTION .text |
---|
| 22 | |
---|
| 23 | ;-------------------------------------------------------------------- |
---|
| 24 | ; Int 13h function AH=48h, Get Extended Drive Parameters. |
---|
| 25 | ; |
---|
[533] | 26 | ; It is not completely clear what this function should return as total sector count in some cases. |
---|
| 27 | ; What is certain is that: |
---|
| 28 | ; A) Phoenix Enhanced Disk Drive Specification v3.0 says that P-CHS values |
---|
| 29 | ; are never returned for drives with more than 15,482,880 sectors (16384*15*63). |
---|
| 30 | ; For those drives we can simply return total sector count from |
---|
| 31 | ; ATA ID WORDs 60 and 61 (LBA28) or WORDs 100-103 (LBA48). |
---|
| 32 | ; B) IBM PC DOS 7.1 fdisk32 displays warning message if P-CHS values multiplied |
---|
| 33 | ; together are different than total sector count. Therefore for drives with less |
---|
| 34 | ; than or equal 15,482,880 sectors we MUST NOT return total sector count from |
---|
| 35 | ; ATA ID WORDs 60 and 61. |
---|
| 36 | ; |
---|
| 37 | ; Lets take an example. 6 GB Hitachi microdrive reports following values in ATA ID: |
---|
| 38 | ; Sector count from WORDs 60 and 61 : 12,000,556 |
---|
| 39 | ; Cylinders : 11905 |
---|
| 40 | ; Heads : 16 |
---|
| 41 | ; Sectors per track : 63 |
---|
| 42 | ; |
---|
| 43 | ; When multiplying C*H*S we get : 12,000,240 |
---|
| 44 | ; So the CHS size is a little bit less than LBA size. But we must use |
---|
| 45 | ; the smaller value since C*H*S must equal total sector count! |
---|
| 46 | ; |
---|
| 47 | ; Now we get to the uncertain area where I could not find any information. |
---|
| 48 | ; Award BIOS from 1997 Pentium motherboard returns following values: |
---|
| 49 | ; AH=08h L-CHS: 745, 255, 63 (exactly the same as what we return) |
---|
| 50 | ; => Total Sector Count: 745*255*63 = 11,968,425 |
---|
| 51 | ; AH=48h P-CHS: 11873, 16, 63 |
---|
| 52 | ; AH=48h Total Sector Count: 11873* 16*63 = 11,967,984 |
---|
| 53 | ; |
---|
| 54 | ; Notice how AH=48h returns lesser total sector count than AH=8h! The only |
---|
| 55 | ; way I could think of to get 11873 cylinders is to divide AH=08h sector |
---|
| 56 | ; count with P-CHS heads and sectors: (745*255*63) / (16*63) = 11873 |
---|
| 57 | ; |
---|
| 58 | ; I have no idea what is the reasoning behind it but at least there is one |
---|
| 59 | ; BIOS that does just that. |
---|
| 60 | ; |
---|
[535] | 61 | ; I decided that we multiply P-CHS values and do not waste space like the |
---|
| 62 | ; Award BIOS does. |
---|
[533] | 63 | ; |
---|
| 64 | ; |
---|
[165] | 65 | ; AH48h_GetExtendedDriveParameters |
---|
| 66 | ; Parameters: |
---|
| 67 | ; SI: Same as in INTPACK |
---|
| 68 | ; DL: Translated Drive number |
---|
| 69 | ; DS:DI: Ptr to DPT (in RAMVARS segment) |
---|
| 70 | ; SS:BP: Ptr to IDEPACK |
---|
| 71 | ; Parameters on INTPACK: |
---|
| 72 | ; DS:SI: Ptr to Extended Drive Information Table to fill |
---|
| 73 | ; Returns with INTPACK: |
---|
| 74 | ; AH: Int 13h return status |
---|
| 75 | ; DS:SI: Ptr to Extended Drive Information Table |
---|
[294] | 76 | ; CF: 0 if successful, 1 if error |
---|
[165] | 77 | ;-------------------------------------------------------------------- |
---|
| 78 | AH48h_HandlerForGetExtendedDriveParameters: |
---|
[535] | 79 | mov si, di |
---|
| 80 | push ds |
---|
| 81 | pop es ; ES = RAMVARS segment |
---|
| 82 | xor bx, bx |
---|
| 83 | dec bx ; Set to FFFFh to assume we do not return DPTE |
---|
[167] | 84 | |
---|
[535] | 85 | ; Create DPTE (hardware information for device drivers) |
---|
| 86 | %ifdef RETURN_DPTE_ON_AH48H |
---|
| 87 | call AH41h_GetSupportBitsToCX |
---|
| 88 | test cl, ENHANCED_DISK_DRIVE_SUPPORT |
---|
| 89 | jz SHORT .DoNotCreateDPTE |
---|
| 90 | call CreateDeviceParameterTableExtensionToESBXfromDPTinDSSI |
---|
| 91 | .DoNotCreateDPTE: |
---|
| 92 | %endif |
---|
| 93 | |
---|
| 94 | ; Point DS:DI to Extended Drive Information Table to fill |
---|
| 95 | mov di, [bp+IDEPACK.intpack+INTPACK.si] |
---|
[169] | 96 | mov ds, [bp+IDEPACK.intpack+INTPACK.ds] |
---|
[535] | 97 | |
---|
| 98 | ; Check and adjust Extended Drive Information Table size |
---|
| 99 | ; to MINIMUM_EDRIVEINFO_SIZE or EDRIVEINFO_SIZE_WITH_DPTE |
---|
| 100 | mov ax, MINIMUM_EDRIVEINFO_SIZE |
---|
| 101 | mov cx, [di+EDRIVE_INFO.wSize] |
---|
| 102 | cmp cx, ax |
---|
[332] | 103 | jb Prepare_ReturnFromInt13hWithInvalidFunctionError |
---|
[535] | 104 | mov [di+EDRIVE_INFO.wSize], ax |
---|
| 105 | add al, EDRIVEINFO_SIZE_WITH_DPTE - MINIMUM_EDRIVEINFO_SIZE |
---|
| 106 | cmp cx, ax |
---|
| 107 | jb SHORT .SkipEddConfigurationParameters |
---|
| 108 | mov [di+EDRIVE_INFO.wSize], ax |
---|
[165] | 109 | |
---|
[535] | 110 | ; Store DPTE for standard controllers only, |
---|
| 111 | ; FFFF:FFFF for non standard controllers |
---|
| 112 | %ifdef RETURN_DPTE_ON_AH48H |
---|
| 113 | mov [di+EDRIVE_INFO.fpDPTE], bx |
---|
| 114 | mov [di+EDRIVE_INFO.fpDPTE+2], es |
---|
| 115 | inc bx |
---|
| 116 | jnz SHORT .SkipEddConfigurationParameters ; Already stored |
---|
| 117 | dec bx |
---|
| 118 | mov [di+EDRIVE_INFO.fpDPTE+2], bx ; Segment = FFFFh |
---|
| 119 | %else |
---|
| 120 | mov [di+EDRIVE_INFO.fpDPTE], bx |
---|
| 121 | mov [di+EDRIVE_INFO.fpDPTE+2], bx |
---|
| 122 | %endif |
---|
[167] | 123 | |
---|
[535] | 124 | ; Fill Extended Drive Information Table in DS:DI from DPT in ES:SI |
---|
[167] | 125 | .SkipEddConfigurationParameters: |
---|
[535] | 126 | mov WORD [di+EDRIVE_INFO.wFlags], FLG_DMA_BOUNDARY_ERRORS_HANDLED_BY_BIOS |
---|
[165] | 127 | |
---|
[324] | 128 | ; Store total sector count |
---|
[535] | 129 | call Registers_ExchangeDSSIwithESDI |
---|
| 130 | call AccessDPT_GetLbaSectorCountToBXDXAX |
---|
| 131 | call Registers_ExchangeDSSIwithESDI |
---|
| 132 | mov [di+EDRIVE_INFO.qwTotalSectors], ax |
---|
| 133 | mov [di+EDRIVE_INFO.qwTotalSectors+2], dx |
---|
| 134 | mov [di+EDRIVE_INFO.qwTotalSectors+4], bx |
---|
[530] | 135 | xor cx, cx |
---|
[535] | 136 | mov [di+EDRIVE_INFO.qwTotalSectors+6], cx ; Always zero |
---|
| 137 | mov WORD [di+EDRIVE_INFO.wSectorSize], 512 |
---|
[169] | 138 | |
---|
[530] | 139 | ; Store P-CHS. Based on phoenix specification this is returned only if |
---|
| 140 | ; total sector count is 15,482,880 or less. |
---|
| 141 | sub ax, 4001h |
---|
| 142 | sbb dx, 0ECh |
---|
| 143 | sbb bx, cx ; Zero |
---|
| 144 | jnc SHORT .ReturnWithSuccess ; More than EC4000h |
---|
[535] | 145 | or WORD [di+EDRIVE_INFO.wFlags], FLG_CHS_INFORMATION_IS_VALID |
---|
[530] | 146 | |
---|
[535] | 147 | eMOVZX dx, BYTE [es:si+DPT.bPchsHeads] |
---|
| 148 | mov [di+EDRIVE_INFO.dwHeads], dx |
---|
| 149 | mov [di+EDRIVE_INFO.dwHeads+2], cx |
---|
[421] | 150 | |
---|
[535] | 151 | mov dl, [es:si+DPT.bPchsSectorsPerTrack] |
---|
| 152 | mov [di+EDRIVE_INFO.dwSectorsPerTrack], dx |
---|
| 153 | mov [di+EDRIVE_INFO.dwSectorsPerTrack+2], cx |
---|
[421] | 154 | |
---|
[535] | 155 | mov dx, [es:si+DPT.wPchsCylinders] |
---|
| 156 | mov [di+EDRIVE_INFO.dwCylinders], dx |
---|
| 157 | mov [di+EDRIVE_INFO.dwCylinders+2], cx |
---|
[421] | 158 | |
---|
[530] | 159 | .ReturnWithSuccess: |
---|
| 160 | xor ax, ax |
---|
[167] | 161 | .ReturnWithError: |
---|
[165] | 162 | jmp Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH |
---|
[535] | 163 | |
---|
| 164 | |
---|
| 165 | %ifdef RETURN_DPTE_ON_AH48H |
---|
| 166 | ;-------------------------------------------------------------------- |
---|
| 167 | ; CreateDeviceParameterTableExtensionToESBXfromDPTinDSSI |
---|
| 168 | ; Parameters: |
---|
| 169 | ; DS:SI: Ptr to DPT (in RAMVARS segment) |
---|
| 170 | ; ES: RAMVARS segment |
---|
| 171 | ; Returns: |
---|
| 172 | ; ES:BX: Ptr to Device Parameter Table Extension (DPTE) |
---|
| 173 | ; Corrupts registers: |
---|
| 174 | ; AX, CX, DX, DI |
---|
| 175 | ;-------------------------------------------------------------------- |
---|
| 176 | CreateDeviceParameterTableExtensionToESBXfromDPTinDSSI: |
---|
| 177 | ; Point ES:DI to DPTE buffer (valid until next AH=48h call) |
---|
| 178 | mov di, [cs:ROMVARS.bStealSize] |
---|
| 179 | eSHL_IM di, 10 ; DI = RAMVARS size in bytes |
---|
| 180 | sub di, BYTE DPTE_size ; DI = Offset to DPTE |
---|
| 181 | xor dx, dx ; Clear for checksum |
---|
| 182 | |
---|
| 183 | ; Set 32-bit flag for 32-bit controllers |
---|
| 184 | mov cx, FLG_LBA_TRANSLATION_ENABLED ; DPTE.wFlags |
---|
| 185 | cmp BYTE [si+DPT_ATA.bDevice], DEVICE_32BIT_ATA |
---|
| 186 | eCMOVE cl, FLG_LBA_TRANSLATION_ENABLED | FLG_32BIT_XFER_MODE |
---|
| 187 | |
---|
| 188 | ; DPTE.wBasePort |
---|
| 189 | mov ax, [si+DPT.wBasePort] |
---|
| 190 | call StoswThenAddALandAHtoDL ; Bytes 0 and 1 |
---|
| 191 | |
---|
| 192 | ; DPTE.wControlBlockPort |
---|
| 193 | eMOVZX bx, BYTE [si+DPT.bIdevarsOffset] |
---|
| 194 | mov ax, [cs:bx+IDEVARS.wControlBlockPort] |
---|
| 195 | call StoswThenAddALandAHtoDL ; Bytes 2 and 3 |
---|
| 196 | |
---|
| 197 | ; DPTE.bDrvnhead and DPTE.bBiosVendor |
---|
| 198 | xchg di, si |
---|
| 199 | call AccessDPT_GetDriveSelectByteForEbiosToAL |
---|
| 200 | xchg si, di |
---|
| 201 | call StoswThenAddALandAHtoDL ; Bytes 4 and 5 |
---|
| 202 | |
---|
| 203 | ; DPTE.bIRQ and DPTE.bBlockSize |
---|
| 204 | mov al, [cs:bx+IDEVARS.bIRQ] ; No way to define that we might not use IRQ |
---|
| 205 | mov ah, [si+DPT_ATA.bBlockSize] |
---|
| 206 | cmp ah, 1 |
---|
| 207 | jbe SHORT .DoNotSetBlockModeFlag |
---|
| 208 | or cl, FLG_BLOCK_MODE_ENABLED |
---|
| 209 | .DoNotSetBlockModeFlag: |
---|
| 210 | call StoswThenAddALandAHtoDL ; Bytes 6 and 7 |
---|
| 211 | |
---|
| 212 | ; DPTE.bDmaChannelAndType and DPTE.bPioMode |
---|
| 213 | xor ax, ax |
---|
| 214 | %ifdef MODULE_ADVANCED_ATA |
---|
| 215 | or ah, [si+DPT_ADVANCED_ATA.bPioMode] |
---|
| 216 | jz SHORT .NoDotSetFastPioFlag |
---|
| 217 | cmp WORD [si+DPT_ADVANCED_ATA.wControllerID], BYTE 0 |
---|
| 218 | je SHORT .NoDotSetFastPioFlag |
---|
| 219 | inc cx ; FLG_FAST_PIO_ENABLED |
---|
| 220 | .NoDotSetFastPioFlag: |
---|
| 221 | %endif |
---|
| 222 | call StoswThenAddALandAHtoDL ; Bytes 8 and 9 |
---|
| 223 | |
---|
| 224 | ; Set CHS translation flags and store DPTE.wFlags |
---|
| 225 | mov al, [si+DPT.bFlagsLow] |
---|
| 226 | and al, MASKL_DPT_TRANSLATEMODE |
---|
| 227 | jz SHORT .NoChsTranslationOrBitShiftTranslationSet |
---|
| 228 | or cl, FLG_CHS_TRANSLATION_ENABLED |
---|
| 229 | test al, FLGL_DPT_ASSISTED_LBA |
---|
| 230 | jz SHORT .NoChsTranslationOrBitShiftTranslationSet |
---|
| 231 | or cx, LBA_ASSISTED_TRANSLATION << TRANSLATION_TYPE_FIELD_POSITION |
---|
| 232 | .NoChsTranslationOrBitShiftTranslationSet: |
---|
| 233 | xchg ax, cx |
---|
| 234 | call StoswThenAddALandAHtoDL ; Bytes 10 and 11 |
---|
| 235 | |
---|
| 236 | ; DPTE.wReserved (must be zero) |
---|
| 237 | xor ax, ax |
---|
| 238 | call StoswThenAddALandAHtoDL ; Bytes 12 and 13 |
---|
| 239 | |
---|
| 240 | ; DPTE.bRevision and DPTE.bChecksum |
---|
| 241 | mov ax, DPTE_REVISION | (DPTE_REVISION<<8) |
---|
| 242 | add ah, dl |
---|
| 243 | neg ah |
---|
| 244 | stosw |
---|
| 245 | lea bx, [di-DPTE_size] |
---|
| 246 | ret |
---|
| 247 | |
---|
| 248 | |
---|
| 249 | ;-------------------------------------------------------------------- |
---|
| 250 | ; StoswThenAddALandAHtoDL |
---|
| 251 | ; Parameters: |
---|
| 252 | ; AX: WORD to store |
---|
| 253 | ; ES:DI: Ptr to where to store AX |
---|
| 254 | ; DL: Checksum byte |
---|
| 255 | ; Returns: |
---|
| 256 | ; DL: Checksum byte |
---|
| 257 | ; DI: Incremented by 2 |
---|
| 258 | ; Corrupts registers: |
---|
| 259 | ; Nothing |
---|
| 260 | ;-------------------------------------------------------------------- |
---|
| 261 | StoswThenAddALandAHtoDL: |
---|
| 262 | stosw |
---|
| 263 | add dl, al |
---|
| 264 | add dl, ah |
---|
| 265 | ret |
---|
| 266 | |
---|
| 267 | %endif ; RETURN_DPTE_ON_AH48H |
---|