source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HPIO.asm@ 57

Last change on this file since 57 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: 9.6 KB
Line 
1; File name : HPIO.asm
2; Project name : IDE BIOS
3; Created date : 14.12.2007
4; Last update : 1.8.2010
5; Author : Tomi Tilli
6; Description : PIO transfer functions.
7
8; Structure containing variables for PIO transfer functions
9struc PIOVARS
10 .fnXfer resb 2 ; Offset to transfer function
11 .wBlockSize resb 2 ; Block size in WORDs
12 .wWordsLeft resb 2 ; Number of WORDs left to transfer
13 ; (full sectors, can be partial block)
14endstruc
15
16
17; Section containing code
18SECTION .text
19
20;--------------------------------------------------------------------
21; Normalizes far pointer to that offset overflows won't happen
22; when transferring data using PIO.
23;
24; HPIO_NORMALIZE_PTR
25; Parameters:
26; %1:%2: Far pointer to normalize
27; %3: Scratch register
28; %4: Scratch register
29; Returns:
30; %1:%2: Normalized far pointer
31; Corrupts registers:
32; %3, %4
33;--------------------------------------------------------------------
34%macro HPIO_NORMALIZE_PTR 4
35 mov %4, %2 ; Copy offset to scratch reg
36 and %2, BYTE 0Fh ; Clear offset bits 15...4
37 eSHR_IM %4, 4 ; Divide offset by 16
38 mov %3, %1 ; Copy segment to scratch reg
39 add %3, %4 ; Add shifted offset to segment
40 mov %1, %3 ; Set normalized segment
41%endmacro
42
43
44;--------------------------------------------------------------------
45; Reads sectors from hard disk using PIO transfer mode.
46;
47; HPIO_ReadBlock
48; Parameters:
49; AL: Number of sectors to read (1...255)
50; ES:BX: Pointer to buffer to recieve data
51; DS:DI: Ptr to Disk Parameter Table
52; Returns:
53; AH: BIOS Error code
54; CF: 0 if transfer succesfull
55; 1 if any error
56; Corrupts registers:
57; AL, BX, CX, DX
58;--------------------------------------------------------------------
59ALIGN JUMP_ALIGN
60HPIO_ReadBlock:
61 push es
62
63 ; Create PIOVARS to stack
64 eENTER PIOVARS_size, 0
65 sub bp, BYTE PIOVARS_size ; SS:BP now points to PIOVARS
66 push si
67 mov si, g_rgfnPioRead ; Offset to read function lookup
68 call HPIO_InitializePIOVARS ; Store word count and block size
69 pop si
70
71 ; Start to read data
72 xchg bx, di ; DS:BX points DPT, ES:DI points buffer
73 mov dx, [RAMVARS.wIdeBase] ; Load IDE Base Port address
74 call HPIO_ReadFromDrive
75
76 ; Destroy stack frame
77 rcl al, 1 ; CF to AL bit 0
78 add bp, BYTE PIOVARS_size
79 eLEAVE
80 rcr al, 1 ; Restore CF
81 mov di, bx ; Restore DI
82 pop es
83 ret
84
85
86;--------------------------------------------------------------------
87; Initializes PIOVARS members.
88;
89; HPIO_InitializePIOVARS
90; Parameters:
91; AL: Number of sectors to transfer (1...255)
92; SI: Offset to transfer function lookup table
93; DS:DI: Ptr to Disk Parameter Table
94; ES:BX: Ptr to source or destination data buffer
95; SS:BP: Ptr to PIOVARS
96; Returns:
97; ES:BX: Normalized pointer to data buffer
98; Corrupts registers:
99; AX, CX
100;--------------------------------------------------------------------
101ALIGN JUMP_ALIGN
102HPIO_InitializePIOVARS:
103 ; Store number of WORDs to transfer
104 mov ah, al ; Number of WORDs to transfer...
105 xor al, al ; ...to AX
106 mov [bp+PIOVARS.wWordsLeft], ax ; Store WORD count
107
108 ; Store block size in WORDs
109 mov ah, [di+DPT.bSetBlock] ; AX = block size in WORDs
110 mov [bp+PIOVARS.wBlockSize], ax ; Store block size
111
112 ; Get transfer function based on bus type
113 xchg ax, bx ; Backup BX
114 eMOVZX bx, BYTE [di+DPT.bIdeOff] ; CS:BX now points to IDEVARS
115 mov bl, BYTE [cs:bx+IDEVARS.bBusType] ; Load bus type to BX
116 mov bx, [cs:bx+si] ; Load offset to transfer function
117 mov [bp+PIOVARS.fnXfer], bx ; Store offset to transfer function
118 xchg bx, ax
119 ; Fall to HPIO_NormalizePtr
120
121;--------------------------------------------------------------------
122; Initializes PIOVARS members.
123;
124; HPIO_InitializePIOVARS
125; Parameters:
126; ES:BX: Ptr to source or destination data buffer
127; Returns:
128; ES:BX: Normalized pointer to data buffer
129; Corrupts registers:
130; AX, CX
131;--------------------------------------------------------------------
132;ALIGN JUMP_ALIGN
133HPIO_NormalizeDataPointer:
134 HPIO_NORMALIZE_PTR es, bx, ax, cx
135 ret
136
137
138;--------------------------------------------------------------------
139; Reads blocks using PIO transfers.
140;
141; HPIO_ReadFromDrive
142; Parameters:
143; DX: IDE Data port address
144; DS:BX: Ptr to DPT (in RAMVARS segment)
145; ES:DI: Normalized ptr to buffer to recieve data
146; SS:BP: Ptr to PIOVARS
147; Returns:
148; AH: BIOS Error code
149; CF: 0 if transfer succesfull
150; 1 if any error
151; Corrupts registers:
152; AL, CX, DX, DI
153;--------------------------------------------------------------------
154ALIGN JUMP_ALIGN
155HPIO_ReadFromDrive:
156 cld ; INS to increment DI
157ALIGN JUMP_ALIGN
158.BlockLoop:
159 call HStatus_WaitIrqOrDrq ; Wait until ready to transfer
160 jc SHORT .RetError ; Return if error (code in AH)
161 mov cx, [bp+PIOVARS.wBlockSize] ; Load block size
162 sub [bp+PIOVARS.wWordsLeft], cx ; Transferring last (possibly partial) block?
163 jbe SHORT .XferLastBlock ; If so, jump to transfer
164 call [bp+PIOVARS.fnXfer] ; Transfer full block
165 jmp SHORT .BlockLoop ; Loop while blocks left
166ALIGN JUMP_ALIGN
167.XferLastBlock:
168 add cx, [bp+PIOVARS.wWordsLeft] ; CX to partial block size
169 call [bp+PIOVARS.fnXfer] ; Transfer possibly partial block
170 jmp HStatus_WaitBsyDefTime ; Check for errors
171.RetError:
172 ret
173
174
175;--------------------------------------------------------------------
176; Writes sectors to hard disk using PIO transfer mode.
177;
178; HPIO_WriteBlock
179; Parameters:
180; AL: Number of sectors to write (1...255)
181; ES:BX: Pointer to buffer containing data
182; DS:DI: Ptr to Disk Parameter Table
183; Returns:
184; AH: BIOS Error code
185; CF: 0 if transfer successfull
186; 1 if any error
187; Corrupts registers:
188; AL, BX, CX, DX
189;--------------------------------------------------------------------
190ALIGN JUMP_ALIGN
191HPIO_WriteBlock:
192 push es
193 push si
194
195 ; Create PIOVARS to stack
196 eENTER PIOVARS_size, 0
197 sub bp, BYTE PIOVARS_size ; SS:BP now points to PIOVARS
198 mov si, g_rgfnPioWrite ; Offset to write function lookup
199 call HPIO_InitializePIOVARS ; Store word count and block size
200
201 ; Prepare pointers and start transfer
202 mov si, bx ; ES:SI now points source buffer
203 mov bx, di ; DS:BX now points DPT
204 call HPIO_WriteToDrive
205
206 ; Destroy stack frame
207 rcl al, 1 ; CF to AL bit 0
208 add bp, BYTE PIOVARS_size
209 eLEAVE
210 rcr al, 1 ; Restore CF
211 pop si
212 pop es
213 ret
214
215;--------------------------------------------------------------------
216; Writes blocks using PIO transfers.
217;
218; HPIO_WriteToDrive
219; Parameters:
220; DS:BX: Ptr to DPT (in RAMVARS segment)
221; ES:SI: Normalized ptr to buffer containing data
222; SS:BP: Ptr to PIOVARS
223; Returns:
224; AH: BIOS Error code
225; CF: 0 if transfer succesfull
226; 1 if any error
227; Corrupts registers:
228; AL, CX, DX, SI
229;--------------------------------------------------------------------
230ALIGN JUMP_ALIGN
231HPIO_WriteToDrive:
232 cld ; OUTS to increment SI
233 call HStatus_WaitDrqDefTime ; Always poll DRQ for first block, get status reg to DX
234 jc SHORT .RetError ; Return if error (code in AH)
235 sub dx, BYTE REGR_IDE_ST ; DX to Data Port address
236ALIGN JUMP_ALIGN
237.BlockLoop:
238 mov cx, [bp+PIOVARS.wBlockSize] ; Load block size
239 sub [bp+PIOVARS.wWordsLeft], cx ; Transferring last (possibly partial) block?
240 jbe SHORT .XferLastBlock ; If so, jump to transfer
241 call [bp+PIOVARS.fnXfer] ; Transfer full block
242 call HStatus_WaitIrqOrDrq ; Wait until ready to transfer
243 jnc SHORT .BlockLoop ; If no error, loop while blocks left
244.RetError:
245 ret
246ALIGN JUMP_ALIGN
247.XferLastBlock:
248 add cx, [bp+PIOVARS.wWordsLeft] ; CX to partial block size
249 call [bp+PIOVARS.fnXfer] ; Transfer possibly partial block
250 jmp HStatus_WaitIrqOrRdy ; Check for errors
251
252
253;--------------------------------------------------------------------
254; Bus specific transfer functions and lookup table.
255;
256; HPIO_DualByteRead Dual port 8-bit XTIDE PIO read transfer
257; HPIO_WordRead Normal 16-bit IDE PIO read transfer
258; HPIO_DualByteWrite Dual port 8-bit XTIDE PIO write transfer
259; HPIO_WordWrite Normal 16-bit IDE PIO write transfer
260; Parameters:
261; CX: Block size in WORDs
262; DX: IDE Data port address
263; ES:DI: Normalized ptr to buffer to recieve data (read only)
264; ES:SI: Normalized ptr to buffer containing data (write only)
265; Returns:
266; Nothing
267; Corrupts registers:
268; AX, CX
269;--------------------------------------------------------------------
270ALIGN JUMP_ALIGN
271HPIO_DualByteRead:
272 eREP_DUAL_BYTE_PORT_INSW
273 ret
274ALIGN JUMP_ALIGN
275HPIO_WordRead:
276 rep
277 db 6Dh ; INSW
278 ret
279ALIGN JUMP_ALIGN
280HPIO_DWordRead:
281 shr cx, 1 ; WORD count to DWORD count
282 rep
283 db 66h ; Override operand size to 32-bit
284 db 6Dh ; INSW/INSD
285 ret
286ALIGN JUMP_ALIGN
287HPIO_SingleByteRead:
288 eREP_SINGLE_BYTE_PORT_INSW
289 ret
290
291ALIGN JUMP_ALIGN
292HPIO_DualByteWrite:
293 eREP_DUAL_BYTE_PORT_OUTSW
294 ret
295ALIGN JUMP_ALIGN
296HPIO_WordWrite:
297 eSEG es ; Source is ES segment
298 rep
299 db 6Fh ; OUTSW
300 ret
301ALIGN JUMP_ALIGN
302HPIO_DWordWrite:
303 shr cx, 1 ; WORD count to DWORD count
304 eSEG es ; Source is ES segment
305 rep
306 db 66h ; Override operand size to 32-bit
307 db 6Fh ; OUTSW/OUTSD
308 ret
309ALIGN JUMP_ALIGN
310HPIO_SingleByteWrite:
311 eREP_SINGLE_BYTE_PORT_OUTSW
312 ret
313
314ALIGN WORD_ALIGN
315g_rgfnPioRead:
316 dw HPIO_DualByteRead ; 8-bit dual port reads
317 dw HPIO_WordRead ; 16-bit reads
318 dw HPIO_DWordRead ; 32-bit reads
319 dw HPIO_SingleByteRead ; 8-bit single port reads
320g_rgfnPioWrite:
321 dw HPIO_DualByteWrite ; 8-bit dual port writes
322 dw HPIO_WordWrite ; 16-bit writes
323 dw HPIO_DWordWrite ; 32-bit writes
324 dw HPIO_SingleByteWrite ; 8-bit single port writes
Note: See TracBrowser for help on using the repository browser.