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

Last change on this file since 535 was 535, checked in by aitotat@…, 11 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.