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

Last change on this file since 628 was 623, checked in by Krister Nordvall, 2 years ago

Changes:

  • Reversed the change to IdeDPT.asm in r622 as it didn't work as intended.
  • Reordered some procedures to reduce alignment padding.
  • Added two new defines (EXTRA_LOOP_UNROLLING_SMALL and EXTRA_LOOP_UNROLLING_LARGE) that should improve transfer speeds for some hardware combinations, specifically 808x CPUs with any IDE controller using port I/O and any CPU with XT-IDE controllers.
  • Added a new define (USE_086) for use with 8086 and V30 CPUs only. Unlike the other USE_x86 defines, this define will not change the instruction set used and is therefore compatible with all CPUs. However, it will apply padding to make jump destinations WORD aligned which should improve performance on 8086/V30 CPUs but on 8088/V20 CPUs there is no benefit and, in addition to wasting ROM space, it might in fact be slower on these machines. Since the vast majority of XT class machines are using 8088/V20 CPUs this define is not used in the official XT builds - it's primarily intended for custom BIOS builds.
  • XTIDECFG: The URL to the support forum has been updated.
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
[623]67 je SHORT .CalcDPTForDriveNumber
[262]68 cmp al, dl ; Check first drive in all cases, redundant but OK to repeat
[623]69 jne 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
[623]102 js SHORT .Harddisk
[258]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
[623]108.Harddisk:
[258]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
116 mul dl
[522]117 add ax, RAMVARS_size ; Clears CF (will not overflow)
[3]118
[150]119 pop dx
[262]120
121 xchg di, ax ; Restore AX from entry at FindDPT_ForDriveNumber, put DPT pointer in DI
[150]122 ret
123
[294]124ALIGN JUMP_ALIGN
125.DiskIsNotHandledByThisBIOS:
[259]126;
[262]127; Drive not found...
128;
129 xor ax, ax ; Clear DPT pointer
[294]130 stc ; Is not supported by our BIOS
131
[262]132 xchg di, ax ; Restore AX from save at top
[259]133 ret
134
[271]135
[259]136;--------------------------------------------------------------------
[521]137; Iteration routines for FindDPT_MasterOrSingleForIdevarsOffsetInDL and
[621]138; FindDPT_SlaveForIdevarsOffsetInDL, for use with FindDPT_IterateAllDPTs
[294]139;
[271]140; Returns when DPT is found on the controller with Idevars offset in DL
141;
[521]142; IterateFindSecondDPTforIdevars
[271]143; IterateFindFirstDPTforIdevars
[567]144; DL: Offset to IDEVARS to search from DPTs
[524]145; SI: Offset to this callback function
[271]146; DS:DI: Ptr to DPT to examine
147; Returns:
[567]148; CF: Cleared if wanted DPT found
[271]149; Set if wrong DPT
150;--------------------------------------------------------------------
[521]151IterateFindSecondDPTforIdevars:
152 call IterateFindFirstDPTforIdevars
[621]153 jc SHORT WrongController
[524]154 mov si, IterateFindFirstDPTforIdevars
[621]155SetCFandReturn:
[524]156 stc
[621]157WrongController:
[524]158 ret
[521]159
[294]160IterateFindFirstDPTforIdevars:
[271]161 cmp dl, [di+DPT.bIdevarsOffset] ; Clears CF if matched
[621]162 jne SHORT SetCFandReturn
[271]163 ret
164
165
166;--------------------------------------------------------------------
[262]167; Finds pointer to first unused Disk Parameter Table.
168; Should only be used before DetectDrives is complete (not valid after this time).
[3]169;
[262]170; FindDPT_ForNewDriveToDSDI
[3]171; Parameters:
172; DS: RAMVARS segment
173; Returns:
[262]174; DS:DI: Ptr to first unused DPT
[3]175; Corrupts registers:
[262]176; AX
[3]177;--------------------------------------------------------------------
[262]178ALIGN JUMP_ALIGN
179FindDPT_ForNewDriveToDSDI:
180 push dx
[294]181
[262]182%ifdef MODULE_SERIAL_FLOPPY
183 mov dx, [RAMVARS.wDrvCntAndFlopCnt]
184 add dl, dh
185%else
186 mov dl, [RAMVARS.bDrvCnt]
187%endif
[294]188
[567]189 jmp SHORT FindDPT_ForDriveNumberInDL.CalcDPTForNewDrive
[3]190
[152]191;--------------------------------------------------------------------
[233]192; IterateToDptWithFlagsHighInBL
[152]193; Parameters:
194; DS:DI: Ptr to DPT to examine
[567]195; BL: Bit(s) to test in DPT.bFlagsHigh
[152]196; Returns:
[567]197; CF: Cleared if wanted DPT found
[262]198; Set if wrong DPT
[152]199; Corrupts registers:
200; Nothing
201;--------------------------------------------------------------------
[567]202%ifdef MODULE_SERIAL
[152]203ALIGN JUMP_ALIGN
[294]204IterateToDptWithFlagsHighInBL:
205 test [di+DPT.bFlagsHigh], bl ; Clears CF
[262]206 jnz SHORT .ReturnRightDPT
207 stc
[294]208.ReturnRightDPT:
[3]209 ret
[567]210%endif
[3]211
212;--------------------------------------------------------------------
[233]213; FindDPT_ToDSDIforSerialDevice
[161]214; Parameters:
215; DS: RAMVARS segment
216; Returns:
217; DS:DI: Ptr to DPT
[567]218; CF: Cleared if wanted DPT found
219; Set if DPT not found, or no DPTs present
[161]220; Corrupts registers:
[621]221; BL, SI
[161]222;--------------------------------------------------------------------
[265]223%ifdef MODULE_SERIAL
[294]224ALIGN JUMP_ALIGN
225FindDPT_ToDSDIforSerialDevice:
[233]226 mov bl, FLGH_DPT_SERIAL_DEVICE
[567]227 ; Fall to FindDPT_ToDSDIforFlagsHighInBL
[265]228%endif
[294]229
[233]230;--------------------------------------------------------------------
[567]231; FindDPT_ToDSDIforFlagsHighInBL
[233]232; Parameters:
233; DS: RAMVARS segment
[567]234; BL: Bit(s) to test in DPT.bFlagsHigh
[233]235; Returns:
236; DS:DI: Ptr to DPT
[567]237; CF: Cleared if wanted DPT found
238; Set if DPT not found, or no DPTs present
[233]239; Corrupts registers:
240; SI
241;--------------------------------------------------------------------
[567]242%ifdef MODULE_SERIAL
243;%ifdef MODULE_IRQ
244;ALIGN JUMP_ALIGN
245;FindDPT_ToDSDIforFlagsHighInBL: ; This label is unused
246;%endif
247 mov si, IterateToDptWithFlagsHighInBL
248 jmp SHORT FindDPT_IterateAllDPTs
[489]249%endif
[161]250
251;--------------------------------------------------------------------
[567]252; FindDPT_MasterOrSingleForIdevarsOffsetInDL
253; Parameters:
254; DL: Offset to IDEVARS to search for
255; DS: RAMVARS segment
256; Returns:
257; DS:DI: Ptr to first DPT with same IDEVARS as in DL
258; CF: Cleared if wanted DPT found
259; Set if DPT not found, or no DPTs present
260; Corrupts registers:
261; SI
262;--------------------------------------------------------------------
263FindDPT_MasterOrSingleForIdevarsOffsetInDL:
264 mov si, IterateFindFirstDPTforIdevars
265 jmp SHORT FindDPT_IterateAllDPTs
266
267;--------------------------------------------------------------------
268; FindDPT_SlaveForIdevarsOffsetInDL
269; Parameters:
270; DL: Offset to IDEVARS to search for
271; DS: RAMVARS segment
272; Returns:
273; DS:DI: Ptr to second DPT with same IDEVARS as in DL
274; CF: Cleared if wanted DPT found
275; Set if DPT not found, or no DPTs present
276; Corrupts registers:
277; SI
278;--------------------------------------------------------------------
279FindDPT_SlaveForIdevarsOffsetInDL:
280 mov si, IterateFindSecondDPTforIdevars
281 ; Fall to FindDPT_IterateAllDPTs
282
283;--------------------------------------------------------------------
[3]284; Iterates all Disk Parameter Tables.
285;
[271]286; FindDPT_IterateAllDPTs
[3]287; Parameters:
[152]288; AX,BX,DX: Parameters to callback function
289; CS:SI: Ptr to callback function
[567]290; Callback routine should return CF=clear if found
[152]291; DS: RAMVARS segment
[3]292; Returns:
[152]293; DS:DI: Ptr to wanted DPT (if found)
[258]294; If not found, points to first empty DPT
[567]295; CF: Cleared if wanted DPT found
[262]296; Set if DPT not found, or no DPTs present
[3]297; Corrupts registers:
[150]298; Nothing unless corrupted by callback function
[3]299;--------------------------------------------------------------------
300ALIGN JUMP_ALIGN
[271]301FindDPT_IterateAllDPTs:
[3]302 push cx
[258]303
304 mov di, RAMVARS_size ; Point DS:DI to first DPT
[294]305 eMOVZX cx, [RAMVARS.bDrvCnt]
[262]306 jcxz .NotFound ; Return if no drives
[294]307
[3]308ALIGN JUMP_ALIGN
309.LoopWhileDPTsLeft:
310 call si ; Is wanted DPT?
[262]311 jnc SHORT .Found ; If so, return
312 add di, BYTE LARGEST_DPT_SIZE ; Point to next DPT
[258]313 loop .LoopWhileDPTsLeft
[262]314
315.NotFound:
316 stc
317
318ALIGN JUMP_ALIGN
319.Found:
[3]320 pop cx
321 ret
Note: See TracBrowser for help on using the repository browser.