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

Last change on this file since 623 was 623, checked in by krille_n_, 23 months 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.