source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HStatus.asm @ 28

Last change on this file since 28 was 28, checked in by aitotat, 14 years ago
  • v1.1.1 broke booting from foreign drives, it is now fixed.
  • Improved error handling a bit.
  • Longer DRQ and IRQ timeouts to minimize write timouts with some (bad) CF cards.
  • Default boot menu drive should now be properly selected.
File size: 7.3 KB
RevLine 
[3]1; File name     :   HStatus.asm
2; Project name  :   IDE BIOS
3; Created date  :   15.12.2009
[28]4; Last update   :   1.8.2010
[3]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:
[26]27    test    BYTE [bx+DPT.bDrvCtrl], FLG_IDE_CTRL_nIEN
[28]28    jnz     SHORT .PollRdySinceInterruptsAreDisabled
[10]29    jmp     HIRQ_WaitIRQ
[28]30
[10]31ALIGN JUMP_ALIGN
[28]32.PollRdySinceInterruptsAreDisabled:
[3]33    mov     cl, B_TIMEOUT_DRQ               ; Load DRQ (not RDY) timeout
34    jmp     SHORT HStatus_WaitRdy           ; Jump to poll RDY
35
36
37;--------------------------------------------------------------------
38; Waits until Hard Disk is ready to transfer data.
39;
40; HStatus_WaitIrqOrDrq
41;   Parameters:
42;       DS:BX:  Ptr to DPT (in RAMVARS segment)
43;   Returns:
44;       AH:     BIOS Error code
45;       CF:     0 if wait succesfull
46;               1 if any error
47;   Corrupts registers:
48;       AL
49;--------------------------------------------------------------------
50ALIGN JUMP_ALIGN
51HStatus_WaitIrqOrDrq:
52    test    BYTE [bx+DPT.bDrvCtrl], FLG_IDE_CTRL_nIEN
[28]53    jnz     SHORT .PollDrqSinceInterruptsAreDisabled
54    jmp     HIRQ_WaitIRQ
[3]55
56ALIGN JUMP_ALIGN
[28]57.PollDrqSinceInterruptsAreDisabled:
58    push    dx
59    push    cx
[3]60    call    HStatus_WaitDrqDefTime
61    pop     cx
62    pop     dx
63    ret
64
65
66;--------------------------------------------------------------------
67; Waits until busy flag is cleared from selected Hard Disk drive.
68;
69; HStatus_WaitBsyDefTime    Uses default timeout
70; HStatus_WaitBsy           Uses user defined timeout
71; HStatus_WaitBsyBase       Uses user base port address and timeout
72;   Parameters:
73;       CL:     Timeout value in system timer ticks (not HStatus_WaitBsyDefTime)
74;       DX:     IDE Base port address (HUtil_WaitBsyBase only)
75;       DS:     Segment to RAMVARS
76;   Returns:
77;       AH:     BIOS Error code
78;       DX:     IDE Status Register Address
79;       CF:     0 if wait succesfull
80;               1 if any error
81;   Corrupts registers:
82;       AL, CX
83;--------------------------------------------------------------------
84ALIGN JUMP_ALIGN
85HStatus_WaitBsyDefTime:
86    mov     cl, B_TIMEOUT_BSY           ; Load timeout value
87ALIGN JUMP_ALIGN
88HStatus_WaitBsy:
89    mov     dx, [RAMVARS.wIdeBase]      ; Load offset to base port
90ALIGN JUMP_ALIGN
91HStatus_WaitBsyBase:
92    add     dx, BYTE REGR_IDE_ST        ; Add offset to status reg
93    jmp     SHORT HStatus_PollBsy       ; Wait until not busy
94
95
96;--------------------------------------------------------------------
97; Waits until Hard Disk is ready to accept commands.
98;
99; HStatus_WaitRdyDefTime    Uses default timeout
100; HStatus_WaitRdy           Uses user defined timeout
101; HStatus_WaitRdyBase       Uses user base port address and timeout
102;   Parameters:
103;       CL:     Timeout value in system timer ticks (not HStatus_WaitRdyDefTime)
104;       DX:     IDE Base port address (HStatus_WaitRdyBase 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_WaitRdyDefTime:
116    mov     cl, B_TIMEOUT_RDY           ; Load timeout value
117ALIGN JUMP_ALIGN
118HStatus_WaitRdy:
119    mov     dx, [RAMVARS.wIdeBase]      ; Load offset to base port
120ALIGN JUMP_ALIGN
121HStatus_WaitRdyBase:
122    add     dx, BYTE REGR_IDE_ST        ; Add offset to status reg
123    mov     ah, FLG_IDE_ST_DRDY         ; Flag to poll
124    jmp     SHORT HStatus_PollBsyAndFlg ; Wait until flag set
125
126
127;--------------------------------------------------------------------
128; Waits until Hard Disk is ready to transfer data.
129; Note! This function polls DRQ even if interrupts are enabled!
130;
131; HStatus_WaitDrqDefTime    Uses default timeout
132; HStatus_WaitDrq           Uses user defined timeout
133; HStatus_WaitDrqBase       Uses user base port address and timeout
134;   Parameters:
135;       CL:     Timeout value in system timer ticks (not HStatus_WaitDrqDefTime)
136;       DX:     IDE Base port address (HStatus_WaitDrqBase only)
137;       DS:     Segment to RAMVARS
138;   Returns:
139;       AH:     BIOS Error code
140;       DX:     IDE Status Register Address
141;       CF:     0 if wait succesfull
142;               1 if any error
143;   Corrupts registers:
144;       AL, CX
145;--------------------------------------------------------------------
146ALIGN JUMP_ALIGN
147HStatus_WaitDrqDefTime:
148    mov     cl, B_TIMEOUT_DRQ           ; Load timeout value
149ALIGN JUMP_ALIGN
150HStatus_WaitDrq:
151    mov     dx, [RAMVARS.wIdeBase]      ; Load offset to base port
152ALIGN JUMP_ALIGN
153HStatus_WaitDrqBase:
154    add     dx, BYTE REGR_IDE_ST        ; Add offset to status reg
155    mov     ah, FLG_IDE_ST_DRQ          ; Flag to poll
156    ; Fall to HStatus_PollBsyAndFlg
157
158;--------------------------------------------------------------------
159; IDE Status register polling.
160; This function first waits until controller is not busy.
[27]161; When not busy, IDE Status Register is polled until wanted flag is set.
[3]162;
163; HStatus_PollBusyAndFlg
164;   Parameters:
165;       AH:     Status Register Flag to poll (until set) when not busy
166;       CL:     Timeout value in system timer ticks
167;       DX:     IDE Status Register Address
168;       DS:     Segment to RAMVARS
169;   Returns:
170;       AH:     BIOS Error code
171;       CF:     Clear if wait completed successfully (no errors)
172;               Set if any error
173;   Corrupts registers:
174;       AL, CX
175;--------------------------------------------------------------------
176ALIGN JUMP_ALIGN
177HStatus_PollBsyAndFlg:
[27]178    call    SoftDelay_InitTimeout               ; Initialize timeout counter
[28]179    in      al, dx                              ; Discard contents for first read
180                                                ; (should read Alternate Status Register)
[3]181ALIGN JUMP_ALIGN
182.PollLoop:
[27]183    in      al, dx                              ; Load IDE Status Register
184    test    al, FLG_IDE_ST_BSY                  ; Controller busy?
185    jnz     SHORT .UpdateTimeout                ;  If so, jump to timeout update
186    test    al, ah                              ; Test secondary flag
187    jnz     SHORT GetErrorCodeFromPollingToAH   ; If set, break loop
[3]188ALIGN JUMP_ALIGN
189.UpdateTimeout:
[27]190    call    SoftDelay_UpdTimeout                ; Update timeout counter
191    jnc     SHORT .PollLoop                     ; Loop if time left (sets CF on timeout)
[28]192    jmp     HError_ProcessTimeoutAfterPollingBSYandSomeOtherStatusBit
[3]193
194;--------------------------------------------------------------------
195; IDE Status register polling.
196; This function waits until controller is not busy.
197;
198; HStatus_PollBsy
199;   Parameters:
200;       CL:     Timeout value in system timer ticks
201;       DX:     IDE Status Register Address
202;       DS:     Segment to RAMVARS
203;   Returns:
204;       AH:     BIOS Error code
205;       CF:     Clear if wait completed successfully (no errors)
206;               Set if any error
207;   Corrupts registers:
208;       AL, CX
209;--------------------------------------------------------------------
210ALIGN JUMP_ALIGN
211HStatus_PollBsy:
[27]212    call    SoftDelay_InitTimeout               ; Initialize timeout counter
[28]213    in      al, dx                              ; Discard contents for first read
214                                                ; (should read Alternate Status Register)
[3]215ALIGN JUMP_ALIGN
216.PollLoop:
[27]217    in      al, dx                              ; Load IDE Status Reg
218    test    al, FLG_IDE_ST_BSY                  ; Controller busy?
219    jz      SHORT GetErrorCodeFromPollingToAH   ;  If not, jump to check errors
220    call    SoftDelay_UpdTimeout                ; Update timeout counter
221    jnc     SHORT .PollLoop                     ; Loop if time left (sets CF on timeout)
[3]222ALIGN JUMP_ALIGN
[27]223GetErrorCodeFromPollingToAH:
[28]224    jmp     HError_ProcessErrorsAfterPollingBSY
Note: See TracBrowser for help on using the repository browser.