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

Last change on this file since 29 was 28, checked in by Tomi Tilli, 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
Line 
1; File name : HStatus.asm
2; Project name : IDE BIOS
3; Created date : 15.12.2009
4; Last update : 1.8.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 .PollRdySinceInterruptsAreDisabled
29 jmp HIRQ_WaitIRQ
30
31ALIGN JUMP_ALIGN
32.PollRdySinceInterruptsAreDisabled:
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
53 jnz SHORT .PollDrqSinceInterruptsAreDisabled
54 jmp HIRQ_WaitIRQ
55
56ALIGN JUMP_ALIGN
57.PollDrqSinceInterruptsAreDisabled:
58 push dx
59 push cx
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.
161; When not busy, IDE Status Register is polled until wanted flag is set.
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:
178 call SoftDelay_InitTimeout ; Initialize timeout counter
179 in al, dx ; Discard contents for first read
180 ; (should read Alternate Status Register)
181ALIGN JUMP_ALIGN
182.PollLoop:
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
188ALIGN JUMP_ALIGN
189.UpdateTimeout:
190 call SoftDelay_UpdTimeout ; Update timeout counter
191 jnc SHORT .PollLoop ; Loop if time left (sets CF on timeout)
192 jmp HError_ProcessTimeoutAfterPollingBSYandSomeOtherStatusBit
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:
212 call SoftDelay_InitTimeout ; Initialize timeout counter
213 in al, dx ; Discard contents for first read
214 ; (should read Alternate Status Register)
215ALIGN JUMP_ALIGN
216.PollLoop:
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)
222ALIGN JUMP_ALIGN
223GetErrorCodeFromPollingToAH:
224 jmp HError_ProcessErrorsAfterPollingBSY
Note: See TracBrowser for help on using the repository browser.