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

Last change on this file was 612, checked in by krille_n_, 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
Line 
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;--------------------------------------------------------------------
65%ifdef MODULE_EBIOS
66GetTemporaryBufferForDPTEtoESDI:
67    call    GetBufferForDrive80hToESDI
68    add     di, BYTE TRANSLATED_DPT_size * 2
69    ret
70%endif
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
77%ifdef MODULE_EBIOS
78    sub     di, BYTE (TRANSLATED_DPT_size * 2) + DPTE_size
79%else
80    sub     di, BYTE TRANSLATED_DPT_size * 2
81%endif
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:
97    mov     ax, [si+DPT.wLchsCylinders]
98    call    AtaGeometry_LimitAXtoMaximumLCylinders
99    test    BYTE [si+DPT.bFlagsLow], MASKL_DPT_TRANSLATEMODE
100    jz      SHORT FillStandardDPTtoESDIfromDPTinDSSI
101    ; Fall to FillTranslatedDPTtoESDIfromDPTinDSSI
102
103;--------------------------------------------------------------------
104; FillTranslatedDPTtoESDIfromDPTinDSSI
105;   Parameters:
106;       AX:     Number of Logical Cylinders
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:
116    cwd                                 ; Clear for checksum
117    call    StoswThenAddALandAHtoDL     ; Bytes 0 and 1 (Logical number of cylinders)
118
119    mov     al, [si+DPT.bLchsHeads]
120    mov     ah, TRANSLATED_DPT_SIGNATURE
121    call    StoswThenAddALandAHtoDL     ; Bytes 2 (Logical number of heads) and 3 (Axh signature to indicate Translated DPT)
122
123    eMOVZX  ax, [si+DPT.bPchsSectorsPerTrack]
124    call    StoswThenAddALandAHtoDL     ; Bytes 4 (Physical sectors per track) and 5 (Write Precompensation Cylinder low)
125
126    mov     al, ah                      ; Zero AX
127    stosw                               ; Bytes 6 (Write Precompensation Cylinder high) and 7
128
129    xchg    cx, ax                      ; Device Control byte to AL, zero to CX
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
137    xchg    cx, ax                      ; Zero to AX
138    stosw                               ; Bytes 12 and 13 (Landing Zone Cylinder)
139
140    mov     al, [si+DPT.bLchsSectorsPerTrack]
141%ifndef USE_186
142    call    StoswALandChecksumFromDL    ; Bytes 14 (Logical sectors per track) and 15 (Checksum)
143    jmp     SHORT FillStandardDPTtoESDIfromDPTinDSSI.RestoreOffsetsAndReturn
144%else
145    push    FillStandardDPTtoESDIfromDPTinDSSI.RestoreOffsetsAndReturn
146    ; Fall to StoswALandChecksumFromDL
147%endif
148
149
150;--------------------------------------------------------------------
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:
160;       AH
161;--------------------------------------------------------------------
162StoswALandChecksumFromDL:
163    mov     ah, al
164    add     ah, dl
165    neg     ah
166    stosw
167    ret
168
169
170;--------------------------------------------------------------------
171; FillStandardDPTtoESDIfromDPTinDSSI
172;   Parameters:
173;       AX:     Number of Physical Cylinders == Number of Logical Cylinders
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)
184    eMOVZX  ax, [si+DPT.bLchsHeads]
185    stosw               ; Bytes 2 (Physical number of heads) and 3
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
193    mov     al, ah      ; Zero AX
194%endif
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
199%ifdef USE_UNDOC_INTEL
200    salc                ; Zero AX (CF cleared above)
201%else
202    mov     al, ah      ; Zero AX
203%endif
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
214%ifdef MODULE_EBIOS
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:
222;       AX, CX, DL, DI
223;--------------------------------------------------------------------
224CompatibleDPT_CreateDeviceParameterTableExtensionToESBXfromDPTinDSSI:
225    call    GetTemporaryBufferForDPTEtoESDI ; Valid until next AH=48h call
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
232    xor     dl, dl                          ; Clear DL for checksum
233    push    bp
234    mov     bp, StoswThenAddALandAHtoDL
235
236    ; DPTE.wBasePort
237    mov     ax, [si+DPT.wBasePort]
238    call    bp                              ; Bytes 0 and 1
239
240    ; DPTE.wControlBlockPort
241    eMOVZX  bx, [si+DPT.bIdevarsOffset]
242    mov     ax, [cs:bx+IDEVARS.wControlBlockPort]
243    call    bp                              ; Bytes 2 and 3
244
245    ; DPTE.bDrvnhead and DPTE.bBiosVendor
246    xchg    di, si
247    call    AccessDPT_GetDriveSelectByteToAL
248    xchg    si, di
249    call    bp                              ; Bytes 4 and 5
250
251    ; DPTE.bIRQ and DPTE.bBlockSize
252    mov     al, [cs:bx+IDEVARS.bIRQ]        ; No way to define that we might not use IRQ
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
256    or      cl, FLG_BLOCK_MODE_ENABLED
257.DoNotSetBlockModeFlag:
258    call    bp                              ; Bytes 6 and 7
259
260    ; DPTE.bDmaChannelAndType and DPTE.bPioMode
261    xor     ax, ax
262%ifndef MODULE_ADVANCED_ATA
263    stosw                                   ; Bytes 8 and 9
264%else
265    or      ah, [si+DPT_ADVANCED_ATA.bPioMode]
266    jz      SHORT .DoNotSetFastPioFlag
267    cmp     WORD [si+DPT_ADVANCED_ATA.wControllerID], BYTE 1
268    sbb     cl, -1  ; FLG_FAST_PIO_ENABLED (if .wControllerID > 0)
269.DoNotSetFastPioFlag:
270    call    bp                              ; Bytes 8 and 9
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
280    or      ch, LBA_ASSISTED_TRANSLATION << (TRANSLATION_TYPE_FIELD_POSITION - 8)
281.NoChsTranslationOrBitShiftTranslationSet:
282    xchg    ax, cx
283    call    bp                              ; Bytes 10 and 11
284    pop     bp
285
286    ; DPTE.wReserved (must be zero)
287    xor     ax, ax
288    stosw                                   ; Bytes 12 and 13
289
290    ; DPTE.bRevision and DPTE.bChecksum
291    mov     al, DPTE_REVISION
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
294%endif ; MODULE_EBIOS
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.