source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CompatibleDPT.asm@ 618

Last change on this file since 618 was 612, checked in by Krister Nordvall, 3 years ago

Changes:

  • BIOSDRVS builds again (broken since r609). Also removed the last remnants of RESERVE_DIAGNOSTIC_CYLINDER from BIOSDRVS that I missed in r606.
  • Put in a limit on the P-CHS cylinder count in an attempt to improve compatibility with some CF cards that violates the ATA specification. The limit applies only to the BIOS. BIOSDRVS will continue to show the true cylinder count since we might want to add code later to warn the user when encountering incompatible drives like these.
  • Optimized the bug fix in r611.
  • Updated the copyright notices in XTIDECFG and BIOSDRVS.
File size: 9.7 KB
RevLine 
[541]1; Project name : XTIDE Universal BIOS
2; Description : Functions to handle DPT structs to present drive geometry
3; to ill behaving applications that want
4; to read DPT from interrupt vectors 41h and 46h.
5
6;
7; XTIDE Universal BIOS and Associated Tools
8; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
9;
10; This program is free software; you can redistribute it and/or modify
11; it under the terms of the GNU General Public License as published by
12; the Free Software Foundation; either version 2 of the License, or
13; (at your option) any later version.
14;
15; This program is distributed in the hope that it will be useful,
16; but WITHOUT ANY WARRANTY; without even the implied warranty of
17; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18; GNU General Public License for more details.
19; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20;
21
22; Section containing code
23SECTION .text
24
25;--------------------------------------------------------------------
26; CompatibleDPT_CreateToAXSIforDriveDL
27; Parameters:
28; DL: Drive number (80h or 81h)
29; DS:DI: Ptr to DPT
30; Returns:
31; AX:SI Ptr to destination buffer
32; Corrupts registers:
33; CX, DX
34;--------------------------------------------------------------------
35CompatibleDPT_CreateToAXSIforDriveDL:
36 push es
37
38 call AccessDPT_GetDeviceControlByteToAL
39 xchg cx, ax ; Device control byte to CL
40 mov si, di ; DPT now in DS:SI
41 call GetBufferForDrive80hToESDI
42 shr dx, 1
43 jnc SHORT .BufferLoadedToESDI
44 add di, BYTE TRANSLATED_DPT_size ; For drive 81h
45.BufferLoadedToESDI:
46
47 call FillToESDIusingDPTfromDSSI
48 xchg di, si
49 mov ax, es
50
51 pop es
52 ret
53
54
55;--------------------------------------------------------------------
56; GetTemporaryBufferForDPTEtoESDI
57; GetBufferForDrive80hToESDI
58; Parameters:
59; DS: RAMVARS segment
60; Returns:
61; ES:DI: Ptr to buffer (in RAMVARS segment)
62; Corrupts registers:
63; Nothing
64;--------------------------------------------------------------------
[550]65%ifdef MODULE_EBIOS
[541]66GetTemporaryBufferForDPTEtoESDI:
67 call GetBufferForDrive80hToESDI
68 add di, BYTE TRANSLATED_DPT_size * 2
69 ret
[550]70%endif
[541]71
72GetBufferForDrive80hToESDI:
73 push ds
74 pop es
75 mov di, [cs:ROMVARS.bStealSize] ; No harm to read WORD
76 eSHL_IM di, 10 ; DI = RAMVARS size in bytes
[550]77%ifdef MODULE_EBIOS
[541]78 sub di, BYTE (TRANSLATED_DPT_size * 2) + DPTE_size
[550]79%else
80 sub di, BYTE TRANSLATED_DPT_size * 2
81%endif
[541]82 ret
83
84
85;--------------------------------------------------------------------
86; FillToESDIusingDPTfromDSSI
87; Parameters:
88; CL: Device Control Byte
89; DS:SI: Ptr to DPT
90; ES:DI Ptr to destination buffer
91; Returns:
92; Nothing
93; Corrupts registers:
94; AX, CX, DX
95;--------------------------------------------------------------------
96FillToESDIusingDPTfromDSSI:
[543]97 mov ax, [si+DPT.wLchsCylinders]
[612]98 call AtaGeometry_LimitAXtoMaximumLCylinders
[541]99 test BYTE [si+DPT.bFlagsLow], MASKL_DPT_TRANSLATEMODE
100 jz SHORT FillStandardDPTtoESDIfromDPTinDSSI
101 ; Fall to FillTranslatedDPTtoESDIfromDPTinDSSI
102
103;--------------------------------------------------------------------
104; FillTranslatedDPTtoESDIfromDPTinDSSI
105; Parameters:
[543]106; AX: Number of Logical Cylinders
[541]107; CL: Device Control Byte
108; DS:SI: Ptr to DPT
109; ES:DI: Ptr to destination buffer
110; Returns:
111; Nothing
112; Corrupts registers:
113; AX, CX, DX
114;--------------------------------------------------------------------
115FillTranslatedDPTtoESDIfromDPTinDSSI:
[568]116 cwd ; Clear for checksum
[541]117 call StoswThenAddALandAHtoDL ; Bytes 0 and 1 (Logical number of cylinders)
118
[568]119 mov al, [si+DPT.bLchsHeads]
[541]120 mov ah, TRANSLATED_DPT_SIGNATURE
121 call StoswThenAddALandAHtoDL ; Bytes 2 (Logical number of heads) and 3 (Axh signature to indicate Translated DPT)
122
[568]123 eMOVZX ax, [si+DPT.bPchsSectorsPerTrack]
[541]124 call StoswThenAddALandAHtoDL ; Bytes 4 (Physical sectors per track) and 5 (Write Precompensation Cylinder low)
125
[568]126 mov al, ah ; Zero AX
127 stosw ; Bytes 6 (Write Precompensation Cylinder high) and 7
[541]128
[568]129 xchg cx, ax ; Device Control byte to AL, zero to CX
[541]130 mov ah, [si+DPT.wPchsCylinders]
131 call StoswThenAddALandAHtoDL ; Bytes 8 (Drive Control Byte) and 9 (Physical number of cylinders low)
132
133 mov al, [si+DPT.wPchsCylinders+1]
134 mov ah, [si+DPT.bPchsHeads]
135 call StoswThenAddALandAHtoDL ; Bytes 10 (Physical number of cylinders high) and 11 (Physical number of heads)
136
[568]137 xchg cx, ax ; Zero to AX
138 stosw ; Bytes 12 and 13 (Landing Zone Cylinder)
[541]139
140 mov al, [si+DPT.bLchsSectorsPerTrack]
[558]141%ifndef USE_186
142 call StoswALandChecksumFromDL ; Bytes 14 (Logical sectors per track) and 15 (Checksum)
143 jmp SHORT FillStandardDPTtoESDIfromDPTinDSSI.RestoreOffsetsAndReturn
144%else
[541]145 push FillStandardDPTtoESDIfromDPTinDSSI.RestoreOffsetsAndReturn
[558]146 ; Fall to StoswALandChecksumFromDL
[541]147%endif
148
149
150;--------------------------------------------------------------------
[558]151; StoswALandChecksumFromDL
152; Parameters:
153; AL: Last byte to store before checksum byte
154; DL: Sum of bytes so far
155; ES:DI: Ptr to where to store AL and Checksum byte
156; Returns:
157; DL: Sum of bytes so far
158; DI: Incremented by 2
159; Corrupts registers:
[568]160; AH
[558]161;--------------------------------------------------------------------
162StoswALandChecksumFromDL:
163 mov ah, al
164 add ah, dl
165 neg ah
166 stosw
167 ret
168
169
170;--------------------------------------------------------------------
[541]171; FillStandardDPTtoESDIfromDPTinDSSI
172; Parameters:
[543]173; AX: Number of Physical Cylinders == Number of Logical Cylinders
[541]174; CL: Device Control Byte
175; DS:SI: Ptr to DPT
176; ES:DI: Ptr to destination buffer
177; Returns:
178; Nothing
179; Corrupts registers:
180; AX
181;--------------------------------------------------------------------
182FillStandardDPTtoESDIfromDPTinDSSI:
183 stosw ; Bytes 0 and 1 (Physical number of cylinders)
[568]184 eMOVZX ax, [si+DPT.bLchsHeads]
[541]185 stosw ; Bytes 2 (Physical number of heads) and 3
[568]186%ifdef USE_UNDOC_INTEL
187%ifdef USE_386
188 xor al, al ; Zero AX and clear CF
189%else
190 salc ; Zero AX (CF cleared by eMOVZX above)
191%endif
192%else
[541]193 mov al, ah ; Zero AX
[568]194%endif
[541]195 stosw ; Bytes 4 and 5 (Write Precompensation Cylinder low)
196 stosw ; Bytes 6 (Write Precompensation Cylinder high) and 7
197 mov al, cl ; Device control byte to AL
198 stosw ; Bytes 8 (Drive Control Byte) and 9
[568]199%ifdef USE_UNDOC_INTEL
200 salc ; Zero AX (CF cleared above)
201%else
[541]202 mov al, ah ; Zero AX
[568]203%endif
[541]204 stosw ; Bytes 10 and 11
205 stosw ; Bytes 12 and 13 (Landing Zone Cylinder)
206 mov al, [si+DPT.bLchsSectorsPerTrack]
207 stosw ; Bytes 14 (Physical sectors per track) and 15
208
209.RestoreOffsetsAndReturn:
210 sub di, BYTE STANDARD_DPT_size
211 ret
212
213
[550]214%ifdef MODULE_EBIOS
[541]215;--------------------------------------------------------------------
216; CompatibleDPT_CreateDeviceParameterTableExtensionToESBXfromDPTinDSSI
217; Parameters:
218; DS:SI: Ptr to DPT (in RAMVARS segment)
219; Returns:
220; ES:BX: Ptr to Device Parameter Table Extension (DPTE)
221; Corrupts registers:
[568]222; AX, CX, DL, DI
[541]223;--------------------------------------------------------------------
224CompatibleDPT_CreateDeviceParameterTableExtensionToESBXfromDPTinDSSI:
[568]225 call GetTemporaryBufferForDPTEtoESDI ; Valid until next AH=48h call
[541]226
227 ; Set 32-bit flag for 32-bit controllers
228 mov cx, FLG_LBA_TRANSLATION_ENABLED ; DPTE.wFlags
229 cmp BYTE [si+DPT_ATA.bDevice], DEVICE_32BIT_ATA
230 eCMOVE cl, FLG_LBA_TRANSLATION_ENABLED | FLG_32BIT_XFER_MODE
231
[568]232 xor dl, dl ; Clear DL for checksum
[589]233 push bp
234 mov bp, StoswThenAddALandAHtoDL
[568]235
[541]236 ; DPTE.wBasePort
237 mov ax, [si+DPT.wBasePort]
[589]238 call bp ; Bytes 0 and 1
[541]239
240 ; DPTE.wControlBlockPort
[568]241 eMOVZX bx, [si+DPT.bIdevarsOffset]
[541]242 mov ax, [cs:bx+IDEVARS.wControlBlockPort]
[589]243 call bp ; Bytes 2 and 3
[541]244
245 ; DPTE.bDrvnhead and DPTE.bBiosVendor
246 xchg di, si
[542]247 call AccessDPT_GetDriveSelectByteToAL
[541]248 xchg si, di
[589]249 call bp ; Bytes 4 and 5
[541]250
251 ; DPTE.bIRQ and DPTE.bBlockSize
252 mov al, [cs:bx+IDEVARS.bIRQ] ; No way to define that we might not use IRQ
[589]253 mov ah, [si+DPT_ATA.bBlockSize] ; DPT_ATA.bBlockSize must never be zero!
254 sahf ; Only block size = 1 sets CF
255 jc SHORT .DoNotSetBlockModeFlag
[541]256 or cl, FLG_BLOCK_MODE_ENABLED
257.DoNotSetBlockModeFlag:
[589]258 call bp ; Bytes 6 and 7
[541]259
260 ; DPTE.bDmaChannelAndType and DPTE.bPioMode
261 xor ax, ax
[568]262%ifndef MODULE_ADVANCED_ATA
263 stosw ; Bytes 8 and 9
264%else
[541]265 or ah, [si+DPT_ADVANCED_ATA.bPioMode]
[558]266 jz SHORT .DoNotSetFastPioFlag
[568]267 cmp WORD [si+DPT_ADVANCED_ATA.wControllerID], BYTE 1
268 sbb cl, -1 ; FLG_FAST_PIO_ENABLED (if .wControllerID > 0)
[558]269.DoNotSetFastPioFlag:
[589]270 call bp ; Bytes 8 and 9
[541]271%endif
272
273 ; Set CHS translation flags and store DPTE.wFlags
274 mov al, [si+DPT.bFlagsLow]
275 and al, MASKL_DPT_TRANSLATEMODE
276 jz SHORT .NoChsTranslationOrBitShiftTranslationSet
277 or cl, FLG_CHS_TRANSLATION_ENABLED
278 test al, FLGL_DPT_ASSISTED_LBA
279 jz SHORT .NoChsTranslationOrBitShiftTranslationSet
[568]280 or ch, LBA_ASSISTED_TRANSLATION << (TRANSLATION_TYPE_FIELD_POSITION - 8)
[541]281.NoChsTranslationOrBitShiftTranslationSet:
282 xchg ax, cx
[589]283 call bp ; Bytes 10 and 11
284 pop bp
[541]285
286 ; DPTE.wReserved (must be zero)
287 xor ax, ax
[568]288 stosw ; Bytes 12 and 13
[541]289
290 ; DPTE.bRevision and DPTE.bChecksum
291 mov al, DPTE_REVISION
[568]292 lea bx, [di+2-DPTE_size] ; The +2 compensates for the last WORD yet to be stored
293 jmp StoswALandChecksumFromDL ; Bytes 14 and 15
[550]294%endif ; MODULE_EBIOS
[541]295
296
297;--------------------------------------------------------------------
298; StoswThenAddALandAHtoDL
299; Parameters:
300; AX: WORD to store
301; DL: Sum of bytes so far
302; ES:DI: Ptr to where to store AX
303; Returns:
304; DL: Sum of bytes so far
305; DI: Incremented by 2
306; Corrupts registers:
307; Nothing
308;--------------------------------------------------------------------
309StoswThenAddALandAHtoDL:
310 stosw
311 add dl, al
312 add dl, ah
313 ret
314
Note: See TracBrowser for help on using the repository browser.