source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDmaTransfer.asm@ 477

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

Changes to XTIDE Universal BIOS:

  • Added non-working DMA transfer code.
File size: 9.6 KB
Line 
1; Project name : XTIDE Universal BIOS
2; Description : IDE Device DMA transfer functions.
3
4;
5; XTIDE Universal BIOS and Associated Tools
6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2012 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 DMA transfer functions.
21; This struct must not be larger than IDEPACK without INTPACK.
22struc DMAVARS ; Must not be larger than 9 bytes! See IDEPACK in RamVars.inc.
23 .wTotalWordsXferred resb 2 ; 0-1,
24 .wBytesLeftToXferLessOne resb 2 ; 2-3,
25 .bbbPhysicalAddress resb 3 ; 4-6,
26 resb 1 ; 7, IDEPACK.bDeviceControl
27endstruc
28
29
30; Section containing code
31SECTION .text
32
33;--------------------------------------------------------------------
34; IdeDmaTransfer_StartWithCommandInAL
35; Parameters:
36; AL: IDE command that was used to start the transfer
37; (all PIO read and write commands including Identify Device)
38; ES:SI: Ptr to data buffer (not normalized)
39; DS:DI: Ptr to DPT (in RAMVARS segment)
40; SS:BP: Ptr to IDEPACK
41; Returns:
42; AH: INT 13h Error Code
43; CX: Number of successfully transferred sectors
44; CF: Cleared if success, Set if error
45; Corrupts registers:
46; AL, BX, DX
47;--------------------------------------------------------------------
48ALIGN JUMP_ALIGN
49IdeDmaTransfer_StartWithCommandInAL:
50 ; Initialize DMAVARS
51 xor cx, cx
52 mov [bp+DMAVARS.wTotalWordsXferred], cx
53 mov ch, [bp+IDEPACK.bSectorCount] ; CX = WORDs to transfer
54 shl cx, 1 ; WORDs to BYTEs, 0 = 65536
55 dec cx
56 mov [bp+DMAVARS.wBytesLeftToXferLessOne], cx
57
58 ; Convert Segment:Offset type pointer to physical address
59 xor bx, bx
60 mov cx, es
61%rep 4
62 shl cx, 1
63 rcl bx, 1
64%endrep
65 add cx, si
66 adc bl, bh
67 mov [bp+DMAVARS.bbbPhysicalAddress], cx
68 mov [bp+DMAVARS.bbbPhysicalAddress+2], bl
69
70 ; Calculate bytes for first page - 1
71 neg cx ; Max number of bytes for first page, 0 = 65536
72 dec cx
73 MIN_U cx, [bp+DMAVARS.wBytesLeftToXferLessOne]
74
75 ; Are we reading or writing?
76 test al, 16 ; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
77 jnz SHORT WriteBlockToXTCF
78 cmp al, COMMAND_WRITE_MULTIPLE
79 je SHORT WriteBlockToXTCF
80 ; Fall to ReadBlockFromXTCF
81
82
83;--------------------------------------------------------------------
84; ReadBlockFromXTCF
85; Parameters:
86; CX: Bytes in first page - 1
87; DS:DI: Ptr to DPT (in RAMVARS segment)
88; SS:BP: Ptr to DMAVARS
89; Returns:
90; DS:DI: Ptr to DPT (in RAMVARS segment)
91; AH: BIOS Error code
92; CX: Number of successfully transferred sectors
93; CF: 0 if transfer successful
94; 1 if any error
95; Corrupts registers:
96; AL, BX, DX
97;--------------------------------------------------------------------
98ReadBlockFromXTCF:
99 ; 8-bit DMA transfers must be done withing 64k physical page.
100 ; We support maximum of 128 sectors (65536 bytes) per one INT 13h call
101 ; so we might need to separate transfer to 2 separate DMA operations.
102
103 ; Transfer first DMA page
104 mov ah, CHANNEL_3 | WRITE | AUTOINIT_DISABLE | ADDRESS_INCREMENT | DEMAND_MODE
105 call StartDMAtransferForXTCFwithDmaModeInAH
106 jc SHORT ReturnNumberOfSectorsXferred
107
108 ; Transfer second DMA page if necessary (always less than 64k)
109 call UpdateVariablesForSecondPageIfRequired
110 jc SHORT SecondDmaPageIsNotRequired
111 mov ah, CHANNEL_3 | WRITE | AUTOINIT_DISABLE | ADDRESS_INCREMENT | DEMAND_MODE
112 call StartDMAtransferForXTCFwithDmaModeInAH
113 jc SHORT ReturnNumberOfSectorsXferred
114 ; Fall to BothDmaPagesTransferredSuccessfully
115
116BothDmaPagesTransferredSuccessfully:
117 inc cx ; Never overflows since second page always less than 64k
118 shr cx, 1 ; BYTEs to WORDs
119 add [bp+DMAVARS.wTotalWordsXferred], cx
120SecondDmaPageIsNotRequired:
121 xor ah, ah
122ReturnNumberOfSectorsXferred:
123 mov cx, [bp+DMAVARS.wTotalWordsXferred]
124 xchg cl, ch ; WORDs to sectors
125 ret
126
127
128;--------------------------------------------------------------------
129; WriteBlockToXTCF
130; Parameters:
131; CX: Bytes in first page - 1
132; DS:DI: Ptr to DPT (in RAMVARS segment)
133; SS:BP: Ptr to DMAVARS
134; Returns:
135; DS:DI: Ptr to DPT (in RAMVARS segment)
136; AH: BIOS Error code
137; CX: Number of successfully transferred sectors
138; CF: 0 if transfer successful
139; 1 if any error
140; Corrupts registers:
141; AL, BX, DX
142;--------------------------------------------------------------------
143WriteBlockToXTCF:
144 ; Transfer first DMA page
145 mov ah, CHANNEL_3 | READ | AUTOINIT_DISABLE | ADDRESS_INCREMENT | DEMAND_MODE
146 call StartDMAtransferForXTCFwithDmaModeInAH
147 jc SHORT ReturnNumberOfSectorsXferred
148
149 ; Transfer second DMA page if necessary (always less than 64k)
150 call UpdateVariablesForSecondPageIfRequired
151 jc SHORT SecondDmaPageIsNotRequired
152 mov ah, CHANNEL_3 | READ | AUTOINIT_DISABLE | ADDRESS_INCREMENT | DEMAND_MODE
153 call StartDMAtransferForXTCFwithDmaModeInAH
154 jc SHORT ReturnNumberOfSectorsXferred
155 jmp SHORT BothDmaPagesTransferredSuccessfully
156
157
158;--------------------------------------------------------------------
159; StartDMAtransferForXTCFwithDmaModeInAH
160; Parameters:
161; AH: Byte for DMA Mode Register
162; CX: Number of BYTEs to transfer - 1
163; DS:DI: Ptr to DPT (in RAMVARS segment)
164; Returns:
165; AH: BIOS Error code
166; CF: 0 if transfer successful
167; 1 if any error
168; Corrupts registers:
169; AL, BX, DX
170;--------------------------------------------------------------------
171StartDMAtransferForXTCFwithDmaModeInAH:
172 push cx
173
174 ; Program 8-bit DMA Controller
175
176 ; Disable Interrupts and DMA Channel 3 during DMA setup
177 cli ; Disable interrupts
178 mov al, SET_CH3_MASK_BIT
179 out MASK_REGISTER_DMA8_out, al ; Disable DMA Channel 3
180
181 ; Set DMA Mode (read or write using channel 3)
182 mov al, ah
183 out MODE_REGISTER_DMA8_out, al
184
185 ; Set address to DMA controller
186 out CLEAR_FLIPFLOP_DMA8_out, al ; Reset flip-flop to low byte
187 mov ax, [bp+DMAVARS.bbbPhysicalAddress]
188 out BASE_AND_CURRENT_ADDRESS_REGISTER_DMA8_CH3_out, al ; Low byte
189 mov al, ah
190 out BASE_AND_CURRENT_ADDRESS_REGISTER_DMA8_CH3_out, al ; High byte
191 mov al, [bp+DMAVARS.bbbPhysicalAddress+2]
192 out PAGE_DMA8_CH_3, al
193
194 ; Set number of bytes to transfer (DMA controller must be programmed number of bytes - 1)
195 out CLEAR_FLIPFLOP_DMA8_out, al ; Reset flip-flop to low byte
196 mov ax, cx
197 out BASE_AND_CURRENT_COUNT_REGISTER_DMA8_CH3_out, al ; Low byte
198 mov al, ah
199 out BASE_AND_CURRENT_COUNT_REGISTER_DMA8_CH3_out, al ; High byte
200
201 ; Enable DMA Channel 3
202 mov al, CLEAR_CH3_MASK_BIT
203 out MASK_REGISTER_DMA8_out, al ; Enable DMA Channel 3
204 sti ; Enable interrupts
205
206
207 ; XT-CFv2 will present data in 16-byte blocks, but byte count may not
208 ; be divisable by 16 due to boundary crossing. So catch any < 16-byte
209 ; block by adding 15, then dividing bytes (in CX) by 16 to get the
210 ; total block requests. The 8237 is programmed with the actual byte
211 ; count and will end the transfer by asserting TC when done.
212 xor ax, ax
213 add cx, BYTE 1 + 15 ; Number of BYTEs to xfer + 15
214 adc al, ah
215 shr ax, 1
216 rcr cx, 1
217 eSHR_IM cx, 3 ; CX = Number of 16 byte blocks
218 mov dx, [di+DPT.wBasePort]
219 add dl, XTCF_CONTROL_REGISTER
220
221.MoreToDo: ; at this point, cx must be >0
222 mov al, 0x40 ; 0x40 = Raise DRQ and clear XT-CFv2 transfer counter
223.NextDemandBlock:
224 out dx, al ; get up to 16 bytes from XT-CF card
225 loop .NextDemandBlock ; decrement CX and loop if <> 0
226 ; (Loop provides a wait-state between 16-byte blocks; do not unroll)
227
228.CleanUp:
229 ; check the transfer is actually done - in case another DMA operation messed things up
230 inc cx ; set up CX, in case we need to do an extra iteration
231 in al, STATUS_REGISTER_DMA8_in ; get DMA status register
232 test al, FLG_CH3_HAS_REACHED_TERMINAL_COUNT ; test DMA ch.3 TC bit
233 jz SHORT .MoreToDo ; it wasn't set so get more bytes
234
235.EndDMA:
236 mov al, 0x10 ;
237 out dx, al ; set back to DMA enabled status
238
239 ; Check IDE Status Register for errors
240 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_BSY)
241 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
242 pop cx
243 ret
244
245
246;--------------------------------------------------------------------
247; UpdateVariablesForSecondPageIfRequired
248; Parameters:
249; CX: Number of BYTEs in first page - 1
250; SS:BP: Ptr to DMAVARS
251; Returns:
252; CX: Bytes left to transfer - 1 (if CF = 0)
253; CF: 0 if second DMA transfer required
254; 1 if one DMA transfer was enough
255; Corrupts registers:
256; AX, (CX)
257;--------------------------------------------------------------------
258UpdateVariablesForSecondPageIfRequired:
259 inc cx ; BYTEs in first page
260 jcxz .FullPageXferred ; 0 = 65536
261
262 ; Store total WORDs transferred so far
263 mov ax, cx
264 shr ax, 1 ; BYTEs to WORDs
265 mov [bp+DMAVARS.wTotalWordsXferred], ax
266
267 ; Get bytes left to transfer for second DMA page
268 mov ax, [bp+DMAVARS.wBytesLeftToXferLessOne]
269 sub ax, cx
270 jb SHORT .OnePageWasEnough
271
272 ; Increment address
273 add [bp+DMAVARS.bbbPhysicalAddress], cx
274 adc BYTE [bp+DMAVARS.bbbPhysicalAddress+2], 0 ; Never sets CF
275 xchg cx, ax
276 ret
277
278.FullPageXferred:
279 mov WORD [bp+DMAVARS.wTotalWordsXferred], 65536 / 2
280 stc
281.OnePageWasEnough:
282 ret
Note: See TracBrowser for help on using the repository browser.