source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/FindDPT.asm @ 621

Last change on this file since 621 was 621, checked in by krille_n_, 6 months ago

Changes:

  • Fixed three different bugs all causing the boot menu to show drives using IRQs even though the BIOS had been built without MODULE_IRQ.
  • Fixed two bugs in XTIDECFG where loading a BIOS from file and then loading the old settings from EEPROM would
    • overwrite ROMVARS.wFlags in the loaded BIOS file (in RAM). The possibly resulting mismatch of module flags could make it impossible to change settings for modules included in the BIOS or allow changing settings for modules not included in the BIOS.
    • not copy the color theme over to the loaded BIOS.
  • Also fixed two very minor bugs in XTIDECFG in BiosFile_LoadFileFromDSSItoRamBuffer and BiosFile_SaveRamBufferToFileInDSSI where the error handling in these routines would close whatever file handle that happened to match the error code returned by DOS in AX.
  • Made significant changes to the new flash ROM programming routines to reduce the size. Also fixed a minor bug that would cause the second verification to be skipped and return success when programming a 64 KB block of data.
  • Changed the custom BIOS build file names to the 8.3 format.
  • Changed some help strings in XTIDECFG to clarify things.
  • Other minor optimizations and fixes.
File size: 9.4 KB
Line 
1; Project name  :   XTIDE Universal BIOS
2; Description   :   Functions for finding Disk Parameter Table.
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; Checks if drive is handled by this BIOS, and return DPT pointer.
25;
26; FindDPT_ForDriveNumberInDL
27;   Parameters:
28;       DL:     Drive number
29;       DS:     RAMVARS segment
30;   Returns:
31;       CF:     Cleared if drive is handled by this BIOS
32;               Set if drive belongs to some other BIOS
33;       DI:     DPT Pointer if drive is handled by this BIOS
34;               Zero if drive belongs to some other BIOS
35;   Corrupts registers:
36;       Nothing
37;--------------------------------------------------------------------
38ALIGN JUMP_ALIGN
39FindDPT_ForDriveNumberInDL:
40    xchg    di, ax                              ; Save the contents of AX in DI
41
42;
43; Check Our Hard Disks
44;
45    mov     ax, [RAMVARS.wFirstDrvAndCount]     ; Drive count to AH, First number to AL
46    add     ah, al                              ; One past last drive to AH
47
48%ifdef MODULE_SERIAL_FLOPPY
49    cmp     dl, ah                              ; Above last supported?
50    jae     SHORT .HardDiskNotHandledByThisBIOS
51
52    cmp     dl, al                              ; Below first supported?
53    jae     SHORT .CalcDPTForDriveNumber
54
55ALIGN JUMP_ALIGN
56.HardDiskNotHandledByThisBIOS:
57;
58; Check Our Floppy Disks
59;
60    call    RamVars_UnpackFlopCntAndFirstToAL
61    js      SHORT .DiskIsNotHandledByThisBIOS
62
63    cbw                                         ; Always 0h (no floppy drive covered above)
64    adc     ah, al                              ; Add in first drive number and number of drives
65
66    cmp     ah, dl                              ; Check second drive if two, first drive if only one
67    jz      SHORT .CalcDPTForDriveNumber
68    cmp     al, dl                              ; Check first drive in all cases, redundant but OK to repeat
69    jnz     SHORT .DiskIsNotHandledByThisBIOS
70%else
71    cmp     dl, ah                              ; Above last supported?
72    jae     SHORT .DiskIsNotHandledByThisBIOS
73
74    cmp     dl, al                              ; Below first supported?
75    jb      SHORT .DiskIsNotHandledByThisBIOS
76%endif
77    ; Fall to .CalcDPTForDriveNumber
78
79;--------------------------------------------------------------------
80; Finds Disk Parameter Table for drive number.
81; Not intended to be called except by FindDPT_ForDriveNumberInDL
82;
83; .CalcDPTForDriveNumber
84;   Parameters:
85;       DL:     Drive number
86;       DS:     RAMVARS segment
87;       DI:     Saved copy of AX from entry at FindDPT_ForDriveNumberInDL
88;   Returns:
89;       DS:DI:  Ptr to DPT
90;       CF:     Clear
91;   Corrupts registers:
92;       Nothing
93;--------------------------------------------------------------------
94ALIGN JUMP_ALIGN
95.CalcDPTForDriveNumber:
96    push    dx
97
98%ifdef MODULE_SERIAL_FLOPPY
99    mov     ax, [RAMVARS.wFirstDrvAndCount]
100
101    test    dl, dl
102    js      .harddisk
103
104    call    RamVars_UnpackFlopCntAndFirstToAL
105    add     dl, ah                      ; add in end of hard disk DPT list, floppies start immediately after
106
107ALIGN JUMP_ALIGN
108.harddisk:
109    sub     dl, al                      ; subtract off beginning of either hard disk or floppy list (as appropriate)
110%else
111    sub     dl, [RAMVARS.bFirstDrv]     ; subtract off beginning of hard disk list
112%endif
113
114.CalcDPTForNewDrive:
115    mov     al, LARGEST_DPT_SIZE
116
117    mul     dl
118    add     ax, RAMVARS_size            ; Clears CF (will not overflow)
119
120    pop     dx
121
122    xchg    di, ax                      ; Restore AX from entry at FindDPT_ForDriveNumber, put DPT pointer in DI
123    ret
124
125ALIGN JUMP_ALIGN
126.DiskIsNotHandledByThisBIOS:
127;
128; Drive not found...
129;
130    xor     ax, ax                              ; Clear DPT pointer
131    stc                                         ; Is not supported by our BIOS
132
133    xchg    di, ax                              ; Restore AX from save at top
134    ret
135
136
137;--------------------------------------------------------------------
138; Iteration routines for FindDPT_MasterOrSingleForIdevarsOffsetInDL and
139; FindDPT_SlaveForIdevarsOffsetInDL, for use with FindDPT_IterateAllDPTs
140;
141; Returns when DPT is found on the controller with Idevars offset in DL
142;
143; IterateFindSecondDPTforIdevars
144; IterateFindFirstDPTforIdevars
145;       DL:     Offset to IDEVARS to search from DPTs
146;       SI:     Offset to this callback function
147;       DS:DI:  Ptr to DPT to examine
148;   Returns:
149;       CF:     Cleared if wanted DPT found
150;               Set if wrong DPT
151;--------------------------------------------------------------------
152IterateFindSecondDPTforIdevars:
153    call    IterateFindFirstDPTforIdevars
154    jc      SHORT WrongController
155    mov     si, IterateFindFirstDPTforIdevars
156SetCFandReturn:
157    stc
158WrongController:
159    ret
160
161IterateFindFirstDPTforIdevars:
162    cmp     dl, [di+DPT.bIdevarsOffset]         ; Clears CF if matched
163    jne     SHORT SetCFandReturn
164    ret
165
166
167;--------------------------------------------------------------------
168; Finds pointer to first unused Disk Parameter Table.
169; Should only be used before DetectDrives is complete (not valid after this time).
170;
171; FindDPT_ForNewDriveToDSDI
172;   Parameters:
173;       DS:     RAMVARS segment
174;   Returns:
175;       DS:DI:  Ptr to first unused DPT
176;   Corrupts registers:
177;       AX
178;--------------------------------------------------------------------
179ALIGN JUMP_ALIGN
180FindDPT_ForNewDriveToDSDI:
181    push    dx
182
183%ifdef MODULE_SERIAL_FLOPPY
184    mov     dx, [RAMVARS.wDrvCntAndFlopCnt]
185    add     dl, dh
186%else
187    mov     dl, [RAMVARS.bDrvCnt]
188%endif
189
190    jmp     SHORT FindDPT_ForDriveNumberInDL.CalcDPTForNewDrive
191
192;--------------------------------------------------------------------
193; IterateToDptWithFlagsHighInBL
194;   Parameters:
195;       DS:DI:  Ptr to DPT to examine
196;       BL:     Bit(s) to test in DPT.bFlagsHigh
197;   Returns:
198;       CF:     Cleared if wanted DPT found
199;               Set if wrong DPT
200;   Corrupts registers:
201;       Nothing
202;--------------------------------------------------------------------
203%ifdef MODULE_SERIAL
204ALIGN JUMP_ALIGN
205IterateToDptWithFlagsHighInBL:
206    test    [di+DPT.bFlagsHigh], bl             ; Clears CF
207    jnz     SHORT .ReturnRightDPT
208    stc
209.ReturnRightDPT:
210    ret
211%endif
212
213;--------------------------------------------------------------------
214; FindDPT_ToDSDIforSerialDevice
215;   Parameters:
216;       DS:     RAMVARS segment
217;   Returns:
218;       DS:DI:  Ptr to DPT
219;       CF:     Cleared if wanted DPT found
220;               Set if DPT not found, or no DPTs present
221;   Corrupts registers:
222;       BL, SI
223;--------------------------------------------------------------------
224%ifdef MODULE_SERIAL
225ALIGN JUMP_ALIGN
226FindDPT_ToDSDIforSerialDevice:
227    mov     bl, FLGH_DPT_SERIAL_DEVICE
228    ; Fall to FindDPT_ToDSDIforFlagsHighInBL
229%endif
230
231;--------------------------------------------------------------------
232; FindDPT_ToDSDIforFlagsHighInBL
233;   Parameters:
234;       DS:     RAMVARS segment
235;       BL:     Bit(s) to test in DPT.bFlagsHigh
236;   Returns:
237;       DS:DI:  Ptr to DPT
238;       CF:     Cleared if wanted DPT found
239;               Set if DPT not found, or no DPTs present
240;   Corrupts registers:
241;       SI
242;--------------------------------------------------------------------
243%ifdef MODULE_SERIAL
244;%ifdef MODULE_IRQ
245;ALIGN JUMP_ALIGN
246;FindDPT_ToDSDIforFlagsHighInBL:    ; This label is unused
247;%endif
248    mov     si, IterateToDptWithFlagsHighInBL
249    jmp     SHORT FindDPT_IterateAllDPTs
250%endif
251
252;--------------------------------------------------------------------
253; FindDPT_MasterOrSingleForIdevarsOffsetInDL
254;   Parameters:
255;       DL:     Offset to IDEVARS to search for
256;       DS:     RAMVARS segment
257;   Returns:
258;       DS:DI:  Ptr to first DPT with same IDEVARS as in DL
259;       CF:     Cleared if wanted DPT found
260;               Set if DPT not found, or no DPTs present
261;   Corrupts registers:
262;       SI
263;--------------------------------------------------------------------
264FindDPT_MasterOrSingleForIdevarsOffsetInDL:
265    mov     si, IterateFindFirstDPTforIdevars
266    jmp     SHORT FindDPT_IterateAllDPTs
267
268;--------------------------------------------------------------------
269; FindDPT_SlaveForIdevarsOffsetInDL
270;   Parameters:
271;       DL:     Offset to IDEVARS to search for
272;       DS:     RAMVARS segment
273;   Returns:
274;       DS:DI:  Ptr to second DPT with same IDEVARS as in DL
275;       CF:     Cleared if wanted DPT found
276;               Set if DPT not found, or no DPTs present
277;   Corrupts registers:
278;       SI
279;--------------------------------------------------------------------
280FindDPT_SlaveForIdevarsOffsetInDL:
281    mov     si, IterateFindSecondDPTforIdevars
282    ; Fall to FindDPT_IterateAllDPTs
283
284;--------------------------------------------------------------------
285; Iterates all Disk Parameter Tables.
286;
287; FindDPT_IterateAllDPTs
288;   Parameters:
289;       AX,BX,DX:   Parameters to callback function
290;       CS:SI:      Ptr to callback function
291;                   Callback routine should return CF=clear if found
292;       DS:         RAMVARS segment
293;   Returns:
294;       DS:DI:      Ptr to wanted DPT (if found)
295;                   If not found, points to first empty DPT
296;       CF:         Cleared if wanted DPT found
297;                   Set if DPT not found, or no DPTs present
298;   Corrupts registers:
299;       Nothing unless corrupted by callback function
300;--------------------------------------------------------------------
301ALIGN JUMP_ALIGN
302FindDPT_IterateAllDPTs:
303    push    cx
304
305    mov     di, RAMVARS_size            ; Point DS:DI to first DPT
306    eMOVZX  cx, [RAMVARS.bDrvCnt]
307    jcxz    .NotFound                   ; Return if no drives
308
309ALIGN JUMP_ALIGN
310.LoopWhileDPTsLeft:
311    call    si                          ; Is wanted DPT?
312    jnc     SHORT .Found                ;  If so, return
313    add     di, BYTE LARGEST_DPT_SIZE   ; Point to next DPT
314    loop    .LoopWhileDPTsLeft
315
316.NotFound:
317    stc
318
319ALIGN JUMP_ALIGN
320.Found:
321    pop     cx
322    ret
Note: See TracBrowser for help on using the repository browser.