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

Last change on this file since 542 was 542, checked in by aitotat@…, 11 years ago

Changes to XTIDE Universal BIOS:

  • Fixed a bug that allowed EBIOS functions for user defined CHS.
  • Simplified user defined CHS and LBA setup a little.
File size: 6.1 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=08h! 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; The only reason I can think of is that the Award BIOS has a bug and
59; uses L-CHS when it should use P-CHS values in the calculation.
60;
61;
62; AH48h_GetExtendedDriveParameters
63;   Parameters:
64;       SI:     Same as in INTPACK
65;       DL:     Translated Drive number
66;       DS:DI:  Ptr to DPT (in RAMVARS segment)
67;       SS:BP:  Ptr to IDEPACK
68;   Parameters on INTPACK:
69;       DS:SI:  Ptr to Extended Drive Information Table to fill
70;   Returns with INTPACK:
71;       AH:     Int 13h return status
72;       DS:SI:  Ptr to Extended Drive Information Table
73;       CF:     0 if successful, 1 if error
74;--------------------------------------------------------------------
75AH48h_HandlerForGetExtendedDriveParameters:
76    mov     si, di
77    push    ds
78    pop     es      ; ES = RAMVARS segment
79    xor     bx, bx
80    dec     bx      ; Set to FFFFh to assume we do not return DPTE
81
82    ; Create DPTE (hardware information for device drivers)
83%ifdef CREATE_COMPATIBLE_DPT
84    call    AH41h_GetSupportBitsToCX
85    test    cl, ENHANCED_DISK_DRIVE_SUPPORT
86    jz      SHORT .DoNotCreateDPTE
87    call    CompatibleDPT_CreateDeviceParameterTableExtensionToESBXfromDPTinDSSI
88.DoNotCreateDPTE:
89%endif
90
91    ; Point DS:DI to Extended Drive Information Table to fill
92    mov     di, [bp+IDEPACK.intpack+INTPACK.si]
93    mov     ds, [bp+IDEPACK.intpack+INTPACK.ds]
94
95    ; Check and adjust Extended Drive Information Table size
96    ; to MINIMUM_EDRIVEINFO_SIZE or EDRIVEINFO_SIZE_WITH_DPTE
97    mov     ax, MINIMUM_EDRIVEINFO_SIZE
98    mov     cx, [di+EDRIVE_INFO.wSize]
99    cmp     cx, ax
100    jb      Prepare_ReturnFromInt13hWithInvalidFunctionError
101    mov     [di+EDRIVE_INFO.wSize], ax
102    add     al, EDRIVEINFO_SIZE_WITH_DPTE - MINIMUM_EDRIVEINFO_SIZE
103    cmp     cx, ax
104    jb      SHORT .SkipEddConfigurationParameters
105    mov     [di+EDRIVE_INFO.wSize], ax
106
107    ; Store DPTE for standard controllers only,
108    ; FFFF:FFFF for non standard controllers
109%ifdef CREATE_COMPATIBLE_DPT
110    mov     [di+EDRIVE_INFO.fpDPTE], bx
111    mov     [di+EDRIVE_INFO.fpDPTE+2], es
112    inc     bx
113    jnz     SHORT .SkipEddConfigurationParameters   ; Already stored
114    dec     bx
115    mov     [di+EDRIVE_INFO.fpDPTE+2], bx   ; Segment = FFFFh
116%else
117    mov     [di+EDRIVE_INFO.fpDPTE], bx
118    mov     [di+EDRIVE_INFO.fpDPTE+2], bx
119%endif
120
121    ; Fill Extended Drive Information Table in DS:DI from DPT in ES:SI
122.SkipEddConfigurationParameters:
123    mov     WORD [di+EDRIVE_INFO.wFlags], FLG_DMA_BOUNDARY_ERRORS_HANDLED_BY_BIOS
124
125    ; Store total sector count
126    call    Registers_ExchangeDSSIwithESDI
127    call    AccessDPT_GetLbaSectorCountToBXDXAX
128    call    Registers_ExchangeDSSIwithESDI
129    mov     [di+EDRIVE_INFO.qwTotalSectors], ax
130    mov     [di+EDRIVE_INFO.qwTotalSectors+2], dx
131    mov     [di+EDRIVE_INFO.qwTotalSectors+4], bx
132    xor     cx, cx
133    mov     [di+EDRIVE_INFO.qwTotalSectors+6], cx   ; Always zero
134    mov     WORD [di+EDRIVE_INFO.wSectorSize], 512
135
136    ; Store P-CHS. Based on phoenix specification this is returned only if
137    ; total sector count is 15,482,880 or less.
138    sub     ax, MAX_SECTOR_COUNT_TO_RETURN_PCHS & 0FFFFh
139    sbb     dx, MAX_SECTOR_COUNT_TO_RETURN_PCHS >> 16
140    sbb     bx, cx      ; Zero
141    ja      SHORT .ReturnWithSuccess
142    or      BYTE [di+EDRIVE_INFO.wFlags], FLG_CHS_INFORMATION_IS_VALID
143
144    eMOVZX  dx, BYTE [es:si+DPT.bPchsHeads]
145    mov     [di+EDRIVE_INFO.dwHeads], dx
146    mov     [di+EDRIVE_INFO.dwHeads+2], cx
147
148    mov     dl, [es:si+DPT.bPchsSectorsPerTrack]
149    mov     [di+EDRIVE_INFO.dwSectorsPerTrack], dx
150    mov     [di+EDRIVE_INFO.dwSectorsPerTrack+2], cx
151
152    mov     dx, [es:si+DPT.wPchsCylinders]
153    mov     [di+EDRIVE_INFO.dwCylinders], dx
154    mov     [di+EDRIVE_INFO.dwCylinders+2], cx
155
156.ReturnWithSuccess:
157    xor     ax, ax
158.ReturnWithError:
159    jmp     Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
Note: See TracBrowser for help on using the repository browser.