source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HStatus.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: 8.3 KB
Line 
1; File name     :   HStatus.asm
2; Project name  :   IDE BIOS
3; Created date  :   15.12.2009
4; Last update   :   26.6.2010
5; Author        :   Tomi Tilli
6; Description   :   IDE Status Register polling functions.
7
8; Section containing code
9SECTION .text
10
11;--------------------------------------------------------------------
12; Waits Hard Disk IRQ when not transferring data.
13; If interrupts are disabled, RDY flag is polled.
14;
15; HStatus_WaitIrqOrRdy
16;   Parameters:
17;       DS:BX:  Ptr to DPT
18;   Returns:
19;       AH:     BIOS Error code
20;       CF:     0 if wait succesfull
21;               1 if any error
22;   Corrupts registers:
23;       AL, CX, DX
24;--------------------------------------------------------------------
25ALIGN JUMP_ALIGN
26HStatus_WaitIrqOrRdy:
27    test    BYTE [bx+DPT.bDrvCtrl], FLG_IDE_CTRL_nIEN
28    jnz     SHORT .PollRdySinceIrqsAreDisabled
29    jmp     HIRQ_WaitIRQ
30ALIGN JUMP_ALIGN
31.PollRdySinceIrqsAreDisabled:
32    call    HStatus_ReadAndIgnoreAlternateStatus
33    mov     cl, B_TIMEOUT_DRQ               ; Load DRQ (not RDY) timeout
34    jmp     SHORT HStatus_WaitRdy           ; Jump to poll RDY
35
36
37;--------------------------------------------------------------------
38; Reads Alternate Status Register and ignores result.
39; Alternate Status Register is read to prevent polling host from
40; reading status before it is valid.
41;
42; HStatus_ReadAndIgnoreAlternateStatus
43;   Parameters:
44;       DS:BX:  Ptr to DPT
45;   Returns:
46;       Nothing
47;   Corrupts registers:
48;       AL, CX, DX
49;--------------------------------------------------------------------
50ALIGN JUMP_ALIGN
51HStatus_ReadAndIgnoreAlternateStatus:
52    mov     cx, bx                          ; Backup BX
53    eMOVZX  bx, BYTE [bx+DPT.bIdeOff]       ; CS:BX now points to IDEVARS
54    mov     dx, [cs:bx+IDEVARS.wPortCtrl]   ; DX = Control Block base port
55    add     dx, BYTE REGR_IDEC_AST          ; DX = Alternate Status Register address
56    in      al, dx                          ; Read Alternate Status Register
57    mov     bx, cx                          ; Restore BX
58    ret
59
60
61;--------------------------------------------------------------------
62; Waits until Hard Disk is ready to transfer data.
63;
64; HStatus_WaitIrqOrDrq
65;   Parameters:
66;       DS:BX:  Ptr to DPT (in RAMVARS segment)
67;   Returns:
68;       AH:     BIOS Error code
69;       CF:     0 if wait succesfull
70;               1 if any error
71;   Corrupts registers:
72;       AL
73;--------------------------------------------------------------------
74ALIGN JUMP_ALIGN
75HStatus_WaitIrqOrDrq:
76    push    dx
77    push    cx
78
79    ; Check if interrupts are enabled
80    test    BYTE [bx+DPT.bDrvCtrl], FLG_IDE_CTRL_nIEN
81    jnz     SHORT .PollDRQ                  ; Poll DRQ if IRQ disabled
82    call    HIRQ_WaitIRQ                    ; Wait for IRQ
83    jmp     SHORT .Return
84
85ALIGN JUMP_ALIGN
86.PollDRQ:
87    call    HStatus_ReadAndIgnoreAlternateStatus
88    call    HStatus_WaitDrqDefTime
89ALIGN JUMP_ALIGN
90.Return:
91    pop     cx
92    pop     dx
93    ret
94
95
96;--------------------------------------------------------------------
97; Waits until busy flag is cleared from selected Hard Disk drive.
98;
99; HStatus_WaitBsyDefTime    Uses default timeout
100; HStatus_WaitBsy           Uses user defined timeout
101; HStatus_WaitBsyBase       Uses user base port address and timeout
102;   Parameters:
103;       CL:     Timeout value in system timer ticks (not HStatus_WaitBsyDefTime)
104;       DX:     IDE Base port address (HUtil_WaitBsyBase only)
105;       DS:     Segment to RAMVARS
106;   Returns:
107;       AH:     BIOS Error code
108;       DX:     IDE Status Register Address
109;       CF:     0 if wait succesfull
110;               1 if any error
111;   Corrupts registers:
112;       AL, CX
113;--------------------------------------------------------------------
114ALIGN JUMP_ALIGN
115HStatus_WaitBsyDefTime:
116    mov     cl, B_TIMEOUT_BSY           ; Load timeout value
117ALIGN JUMP_ALIGN
118HStatus_WaitBsy:
119    mov     dx, [RAMVARS.wIdeBase]      ; Load offset to base port
120ALIGN JUMP_ALIGN
121HStatus_WaitBsyBase:
122    add     dx, BYTE REGR_IDE_ST        ; Add offset to status reg
123    jmp     SHORT HStatus_PollBsy       ; Wait until not busy
124
125
126;--------------------------------------------------------------------
127; Waits until Hard Disk is ready to accept commands.
128;
129; HStatus_WaitRdyDefTime    Uses default timeout
130; HStatus_WaitRdy           Uses user defined timeout
131; HStatus_WaitRdyBase       Uses user base port address and timeout
132;   Parameters:
133;       CL:     Timeout value in system timer ticks (not HStatus_WaitRdyDefTime)
134;       DX:     IDE Base port address (HStatus_WaitRdyBase only)
135;       DS:     Segment to RAMVARS
136;   Returns:
137;       AH:     BIOS Error code
138;       DX:     IDE Status Register Address
139;       CF:     0 if wait succesfull
140;               1 if any error
141;   Corrupts registers:
142;       AL, CX
143;--------------------------------------------------------------------
144ALIGN JUMP_ALIGN
145HStatus_WaitRdyDefTime:
146    mov     cl, B_TIMEOUT_RDY           ; Load timeout value
147ALIGN JUMP_ALIGN
148HStatus_WaitRdy:
149    mov     dx, [RAMVARS.wIdeBase]      ; Load offset to base port
150ALIGN JUMP_ALIGN
151HStatus_WaitRdyBase:
152    add     dx, BYTE REGR_IDE_ST        ; Add offset to status reg
153    mov     ah, FLG_IDE_ST_DRDY         ; Flag to poll
154    jmp     SHORT HStatus_PollBsyAndFlg ; Wait until flag set
155
156
157;--------------------------------------------------------------------
158; Waits until Hard Disk is ready to transfer data.
159; Note! This function polls DRQ even if interrupts are enabled!
160;
161; HStatus_WaitDrqDefTime    Uses default timeout
162; HStatus_WaitDrq           Uses user defined timeout
163; HStatus_WaitDrqBase       Uses user base port address and timeout
164;   Parameters:
165;       CL:     Timeout value in system timer ticks (not HStatus_WaitDrqDefTime)
166;       DX:     IDE Base port address (HStatus_WaitDrqBase only)
167;       DS:     Segment to RAMVARS
168;   Returns:
169;       AH:     BIOS Error code
170;       DX:     IDE Status Register Address
171;       CF:     0 if wait succesfull
172;               1 if any error
173;   Corrupts registers:
174;       AL, CX
175;--------------------------------------------------------------------
176ALIGN JUMP_ALIGN
177HStatus_WaitDrqDefTime:
178    mov     cl, B_TIMEOUT_DRQ           ; Load timeout value
179ALIGN JUMP_ALIGN
180HStatus_WaitDrq:
181    mov     dx, [RAMVARS.wIdeBase]      ; Load offset to base port
182ALIGN JUMP_ALIGN
183HStatus_WaitDrqBase:
184    add     dx, BYTE REGR_IDE_ST        ; Add offset to status reg
185    mov     ah, FLG_IDE_ST_DRQ          ; Flag to poll
186    ; Fall to HStatus_PollBsyAndFlg
187
188;--------------------------------------------------------------------
189; IDE Status register polling.
190; This function first waits until controller is not busy.
191; When not busy, IDE Status Register is polled until wanted
192; flag (HBIT_ST_DRDY or HBIT_ST_DRQ) is set.
193;
194; HStatus_PollBusyAndFlg
195;   Parameters:
196;       AH:     Status Register Flag to poll (until set) when not busy
197;       CL:     Timeout value in system timer ticks
198;       DX:     IDE Status Register Address
199;       DS:     Segment to RAMVARS
200;   Returns:
201;       AH:     BIOS Error code
202;       CF:     Clear if wait completed successfully (no errors)
203;               Set if any error
204;   Corrupts registers:
205;       AL, CX
206;--------------------------------------------------------------------
207ALIGN JUMP_ALIGN
208HStatus_PollBsyAndFlg:
209    call    SoftDelay_InitTimeout       ; Initialize timeout counter
210ALIGN JUMP_ALIGN
211.PollLoop:
212    in      al, dx                      ; Load IDE Status Register
213    test    al, FLG_IDE_ST_BSY          ; Controller busy?
214    jnz     SHORT .UpdateTimeout        ;  If so, jump to timeout update
215    test    al, ah                      ; Test secondary flag
216    jnz     SHORT HStatus_PollCompleted ; If set, break loop
217ALIGN JUMP_ALIGN
218.UpdateTimeout:
219    call    SoftDelay_UpdTimeout        ; Update timeout counter
220    jnc     SHORT .PollLoop             ; Loop if time left (sets CF on timeout)
221    mov     ah, RET_HD_TIMEOUT          ; Load error code for timeout
222    ret
223
224
225;--------------------------------------------------------------------
226; IDE Status register polling.
227; This function waits until controller is not busy.
228;
229; HStatus_PollBsy
230;   Parameters:
231;       CL:     Timeout value in system timer ticks
232;       DX:     IDE Status Register Address
233;       DS:     Segment to RAMVARS
234;   Returns:
235;       AH:     BIOS Error code
236;       CF:     Clear if wait completed successfully (no errors)
237;               Set if any error
238;   Corrupts registers:
239;       AL, CX
240;--------------------------------------------------------------------
241ALIGN JUMP_ALIGN
242HStatus_PollBsy:
243    call    SoftDelay_InitTimeout       ; Initialize timeout counter
244ALIGN JUMP_ALIGN
245.PollLoop:
246    in      al, dx                      ; Load IDE Status Reg
247    test    al, FLG_IDE_ST_BSY          ; Controller busy? (clears CF)
248    jz      SHORT HStatus_PollCompleted ;  If not, jump to check errors
249    call    SoftDelay_UpdTimeout        ; Update timeout counter
250    jnc     SHORT .PollLoop             ; Loop if time left (sets CF on timeout)
251    mov     ah, RET_HD_TIMEOUT          ; Load error code for timeout
252    ret
253
254ALIGN JUMP_ALIGN
255HStatus_PollCompleted:
256    test    al, FLG_IDE_ST_DF | FLG_IDE_ST_ERR
257    jnz     SHORT .GetErrorCode         ;  If errors, jump to get error code
258    xor     ah, ah                      ; Zero AH and clear CF
259    ret
260.GetErrorCode:
261    jmp     HError_GetErrorCodeForStatusReg
Note: See TracBrowser for help on using the repository browser.