source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Device/IDE/JrIdeTransfer.asm@ 580

Last change on this file since 580 was 545, checked in by aitotat@…, 12 years ago

Changes to XTIDE Universal BIOS:

  • Integrated XT-CFv3 support by James Pearce.
  • XT-CFv2 memory mapped I/O and DMA modes are no longer supported (but PIO mode is).
File size: 9.1 KB
Line 
1; Project name : XTIDE Universal BIOS
2; Description : Memory mapped IDE Device transfer functions.
3
4;
5; XTIDE Universal BIOS and Associated Tools
6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
7;
8; This program is free software; you can redistribute it and/or modify
9; it under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2 of the License, or
11; (at your option) any later version.
12;
13; This program is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16; GNU General Public License for more details.
17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18;
19
20; Structure containing variables for PIO transfer functions.
21; This struct must not be larger than IDEPACK without INTPACK.
22struc MEMPIOVARS ; Must not be larger than 9 bytes! See IDEPACK in RamVars.inc.
23 .wSectorsInBlock resb 2 ; 0-1, Block size in sectors
24 .fpDPT resb 4 ; 2-5, Far pointer to DPT
25 .bSectorsLeft resb 1 ; 6, Sectors left to transfer
26 resb 1 ; 7, IDEPACK.bDeviceControl
27 .bSectorsDone resb 1 ; 8, Number of sectors xferred
28endstruc
29
30
31; Section containing code
32SECTION .text
33
34;--------------------------------------------------------------------
35; JrIdeTransfer_StartWithCommandInAL
36; Parameters:
37; AL: IDE command that was used to start the transfer
38; (all PIO read and write commands including Identify Device)
39; ES:SI: Ptr to data buffer
40; DS:DI: Ptr to DPT (in RAMVARS segment)
41; SS:BP: Ptr to IDEPACK
42; Returns:
43; AH: INT 13h Error Code
44; CX: Number of successfully transferred sectors
45; CF: Cleared if success, Set if error
46; Corrupts registers:
47; AL, BX, DX, SI, ES
48;--------------------------------------------------------------------
49ALIGN JUMP_ALIGN
50JrIdeTransfer_StartWithCommandInAL:
51 ; Initialize MEMPIOVARS
52 xchg cx, ax ; IDE command to CL
53 xor ax, ax
54 mov [bp+MEMPIOVARS.bSectorsDone], al
55 mov dh, [bp+IDEPACK.bSectorCount]
56 mov [bp+MEMPIOVARS.bSectorsLeft], dh
57 mov al, [di+DPT_ATA.bBlockSize]
58 mov [bp+MEMPIOVARS.wSectorsInBlock], ax
59 mov [bp+MEMPIOVARS.fpDPT], di
60 mov [bp+MEMPIOVARS.fpDPT+2], ds
61
62 ; Normalize pointer
63 call IdeTransfer_NormalizePointerInESSI
64%ifdef USE_AT
65 jc SHORT ReturnWithMemoryIOtransferErrorInAH
66%endif
67
68 ; Get far pointer to Sector Access Window
69 cmp BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_JRIDE_ISA
70 mov ds, [di+DPT.wBasePort] ; Segment for JR-IDE/ISA and ADP50L
71 mov di, ADP50L_SECTOR_ACCESS_WINDOW_OFFSET
72 eCMOVE di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
73
74 ; Are we reading or writing?
75.SectorAccessWindowLoadedToDSDI:
76 test cl, 16 ; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
77 jnz SHORT WriteToSectorAccessWindow
78 cmp cl, COMMAND_WRITE_MULTIPLE
79 je SHORT WriteToSectorAccessWindow
80 ; Fall to ReadFromSectorAccessWindow
81
82;--------------------------------------------------------------------
83; ReadFromSectorAccessWindow
84; Parameters:
85; DS:DI: Ptr to Sector Access Window
86; ES:SI: Normalized ptr to buffer to receive data
87; SS:BP: Ptr to MEMPIOVARS
88; Returns:
89; DS:DI: Ptr to DPT (in RAMVARS segment)
90; AH: BIOS Error code
91; CX: Number of successfully transferred sectors
92; CF: 0 if transfer successful
93; 1 if any error
94; Corrupts registers:
95; AL, BX, DX, SI
96;--------------------------------------------------------------------
97ReadFromSectorAccessWindow:
98 xchg si, di ; DS:SI = source, ES:DI = Destination
99 call WaitUntilReadyToTransferNextBlock
100 jc SHORT ReturnWithMemoryIOtransferErrorInAH
101
102 mov cx, [bp+MEMPIOVARS.wSectorsInBlock] ; Clears CH
103 cmp [bp+MEMPIOVARS.bSectorsLeft], cl
104 jbe SHORT .ReadLastBlockFromDrive
105
106ALIGN JUMP_ALIGN
107.ReadNextBlockFromDrive:
108 call ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
109 call WaitUntilReadyToTransferNextBlock
110 jc SHORT ReturnWithMemoryIOtransferErrorInAH
111
112 ; Update number of successfully read sectors and sectors left to transfer.
113 ; We cannot use SUB instruction as a comparison since it will not
114 ; work in this situation:
115 ; Before SUB we have 2 full blocks left to transfer. SUB command
116 ; then compares 2 full blocks against one full block and updates
117 ; sectors left to one full block and jumps to .ReadNextBlockFromDrive,
118 ; since we have one full block left to transfer. After it has been
119 ; transferred, there will be a wait for next block but DRQ is never
120 ; set since all is transferred! Then we get timeout error.
121 mov cx, [bp+MEMPIOVARS.wSectorsInBlock]
122 sub [bp+MEMPIOVARS.bSectorsLeft], cl
123 add [bp+MEMPIOVARS.bSectorsDone], cl
124 cmp [bp+MEMPIOVARS.bSectorsLeft], cl
125 ja SHORT .ReadNextBlockFromDrive
126
127ALIGN JUMP_ALIGN
128.ReadLastBlockFromDrive:
129 mov cl, [bp+MEMPIOVARS.bSectorsLeft]
130 push cx
131 call ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
132
133 ; Check for errors in last block
134CheckErrorsAfterTransferringLastMemoryMappedBlock:
135 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
136 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_BSY)
137 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
138 pop cx ; [bp+MEMPIOVARS.bSectorsLeft]
139 jc SHORT ReturnWithMemoryIOtransferErrorInAH
140
141 ; All sectors successfully transferred
142 add cl, [bp+MEMPIOVARS.bSectorsDone] ; Never sets CF
143 ret
144
145 ; Return number of successfully transferred sectors
146ReturnWithMemoryIOtransferErrorInAH:
147 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
148%ifdef USE_386
149 movzx cx, BYTE [bp+MEMPIOVARS.bSectorsDone]
150%else
151 mov ch, 0 ; Preserve CF
152 mov cl, [bp+MEMPIOVARS.bSectorsDone]
153%endif
154 ret
155
156
157;--------------------------------------------------------------------
158; WriteToSectorAccessWindow
159; Parameters:
160; DS:DI: Ptr to Sector Access Window
161; ES:SI: Normalized ptr to buffer containing data
162; SS:BP: Ptr to MEMPIOVARS
163; Returns:
164; DS:DI: Ptr to DPT (in RAMVARS segment)
165; AH: BIOS Error code
166; CX: Number of successfully transferred sectors
167; CF: 0 if transfer successful
168; 1 if any error
169; Corrupts registers:
170; AL, BX, DX, SI, ES
171;--------------------------------------------------------------------
172ALIGN JUMP_ALIGN
173WriteToSectorAccessWindow:
174 push es
175 push ds
176 pop es ; ES:DI = Sector Access Window (destination)
177 pop ds ; DS:SI = Ptr to source buffer
178
179 ; Always poll when writing first block (IRQs are generated for following blocks)
180 call WaitUntilReadyToTransferNextBlock
181 jc SHORT ReturnWithMemoryIOtransferErrorInAH
182
183 mov cx, [bp+MEMPIOVARS.wSectorsInBlock]
184 cmp [bp+MEMPIOVARS.bSectorsLeft], cl
185 jbe SHORT .WriteLastBlockToDrive
186
187ALIGN JUMP_ALIGN
188.WriteNextBlockToDrive:
189 call WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
190 call WaitUntilReadyToTransferNextBlock
191 jc SHORT ReturnWithMemoryIOtransferErrorInAH
192
193 ; Increment number of successfully written WORDs
194 mov cx, [bp+MEMPIOVARS.wSectorsInBlock]
195 sub [bp+MEMPIOVARS.bSectorsLeft], cl
196 add [bp+MEMPIOVARS.bSectorsDone], cl
197 cmp [bp+MEMPIOVARS.bSectorsLeft], cl
198 ja SHORT .WriteNextBlockToDrive
199
200ALIGN JUMP_ALIGN
201.WriteLastBlockToDrive:
202 mov cl, [bp+MEMPIOVARS.bSectorsLeft]
203 push cx
204 ePUSH_T bx, CheckErrorsAfterTransferringLastMemoryMappedBlock
205 ; Fall to WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
206
207;--------------------------------------------------------------------
208; WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
209; Parameters:
210; CX: Number of sectors in block
211; DS:SI: Normalized ptr to source buffer
212; ES:DI: Ptr to Sector Access Window
213; Returns:
214; CX, DX: Zero
215; SI: Updated
216; Corrupts registers:
217; BX
218;--------------------------------------------------------------------
219ALIGN JUMP_ALIGN
220WriteSingleBlockFromDSSIToSectorAccessWindowInESDI:
221 mov bx, di
222 mov dx, cx
223 xor cx, cx
224ALIGN JUMP_ALIGN
225.WriteNextSector:
226 inc ch
227 rep movsw
228 mov di, bx ; Reset for next sector
229 dec dx
230 jnz SHORT .WriteNextSector
231 ret
232
233
234;--------------------------------------------------------------------
235; ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
236; Parameters:
237; CX Number of sectors in full block or sectors in last partial block
238; ES:DI: Normalized ptr to buffer to receive data (destination)
239; DS:SI: Ptr to Sector Access Window (source)
240; Returns:
241; CX, DX: Zero
242; DI: Updated
243; Corrupts registers:
244; BX
245;--------------------------------------------------------------------
246ALIGN JUMP_ALIGN
247ReadSingleBlockFromSectorAccessWindowInDSSItoESDI:
248 mov bx, si
249 mov dx, cx
250 xor cx, cx
251ALIGN JUMP_ALIGN
252.ReadNextSector:
253 inc ch
254 rep movsw
255 mov si, bx ; Reset for next sector
256 dec dx
257 jnz SHORT .ReadNextSector
258 ret
259
260
261;--------------------------------------------------------------------
262; WaitUntilReadyToTransferNextBlock
263; Parameters:
264; SS:BP: Ptr to MEMPIOVARS
265; Returns:
266; AH: INT 13h Error Code
267; CF: Cleared if success, Set if error
268; Corrupts registers:
269; AL, BX, CX, DX
270;--------------------------------------------------------------------
271ALIGN JUMP_ALIGN
272WaitUntilReadyToTransferNextBlock:
273 push ds
274 push di
275 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
276 call IdeWait_IRQorDRQ ; Always polls
277 pop di
278 pop ds
279 ret
280
Note: See TracBrowser for help on using the repository browser.