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

Last change on this file since 590 was 567, checked in by krille_n_@…, 11 years ago

Changes:

  • Renamed MODULE_FEATURE_SETS to MODULE_POWER_MANAGEMENT.
  • Renamed MODULE_VERY_LATE_INITIALIZATION to MODULE_VERY_LATE_INIT and removed it from the official builds.
  • Removed the code that skips detection of slave drives on XT-CF controllers since slave drives can be used with Lo-tech ISA CompactFlash boards.
  • Added autodetection of the SVC ADP50L controller to XTIDECFG.
  • The autodetection of XT-CF controllers now requires MODULE_8BIT_IDE_ADVANCED in the loaded BIOS.
  • Fixed a bug in XTIDECFG from r502 where the "Base (cmd block) address" menu option would be displayed when a serial device was selected as the IDE controller.
  • XTIDECFG would display the "Enable interrupt" menu option for the XTIDE r1 but not for the XTIDE r2. It's now displayed for both controller types.
  • Disabled the "Internal Write Cache" menu option in the Master/Slave Drive menus for serial device type drives.
  • Optimizations and other fixes.
File size: 9.4 KB
RevLine 
[150]1; Project name : XTIDE Universal BIOS
[3]2; Description : Functions for finding Disk Parameter Table.
3
[376]4;
[526]5; XTIDE Universal BIOS and Associated Tools
6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
[376]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.
[526]12;
[376]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
[526]16; GNU General Public License for more details.
[376]17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
[526]18;
[376]19
[3]20; Section containing code
21SECTION .text
22
23;--------------------------------------------------------------------
[262]24; Checks if drive is handled by this BIOS, and return DPT pointer.
[3]25;
[294]26; FindDPT_ForDriveNumberInDL
[3]27; Parameters:
[262]28; DL: Drive number
[3]29; DS: RAMVARS segment
30; Returns:
[262]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
[3]35; Corrupts registers:
[262]36; Nothing
[150]37;--------------------------------------------------------------------
38ALIGN JUMP_ALIGN
[294]39FindDPT_ForDriveNumberInDL:
[262]40 xchg di, ax ; Save the contents of AX in DI
41
[294]42;
[262]43; Check Our Hard Disks
44;
[433]45 mov ax, [RAMVARS.wFirstDrvAndCount] ; Drive count to AH, First number to AL
[262]46 add ah, al ; One past last drive to AH
47
[258]48%ifdef MODULE_SERIAL_FLOPPY
[262]49 cmp dl, ah ; Above last supported?
50 jae SHORT .HardDiskNotHandledByThisBIOS
[294]51
[262]52 cmp dl, al ; Below first supported?
53 jae SHORT .CalcDPTForDriveNumber
54
[294]55ALIGN JUMP_ALIGN
56.HardDiskNotHandledByThisBIOS:
[262]57;
58; Check Our Floppy Disks
[294]59;
[262]60 call RamVars_UnpackFlopCntAndFirstToAL
61 js SHORT .DiskIsNotHandledByThisBIOS
[294]62
[277]63 cbw ; Always 0h (no floppy drive covered above)
64 adc ah, al ; Add in first drive number and number of drives
65
[262]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
[294]69 jnz SHORT .DiskIsNotHandledByThisBIOS
[262]70%else
[294]71 cmp dl, ah ; Above last supported?
[262]72 jae SHORT .DiskIsNotHandledByThisBIOS
[294]73
[262]74 cmp dl, al ; Below first supported?
[294]75 jb SHORT .DiskIsNotHandledByThisBIOS
[258]76%endif
[567]77 ; Fall to .CalcDPTForDriveNumber
[150]78
79;--------------------------------------------------------------------
80; Finds Disk Parameter Table for drive number.
[294]81; Not intended to be called except by FindDPT_ForDriveNumberInDL
[150]82;
[567]83; .CalcDPTForDriveNumber
[150]84; Parameters:
85; DL: Drive number
86; DS: RAMVARS segment
[567]87; DI: Saved copy of AX from entry at FindDPT_ForDriveNumberInDL
[150]88; Returns:
89; DS:DI: Ptr to DPT
[567]90; CF: Clear
[150]91; Corrupts registers:
[3]92; Nothing
93;--------------------------------------------------------------------
94ALIGN JUMP_ALIGN
[262]95.CalcDPTForDriveNumber:
[150]96 push dx
[3]97
[258]98%ifdef MODULE_SERIAL_FLOPPY
[433]99 mov ax, [RAMVARS.wFirstDrvAndCount]
[294]100
[258]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
[294]106
107ALIGN JUMP_ALIGN
[258]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
[262]113
[294]114.CalcDPTForNewDrive:
[150]115 mov al, LARGEST_DPT_SIZE
[294]116
[150]117 mul dl
[522]118 add ax, RAMVARS_size ; Clears CF (will not overflow)
[3]119
[150]120 pop dx
[262]121
122 xchg di, ax ; Restore AX from entry at FindDPT_ForDriveNumber, put DPT pointer in DI
[150]123 ret
124
[294]125ALIGN JUMP_ALIGN
126.DiskIsNotHandledByThisBIOS:
[259]127;
[262]128; Drive not found...
129;
130 xor ax, ax ; Clear DPT pointer
[294]131 stc ; Is not supported by our BIOS
132
[262]133 xchg di, ax ; Restore AX from save at top
[259]134 ret
135
[271]136
[259]137;--------------------------------------------------------------------
[521]138; Iteration routines for FindDPT_MasterOrSingleForIdevarsOffsetInDL and
139; FindDPT_SlaveForIdevarsOffsetInDL, for use with IterateAllDPTs
[294]140;
[271]141; Returns when DPT is found on the controller with Idevars offset in DL
142;
[521]143; IterateFindSecondDPTforIdevars
[271]144; IterateFindFirstDPTforIdevars
[567]145; DL: Offset to IDEVARS to search from DPTs
[524]146; SI: Offset to this callback function
[271]147; DS:DI: Ptr to DPT to examine
148; Returns:
[567]149; CF: Cleared if wanted DPT found
[271]150; Set if wrong DPT
151;--------------------------------------------------------------------
[521]152IterateFindSecondDPTforIdevars:
153 call IterateFindFirstDPTforIdevars
[524]154 jc SHORT .WrongController
155 mov si, IterateFindFirstDPTforIdevars
156.WrongController:
157 stc
158 ret
[521]159
[294]160IterateFindFirstDPTforIdevars:
[271]161 cmp dl, [di+DPT.bIdevarsOffset] ; Clears CF if matched
[567]162 je .Done
[271]163 stc ; Set CF for not found
[567]164.Done:
[271]165 ret
166
167
168;--------------------------------------------------------------------
[262]169; Finds pointer to first unused Disk Parameter Table.
170; Should only be used before DetectDrives is complete (not valid after this time).
[3]171;
[262]172; FindDPT_ForNewDriveToDSDI
[3]173; Parameters:
174; DS: RAMVARS segment
175; Returns:
[262]176; DS:DI: Ptr to first unused DPT
[3]177; Corrupts registers:
[262]178; AX
[3]179;--------------------------------------------------------------------
[262]180ALIGN JUMP_ALIGN
181FindDPT_ForNewDriveToDSDI:
182 push dx
[294]183
[262]184%ifdef MODULE_SERIAL_FLOPPY
185 mov dx, [RAMVARS.wDrvCntAndFlopCnt]
186 add dl, dh
187%else
188 mov dl, [RAMVARS.bDrvCnt]
189%endif
[294]190
[567]191 jmp SHORT FindDPT_ForDriveNumberInDL.CalcDPTForNewDrive
[3]192
[152]193;--------------------------------------------------------------------
[233]194; IterateToDptWithFlagsHighInBL
[152]195; Parameters:
196; DS:DI: Ptr to DPT to examine
[567]197; BL: Bit(s) to test in DPT.bFlagsHigh
[152]198; Returns:
[567]199; CF: Cleared if wanted DPT found
[262]200; Set if wrong DPT
[152]201; Corrupts registers:
202; Nothing
203;--------------------------------------------------------------------
[567]204%ifdef MODULE_SERIAL
[152]205ALIGN JUMP_ALIGN
[294]206IterateToDptWithFlagsHighInBL:
207 test [di+DPT.bFlagsHigh], bl ; Clears CF
[262]208 jnz SHORT .ReturnRightDPT
209 stc
[294]210.ReturnRightDPT:
[3]211 ret
[567]212%endif
[3]213
214;--------------------------------------------------------------------
[233]215; FindDPT_ToDSDIforSerialDevice
[161]216; Parameters:
217; DS: RAMVARS segment
218; Returns:
219; DS:DI: Ptr to DPT
[567]220; CF: Cleared if wanted DPT found
221; Set if DPT not found, or no DPTs present
[161]222; Corrupts registers:
[203]223; SI
[161]224;--------------------------------------------------------------------
[265]225%ifdef MODULE_SERIAL
[294]226ALIGN JUMP_ALIGN
227FindDPT_ToDSDIforSerialDevice:
[233]228 mov bl, FLGH_DPT_SERIAL_DEVICE
[567]229 ; Fall to FindDPT_ToDSDIforFlagsHighInBL
[265]230%endif
[294]231
[233]232;--------------------------------------------------------------------
[567]233; FindDPT_ToDSDIforFlagsHighInBL
[233]234; Parameters:
235; DS: RAMVARS segment
[567]236; BL: Bit(s) to test in DPT.bFlagsHigh
[233]237; Returns:
238; DS:DI: Ptr to DPT
[567]239; CF: Cleared if wanted DPT found
240; Set if DPT not found, or no DPTs present
[233]241; Corrupts registers:
242; SI
243;--------------------------------------------------------------------
[567]244%ifdef MODULE_SERIAL
245;%ifdef MODULE_IRQ
246;ALIGN JUMP_ALIGN
247;FindDPT_ToDSDIforFlagsHighInBL: ; This label is unused
248;%endif
249 mov si, IterateToDptWithFlagsHighInBL
250 jmp SHORT FindDPT_IterateAllDPTs
[489]251%endif
[161]252
253;--------------------------------------------------------------------
[567]254; FindDPT_MasterOrSingleForIdevarsOffsetInDL
255; Parameters:
256; DL: Offset to IDEVARS to search for
257; DS: RAMVARS segment
258; Returns:
259; DS:DI: Ptr to first DPT with same IDEVARS as in DL
260; CF: Cleared if wanted DPT found
261; Set if DPT not found, or no DPTs present
262; Corrupts registers:
263; SI
264;--------------------------------------------------------------------
265FindDPT_MasterOrSingleForIdevarsOffsetInDL:
266 mov si, IterateFindFirstDPTforIdevars
267 jmp SHORT FindDPT_IterateAllDPTs
268
269;--------------------------------------------------------------------
270; FindDPT_SlaveForIdevarsOffsetInDL
271; Parameters:
272; DL: Offset to IDEVARS to search for
273; DS: RAMVARS segment
274; Returns:
275; DS:DI: Ptr to second DPT with same IDEVARS as in DL
276; CF: Cleared if wanted DPT found
277; Set if DPT not found, or no DPTs present
278; Corrupts registers:
279; SI
280;--------------------------------------------------------------------
281FindDPT_SlaveForIdevarsOffsetInDL:
282 mov si, IterateFindSecondDPTforIdevars
283 ; Fall to FindDPT_IterateAllDPTs
284
285;--------------------------------------------------------------------
[3]286; Iterates all Disk Parameter Tables.
287;
[271]288; FindDPT_IterateAllDPTs
[3]289; Parameters:
[152]290; AX,BX,DX: Parameters to callback function
291; CS:SI: Ptr to callback function
[567]292; Callback routine should return CF=clear if found
[152]293; DS: RAMVARS segment
[3]294; Returns:
[152]295; DS:DI: Ptr to wanted DPT (if found)
[258]296; If not found, points to first empty DPT
[567]297; CF: Cleared if wanted DPT found
[262]298; Set if DPT not found, or no DPTs present
[3]299; Corrupts registers:
[150]300; Nothing unless corrupted by callback function
[3]301;--------------------------------------------------------------------
302ALIGN JUMP_ALIGN
[271]303FindDPT_IterateAllDPTs:
[3]304 push cx
[258]305
306 mov di, RAMVARS_size ; Point DS:DI to first DPT
[294]307 eMOVZX cx, [RAMVARS.bDrvCnt]
[262]308 jcxz .NotFound ; Return if no drives
[294]309
[3]310ALIGN JUMP_ALIGN
311.LoopWhileDPTsLeft:
312 call si ; Is wanted DPT?
[262]313 jnc SHORT .Found ; If so, return
314 add di, BYTE LARGEST_DPT_SIZE ; Point to next DPT
[258]315 loop .LoopWhileDPTsLeft
[262]316
[3]317ALIGN JUMP_ALIGN
[262]318.NotFound:
319 stc
320
321ALIGN JUMP_ALIGN
322.Found:
[3]323 pop cx
324 ret
Note: See TracBrowser for help on using the repository browser.