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

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

Changes:

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