source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm@ 170

Last change on this file since 170 was 170, checked in by krille_n_@…, 13 years ago

Changes to all parts of the project:

  • Minor size optimizations
  • Commented away some ALIGN JUMP_ALIGN directives in the Int13h handler (they are either in init procedures, procedures that are rarely called or are unnecessary due to conditional assembly)
  • Fixed what appears to be a typo in EBIOS.inc
File size: 11.5 KB
Line 
1; Project name : XTIDE Universal BIOS
2; Description : IDE Device transfer functions.
3
4; Structure containing variables for PIO transfer functions.
5; This struct must not be larger than IDEPACK without INTPACK.
6struc PIOVARS
7 .wBlocksLeft resb 2
8 .wBlockSize resb 2 ; Block size in WORDs (256...32768)
9 .wDataPort resb 2
10 .bSectorsInLastBlock: resb 1
11 resb 1 ; Offset 7 = IDEPACK.bDeviceControl
12 .fnXfer resb 2 ; Offset to transfer function
13endstruc
14
15
16; Section containing code
17SECTION .text
18
19;--------------------------------------------------------------------
20; IdeTransfer_StartWithCommandInAL
21; Parameters:
22; AL: IDE command that was used to start the transfer
23; ES:SI: Ptr to destination buffer or source data
24; DS:DI: Ptr to DPT (in RAMVARS segment)
25; SS:BP: Ptr to IDEPACK
26; Returns:
27; AH: INT 13h Error Code
28; CF: Cleared if success, Set if error
29; Corrupts registers:
30; AL, BX, CX, DX, SI, ES
31;--------------------------------------------------------------------
32ALIGN JUMP_ALIGN
33IdeTransfer_StartWithCommandInAL:
34 mov ah, [bp+IDEPACK.bSectorCountHighExt]
35
36 ; Are we reading or writing?
37 test al, 11001b
38 jpo SHORT .PrepareToWriteDataFromESSI
39
40 ; Prepare to read data to ESSI
41 mov bx, g_rgfnPioRead
42 mov al, [bp+IDEPACK.bSectorCount]
43 call InitializePiovarsInSSBPwithSectorCountInAX
44 xchg si, di
45 call Registers_NormalizeESDI
46 jmp SHORT ReadFromDrive
47
48ALIGN JUMP_ALIGN
49.PrepareToWriteDataFromESSI:
50 mov bx, g_rgfnPioWrite
51 mov al, [bp+IDEPACK.bSectorCount]
52 call InitializePiovarsInSSBPwithSectorCountInAX
53 call Registers_NormalizeESSI
54 ; Fall to WriteToDrive
55
56
57;--------------------------------------------------------------------
58; WriteToDrive
59; Parameters:
60; DS:DI: Ptr to DPT (in RAMVARS segment)
61; ES:SI: Normalized ptr to buffer containing data
62; SS:BP: Ptr to PIOVARS
63; Returns:
64; AH: BIOS Error code
65; CF: 0 if transfer succesfull
66; 1 if any error
67; Corrupts registers:
68; AL, BX, CX, DX, SI, ES
69;--------------------------------------------------------------------
70WriteToDrive:
71 ; Always poll when writing first block (IRQs are generated for following blocks)
72 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRQ)
73 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
74 jc SHORT .ReturnWithTransferErrorInAH
75ALIGN JUMP_ALIGN
76.WriteNextBlock:
77 mov dx, [bp+PIOVARS.wDataPort]
78 dec WORD [bp+PIOVARS.wBlocksLeft] ; Transferring last (possibly partial) block?
79 jz SHORT .XferLastBlock ; If so, jump to transfer
80 mov cx, [bp+PIOVARS.wBlockSize] ; Load block size in WORDs
81 call [bp+PIOVARS.fnXfer] ; Transfer full block
82
83 ; Normalize pointer when necessary
84 mov ax, si
85 shr ax, 1 ; WORD offset
86 add ax, [bp+PIOVARS.wBlockSize]
87 jns SHORT .WaitUntilReadyToTransferNextBlock
88 call Registers_NormalizeESSI
89
90ALIGN JUMP_ALIGN
91.WaitUntilReadyToTransferNextBlock:
92%ifdef USE_186
93 push .WriteNextBlock
94 jmp IdeWait_IRQorDRQ
95%else
96 call IdeWait_IRQorDRQ
97 jnc SHORT .WriteNextBlock
98%endif
99.ReturnWithTransferErrorInAH:
100 ret
101
102ALIGN JUMP_ALIGN
103.XferLastBlock:
104 xor cx, cx
105 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
106 mov ch, [bp+PIOVARS.bSectorsInLastBlock]; CX = Partial block size in WORDs
107%ifdef USE_186
108 push IdeWait_IRQorStatusFlagInBLwithTimeoutInBH
109 jmp [bp+PIOVARS.fnXfer]
110%else
111 call [bp+PIOVARS.fnXfer] ; Transfer possibly partial block
112 jmp IdeWait_IRQorStatusFlagInBLwithTimeoutInBH ; Check for errors
113%endif
114
115
116;--------------------------------------------------------------------
117; ReadFromDrive
118; Parameters:
119; ES:DI: Normalized ptr to buffer to recieve data
120; DS:SI: Ptr to DPT (in RAMVARS segment)
121; SS:BP: Ptr to PIOVARS
122; Returns:
123; DS:DI: Ptr to DPT (in RAMVARS segment)
124; AH: BIOS Error code
125; CF: 0 if transfer succesfull
126; 1 if any error
127; Corrupts registers:
128; AL, BX, CX, DX, SI, ES
129;--------------------------------------------------------------------
130ALIGN JUMP_ALIGN
131ReadFromDrive:
132 ; Wait until drive is ready to transfer
133 xchg di, si ; DS:DI now points DPT
134 call IdeWait_IRQorDRQ ; Wait until ready to transfer
135 jc SHORT WriteToDrive.ReturnWithTransferErrorInAH
136 xchg si, di ; ES:DI now points buffer
137
138 ; Transfer full or last (possible partial) block
139 mov dx, [bp+PIOVARS.wDataPort]
140 dec WORD [bp+PIOVARS.wBlocksLeft]
141 jz SHORT .XferLastBlock
142 mov cx, [bp+PIOVARS.wBlockSize] ; Load block size in WORDs
143 call [bp+PIOVARS.fnXfer] ; Transfer full block
144
145 ; Normalize pointer when necessary
146 mov ax, di
147 shr ax, 1 ; WORD offset
148 add ax, [bp+PIOVARS.wBlockSize]
149 jns SHORT ReadFromDrive
150%ifdef USE_186
151 push ReadFromDrive
152 jmp Registers_NormalizeESDI
153%else
154 call Registers_NormalizeESDI
155 jmp SHORT ReadFromDrive ; Loop while blocks left
156%endif
157
158
159ALIGN JUMP_ALIGN
160.XferLastBlock:
161 xor cx, cx
162 mov ch, [bp+PIOVARS.bSectorsInLastBlock]; CX = Partial block size in WORDs
163 call [bp+PIOVARS.fnXfer] ; Transfer possibly partial block
164 mov di, si ; DS:DI now points DPT
165 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
166 jmp IdeWait_PollStatusFlagInBLwithTimeoutInBH
167
168
169;--------------------------------------------------------------------
170; InitializePiovarsInSSBPwithSectorCountInAX
171; Parameters:
172; AX: Number of sectors to transfer (1...65535)
173; BX: Offset to transfer function lookup table
174; DS:DI: Ptr to DPT (in RAMVARS segment)
175; SS:BP: Ptr to PIOVARS
176; Returns:
177; Nothing
178; Corrupts registers:
179; AX, BX, CX, DX
180;--------------------------------------------------------------------
181ALIGN JUMP_ALIGN
182InitializePiovarsInSSBPwithSectorCountInAX:
183 ; Store number of blocks to transfer
184 eMOVZX cx, BYTE [di+DPT_ATA.bSetBlock] ; Block size in sectors
185 xor dx, dx ; DX:AX = Sectors to transfer (1...65535)
186 div cx ; AX = Full blocks to transfer
187 test dx, dx
188 mov dh, cl ; DH = Full block size if no partial blocks to transfer
189 jz SHORT .NoPartialBlocksToTransfer
190 inc ax ; Partial block
191 mov dh, dl ; DH = Size of partial block in sectors
192.NoPartialBlocksToTransfer:
193 mov [bp+PIOVARS.wBlocksLeft], ax
194 mov [bp+PIOVARS.bSectorsInLastBlock], dh
195
196 ; Store block size in WORDs
197 xchg ch, cl ; CX = Block size in WORDs
198 mov [bp+PIOVARS.wBlockSize], cx
199
200 ; Get transfer function based on bus type
201 xchg ax, bx ; Lookup table offset to AX
202 eMOVZX bx, BYTE [di+DPT.bIdevarsOffset] ; CS:BX now points to IDEVARS
203 mov dx, [cs:bx+IDEVARS.wPort] ; Load IDE Data port address
204 mov bl, [cs:bx+IDEVARS.bDevice] ; Load device type to BX
205 add bx, ax
206 mov ax, [cs:bx] ; Load offset to transfer function
207 mov [bp+PIOVARS.wDataPort], dx
208 mov [bp+PIOVARS.fnXfer], ax
209 ret
210
211
212;--------------------------------------------------------------------
213; DualByteReadForXtide Dual port 8-bit XTIDE PIO read transfer
214; SingleByteRead Single port 8-bit PIO read transfer
215; WordReadForXTIDEmod 8088/8086 compatible 16-bit IDE PIO read transfer
216; WordReadForXTplusAndAT Normal 16-bit IDE PIO read transfer
217; DWordRead VLB/PCI 32-bit IDE PIO read transfer
218; Parameters:
219; CX: Block size in WORDs
220; DX: IDE Data port address
221; ES:DI: Normalized ptr to buffer to recieve data
222; Returns:
223; Nothing
224; Corrupts registers:
225; AX, BX, CX
226;--------------------------------------------------------------------
227ALIGN JUMP_ALIGN
228DualByteReadForXtide:
229%ifdef USE_186
230 shr cx, 2 ; Smaller but slower on 186/286
231%else
232 times 2 shr cx, 1 ; Loop unrolling
233%endif
234 mov bx, 8 ; Bit mask for toggling data low/high reg
235ALIGN JUMP_ALIGN
236.InswLoop:
237 XTIDE_INSW
238 XTIDE_INSW
239 XTIDE_INSW
240 XTIDE_INSW
241 loop .InswLoop
242 ret
243
244;----
245ALIGN JUMP_ALIGN
246SingleByteRead:
247%ifdef USE_186 ; INS instruction available
248 shl cx, 1 ; WORD count to BYTE count
249 rep insb
250%else ; If 8088/8086
251 shr cx, 1 ; WORD count to DWORD count
252ALIGN JUMP_ALIGN
253.InsdLoop:
254 in al, dx
255 stosb ; Store to [ES:DI]
256 in al, dx
257 stosb
258 in al, dx
259 stosb
260 in al, dx
261 stosb
262 loop .InsdLoop
263%endif
264 ret
265
266;----
267%ifndef USE_186
268ALIGN JUMP_ALIGN
269WordReadForXTIDEmod:
270 times 2 shr cx, 1 ; WORD count to QWORD count
271ALIGN JUMP_ALIGN
272.ReadNextQword:
273 in ax, dx ; Read 1st WORD
274 stosw ; Store 1st WORD to [ES:DI]
275 in ax, dx
276 stosw ; 2nd
277 in ax, dx
278 stosw ; 3rd
279 in ax, dx
280 stosw ; 4th
281 loop .ReadNextQword
282 ret
283%endif
284
285;----
286ALIGN JUMP_ALIGN
287WordReadForXTplusAndAT:
288 rep
289 db 6Dh ; INSW (we want this in XT build)
290 ret
291
292;----
293ALIGN JUMP_ALIGN
294DWordRead:
295 shr cx, 1 ; WORD count to DWORD count
296 rep
297 db 66h ; Override operand size to 32-bit
298 db 6Dh ; INSW/INSD
299 ret
300
301
302;--------------------------------------------------------------------
303; DualByteWriteForXtide Dual port 8-bit XTIDE PIO write transfer
304; SingleByteWrite Single port 8-bit PIO write transfer
305; WordWriteForXTIDEmod 8088/8086 compatible 16-bit IDE PIO read transfer
306; WordWrite Normal 16-bit IDE PIO write transfer
307; DWordWrite VLB/PCI 32-bit IDE PIO write transfer
308; Parameters:
309; CX: Block size in WORDs
310; DX: IDE Data port address
311; ES:SI: Normalized ptr to buffer containing data
312; Returns:
313; Nothing
314; Corrupts registers:
315; AX, CX
316;--------------------------------------------------------------------
317ALIGN JUMP_ALIGN
318DualByteWriteForXtide:
319 push ds
320 push bx
321%ifdef USE_186
322 shr cx, 2 ; Smaller but slower on 186/286
323%else
324 times 2 shr cx, 1 ; Loop unrolling
325%endif
326 mov bx, 8 ; Bit mask for toggling data low/high reg
327 push es ; Copy ES...
328 pop ds ; ...to DS
329ALIGN JUMP_ALIGN
330.OutswLoop:
331 XTIDE_OUTSW
332 XTIDE_OUTSW
333 XTIDE_OUTSW
334 XTIDE_OUTSW
335 loop .OutswLoop
336 pop bx
337 pop ds
338 ret
339
340;----
341ALIGN JUMP_ALIGN
342SingleByteWrite:
343%ifdef USE_186 ; OUTS instruction available
344 shl cx, 1 ; WORD count to BYTE count
345 eSEG es ; Source is ES segment
346 rep outsb
347%else ; If 8088/8086
348 shr cx, 1 ; WORD count to DWORD count
349 push ds ; Store DS
350 push es ; Copy ES...
351 pop ds ; ...to DS
352ALIGN JUMP_ALIGN
353.OutsdLoop:
354 lodsb ; Load from [DS:SI] to AL
355 out dx, al
356 lodsb
357 out dx, al
358 lodsb
359 out dx, al
360 lodsb
361 out dx, al
362 loop .OutsdLoop
363 pop ds ; Restore DS
364%endif
365 ret
366
367;---
368ALIGN JUMP_ALIGN
369WordWriteForXTIDEmod:
370 push ds
371%ifdef USE_186
372 shr cx, 2 ; Smaller but slower on 186/286
373%else
374 times 2 shr cx, 1 ; Loop unrolling
375%endif
376 push es ; Copy ES...
377 pop ds ; ...to DS
378ALIGN JUMP_ALIGN
379.WriteNextQword:
380 XTIDE_MOD_OUTSW
381 XTIDE_MOD_OUTSW
382 XTIDE_MOD_OUTSW
383 XTIDE_MOD_OUTSW
384 loop .WriteNextQword
385 pop ds
386 ret
387
388;----
389ALIGN JUMP_ALIGN
390WordWrite:
391 eSEG es ; Source is ES segment
392 rep
393 db 6Fh ; OUTSW (we want this in XT build)
394 ret
395
396ALIGN JUMP_ALIGN
397DWordWrite:
398 shr cx, 1 ; WORD count to DWORD count
399 eSEG es ; Source is ES segment
400 rep
401 db 66h ; Override operand size to 32-bit
402 db 6Fh ; OUTSW/OUTSD
403 ret
404
405
406
407; Lookup tables to get transfer function based on bus type
408ALIGN WORD_ALIGN
409g_rgfnPioRead:
410 dw DualByteReadForXtide ; DEVICE_8BIT_DUAL_PORT_XTIDE
411%ifdef USE_186
412 dw WordReadForXTplusAndAT ; DEVICE_XTIDE_WITH_REVERSED_A3_AND_A0
413%else
414 dw WordReadForXTIDEmod
415%endif
416 dw SingleByteRead ; DEVICE_8BIT_SINGLE_PORT
417 dw WordReadForXTplusAndAT ; DEVICE_16BIT_ATA
418 dw DWordRead ; DEVICE_32BIT_ATA
419
420g_rgfnPioWrite:
421 dw DualByteWriteForXtide ; DEVICE_8BIT_DUAL_PORT_XTIDE
422 dw WordWriteForXTIDEmod ; DEVICE_XTIDE_WITH_REVERSED_A3_AND_A0
423 dw SingleByteWrite ; DEVICE_8BIT_SINGLE_PORT
424 dw WordWrite ; DEVICE_16BIT_ATA
425 dw DWordWrite ; DEVICE_32BIT_ATA
Note: See TracBrowser for help on using the repository browser.