source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH0h_HReset.asm @ 26

Last change on this file since 26 was 26, checked in by aitotat, 14 years ago

Fixed a bug where Disk Parameter Table was accessed with wrong pointer register after writing last block
Cleaned AH=00h, Disk Controller Reset a bit

File size: 5.6 KB
RevLine 
[3]1; File name     :   AH0h_HReset.asm
2; Project name  :   IDE BIOS
3; Created date  :   27.9.2007
[26]4; Last update   :   26.7.2010
[3]5; Author        :   Tomi Tilli
6; Description   :   Int 13h function AH=0h, Disk Controller Reset.
7
8RETRIES_IF_RESET_FAILS      EQU     3
9TIMEOUT_BEFORE_RESET_RETRY  EQU     5       ; System timer ticks
10
11; Section containing code
12SECTION .text
13
14;--------------------------------------------------------------------
15; Int 13h function AH=0h, Disk Controller Reset.
16;
17; AH0h_HandlerForDiskControllerReset
18;   Parameters:
19;       AH:     Bios function 0h
20;       DL:     Drive number (ignored so all drives are reset)
21;               If bit 7 is set all hard disks and floppy disks reset.
22;   Parameters loaded by Int13h_Jump:
23;       DS:     RAMVARS segment
24;   Returns:
[23]25;       AH:     Int 13h return status (from drive requested in DL)
[3]26;       CF:     0 if succesfull, 1 if error
27;       IF:     1
28;   Corrupts registers:
29;       Flags
30;--------------------------------------------------------------------
31ALIGN JUMP_ALIGN
32AH0h_HandlerForDiskControllerReset:
33    push    dx
34    push    cx
35    push    bx
36    push    ax
37
[23]38    eMOVZX  bx, dl                      ; Copy requested drive to BL, zero BH to assume no errors
[26]39    call    ResetFloppyDrivesWithInt40h
40    test    bl, 80h
41    jz      SHORT .SkipHardDiskReset
42    call    ResetForeignHardDisks
43    call    ResetHardDisksHandledByOurBIOS
[23]44ALIGN JUMP_ALIGN
[26]45.SkipHardDiskReset:
[23]46    mov     ah, bh                      ; Copy error code to AH
47    xor     al, al                      ; Zero AL...
48    sub     al, ah                      ; ...and set CF if error
49    jmp     Int13h_PopXRegsAndReturn
[3]50
51
52;--------------------------------------------------------------------
[26]53; ResetFloppyDrivesWithInt40h
[3]54;   Parameters:
[23]55;       BL:     Requested drive (DL when entering AH=00h)
56;       DL:     Drive number
57;   Returns:
58;       BH:     Error code from requested drive (if available)
59;   Corrupts registers:
60;       AX, DL
61;--------------------------------------------------------------------   
62ALIGN JUMP_ALIGN
[26]63ResetFloppyDrivesWithInt40h:
64    xor     ah, ah                      ; Disk Controller Reset
[23]65    and     dl, 7Fh                     ; Clear bit 7
66    int     INTV_FLOPPY_FUNC
[26]67    jmp     SHORT BackupErrorCodeFromTheRequestedDriveToBH
[23]68
69
70;--------------------------------------------------------------------
[26]71; ResetForeignHardDisks
[23]72;   Parameters:
73;       BL:     Requested drive (DL when entering AH=00h)
[3]74;       DS:     RAMVARS segment
75;   Returns:
[23]76;       BH:     Error code from requested drive (if available)
[3]77;   Corrupts registers:
[23]78;       AX, DL
79;--------------------------------------------------------------------   
80ALIGN JUMP_ALIGN
[26]81ResetForeignHardDisks:
82    mov     dl, bl                      ; Drive to reset
[23]83    mov     ah, 0Dh                     ; Reset Hard Disk (Alternate reset)
[26]84
[23]85    pushf                               ; Push flags to simulate INT
86    cli                                 ; Disable interrupts since INT does that
87    call    FAR [RAMVARS.fpOldI13h]
88    sti                                 ; Make sure interrupts are enabled again (some BIOSes fails to enable it)
89
[26]90    jmp     SHORT BackupErrorCodeFromTheRequestedDriveToBH
[23]91
[26]92
[3]93;--------------------------------------------------------------------
[26]94; ResetHardDisksHandledByOurBIOS
[23]95;   Parameters:
96;       BL:     Requested drive (DL when entering AH=00h)
97;       DS:     RAMVARS segment
98;   Returns:
99;       BH:     Error code from requested drive (if available)
100;   Corrupts registers:
[26]101;       AX, CX, DX
[23]102;--------------------------------------------------------------------
[3]103ALIGN JUMP_ALIGN
[26]104ResetHardDisksHandledByOurBIOS:
105    mov     dh, [RAMVARS.bDrvCnt]       ; Load drive count to DH
106    test    dh, dh
107    jz      SHORT .AllDrivesReset       ; Return if no drives
108    mov     dl, [RAMVARS.bFirstDrv]     ; Load number of first our drive
109    add     dh, dl                      ; DH = one past last drive to reset
[3]110ALIGN JUMP_ALIGN
[26]111.DriveResetLoop:
112    call    AHDh_ResetDrive
113    call    BackupErrorCodeFromTheRequestedDriveToBH
114    call    .SkipNextDriveIfItIsSlaveForThisController
115    inc     dx
116    cmp     dl, dh                      ; All done?
117    jb      SHORT .DriveResetLoop       ;  If not, reset next drive
118.AllDrivesReset:
[3]119    ret
120
121;--------------------------------------------------------------------
[26]122; .SkipNextDriveIfItIsSlaveForThisController
[3]123;   Parameters:
[26]124;       DL:     Drive just resetted
[3]125;       DS:     RAMVARS segment
126;   Returns:
[26]127;       DL:     Incremented if next drive is slave drive
128;               (=already resetted)
[3]129;   Corrupts registers:
[26]130;       AX, CX
[3]131;--------------------------------------------------------------------
132ALIGN JUMP_ALIGN
[26]133.SkipNextDriveIfItIsSlaveForThisController:
134    push    di
135
136    call    .GetBasePortToAXfromDriveInDL
137    xchg    cx, ax
138
139    inc     dx
140    call    .GetBasePortToAXfromDriveInDL
141    jnc     SHORT .SkipNextDrive
142
143    cmp     ax, cx
144    je      SHORT .SkipNextDrive        ; Same controller so slave already reset
145
146    dec     dx                          ; Restore DX
147.SkipNextDrive:
148    pop     di
[3]149    ret
150
151;--------------------------------------------------------------------
[26]152; .GetBasePortToAXfromDriveInDL
[3]153;   Parameters:
[26]154;       DL:     Drive whose base port to find
[23]155;       DS:     RAMVARS segment
[3]156;   Returns:
[26]157;       AX:     Base port (if drive found)
158;       CF:     Set if drive found
159;               Cleared if drive not found
[3]160;   Corrupts registers:
[26]161;       DI
[3]162;--------------------------------------------------------------------
163ALIGN JUMP_ALIGN
[26]164.GetBasePortToAXfromDriveInDL:
165    call    FindDPT_ForDriveNumber      ; Get DPT to DS:DI
166    jnc     SHORT .DriveNotFound
167    eMOVZX  di, BYTE [di+DPT.bIdeOff]   ; CS:DI now points to IDEVARS
168    mov     ax, [cs:di+IDEVARS.wPort]
169.DriveNotFound:
170    ret
[3]171
[26]172
[3]173;--------------------------------------------------------------------
[26]174; BackupErrorCodeFromTheRequestedDriveToBH
[3]175;   Parameters:
[23]176;       AH:     Error code from the last resetted drive
177;       DL:     Drive last resetted
178;       BL:     Requested drive (DL when entering AH=00h)
[3]179;   Returns:
[23]180;       BH:     Backuped error code
[3]181;   Corrupts registers:
182;       Nothing
183;--------------------------------------------------------------------
184ALIGN JUMP_ALIGN
[26]185BackupErrorCodeFromTheRequestedDriveToBH:
186    cmp     dl, bl              ; Requested drive?
[23]187    jne     SHORT .Return
188    mov     bh, ah
189ALIGN JUMP_ALIGN
190.Return:
[3]191    ret
Note: See TracBrowser for help on using the repository browser.