source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm@ 536

Last change on this file since 536 was 535, checked in by aitotat@…, 12 years ago

Changes to XTIDE Universal BIOS:

  • AH=48h now returns Device Parameter Table Extension when RETURN_DPTE_ON_AH48H is defined.
  • Removed few unnecessary instructions from hardware interrupt handler.
  • P-Cylinders returned by AH=48h are no longer calculated from L-CHS capacity.
File size: 9.3 KB
Line 
1; Project name : XTIDE Universal BIOS
2; Description : Int 13h function AH=48h, Get Extended Drive Parameters.
3
4;
5; XTIDE Universal BIOS and Associated Tools
6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
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.
12;
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.
17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18;
19
20; Section containing code
21SECTION .text
22
23;--------------------------------------------------------------------
24; Int 13h function AH=48h, Get Extended Drive Parameters.
25;
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;
61; I decided that we multiply P-CHS values and do not waste space like the
62; Award BIOS does.
63;
64;
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
76; CF: 0 if successful, 1 if error
77;--------------------------------------------------------------------
78AH48h_HandlerForGetExtendedDriveParameters:
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
84
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]
96 mov ds, [bp+IDEPACK.intpack+INTPACK.ds]
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
103 jb Prepare_ReturnFromInt13hWithInvalidFunctionError
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
109
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
123
124 ; Fill Extended Drive Information Table in DS:DI from DPT in ES:SI
125.SkipEddConfigurationParameters:
126 mov WORD [di+EDRIVE_INFO.wFlags], FLG_DMA_BOUNDARY_ERRORS_HANDLED_BY_BIOS
127
128 ; Store total sector count
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
135 xor cx, cx
136 mov [di+EDRIVE_INFO.qwTotalSectors+6], cx ; Always zero
137 mov WORD [di+EDRIVE_INFO.wSectorSize], 512
138
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
145 or WORD [di+EDRIVE_INFO.wFlags], FLG_CHS_INFORMATION_IS_VALID
146
147 eMOVZX dx, BYTE [es:si+DPT.bPchsHeads]
148 mov [di+EDRIVE_INFO.dwHeads], dx
149 mov [di+EDRIVE_INFO.dwHeads+2], cx
150
151 mov dl, [es:si+DPT.bPchsSectorsPerTrack]
152 mov [di+EDRIVE_INFO.dwSectorsPerTrack], dx
153 mov [di+EDRIVE_INFO.dwSectorsPerTrack+2], cx
154
155 mov dx, [es:si+DPT.wPchsCylinders]
156 mov [di+EDRIVE_INFO.dwCylinders], dx
157 mov [di+EDRIVE_INFO.dwCylinders+2], cx
158
159.ReturnWithSuccess:
160 xor ax, ax
161.ReturnWithError:
162 jmp Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
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;--------------------------------------------------------------------
176CreateDeviceParameterTableExtensionToESBXfromDPTinDSSI:
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;--------------------------------------------------------------------
261StoswThenAddALandAHtoDL:
262 stosw
263 add dl, al
264 add dl, ah
265 ret
266
267%endif ; RETURN_DPTE_ON_AH48H
Note: See TracBrowser for help on using the repository browser.