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

Last change on this file since 27 was 27, checked in by Tomi Tilli, 14 years ago
  • v1.1.1 broke booting from foreign drives, it is now fixed.
  • 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.
  • Timeout errors might now get translated for better error codes on certain situations.
File size: 8.0 KB
Line 
1; File name : HStatus.asm
2; Project name : IDE BIOS
3; Created date : 15.12.2009
4; Last update : 28.7.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 flag is set.
192;
193; HStatus_PollBusyAndFlg
194; Parameters:
195; AH: Status Register Flag to poll (until set) when not busy
196; CL: Timeout value in system timer ticks
197; DX: IDE Status Register Address
198; DS: Segment to RAMVARS
199; Returns:
200; AH: BIOS Error code
201; CF: Clear if wait completed successfully (no errors)
202; Set if any error
203; Corrupts registers:
204; AL, CX
205;--------------------------------------------------------------------
206ALIGN JUMP_ALIGN
207HStatus_PollBsyAndFlg:
208 call SoftDelay_InitTimeout ; Initialize timeout counter
209ALIGN JUMP_ALIGN
210.PollLoop:
211 in al, dx ; Load IDE Status Register
212 test al, FLG_IDE_ST_BSY ; Controller busy?
213 jnz SHORT .UpdateTimeout ; If so, jump to timeout update
214 test al, ah ; Test secondary flag
215 jnz SHORT GetErrorCodeFromPollingToAH ; If set, break loop
216ALIGN JUMP_ALIGN
217.UpdateTimeout:
218 call SoftDelay_UpdTimeout ; Update timeout counter
219 jnc SHORT .PollLoop ; Loop if time left (sets CF on timeout)
220 jmp HError_GetErrorCodeToAHforBitPollingTimeout
221
222;--------------------------------------------------------------------
223; IDE Status register polling.
224; This function waits until controller is not busy.
225;
226; HStatus_PollBsy
227; Parameters:
228; CL: Timeout value in system timer ticks
229; DX: IDE Status Register Address
230; DS: Segment to RAMVARS
231; Returns:
232; AH: BIOS Error code
233; CF: Clear if wait completed successfully (no errors)
234; Set if any error
235; Corrupts registers:
236; AL, CX
237;--------------------------------------------------------------------
238ALIGN JUMP_ALIGN
239HStatus_PollBsy:
240 call SoftDelay_InitTimeout ; Initialize timeout counter
241ALIGN JUMP_ALIGN
242.PollLoop:
243 in al, dx ; Load IDE Status Reg
244 test al, FLG_IDE_ST_BSY ; Controller busy?
245 jz SHORT GetErrorCodeFromPollingToAH ; If not, jump to check errors
246 call SoftDelay_UpdTimeout ; Update timeout counter
247 jnc SHORT .PollLoop ; Loop if time left (sets CF on timeout)
248ALIGN JUMP_ALIGN
249GetErrorCodeFromPollingToAH:
250 jmp HError_GetErrorCodeForStatusReg
Note: See TracBrowser for help on using the repository browser.