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

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

Changes to XTIDE Universal BIOS:

  • Large changes to prepare full XT-CF support (DMA not yet implemented and memory mapped transfers are not working).
File size: 8.9 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-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 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
30SECTOR_ACCESS_WINDOW_SIZE EQU 512 ; 512 bytes
31
32
33; Section containing code
34SECTION .text
35
36;--------------------------------------------------------------------
37; JrIdeTransfer_StartWithCommandInAL
38; Parameters:
39; AL: IDE command that was used to start the transfer
40; (all PIO read and write commands including Identify Device)
41; ES:SI: Ptr to normalized data buffer (SI 0...15)
42; DS:DI: Ptr to DPT (in RAMVARS segment)
43; SS:BP: Ptr to IDEPACK
44; Returns:
45; AH: INT 13h Error Code
46; CX: Number of successfully transferred sectors
47; CF: Cleared if success, Set if error
48; Corrupts registers:
49; AL, BX, DX, SI, ES
50;--------------------------------------------------------------------
51ALIGN JUMP_ALIGN
52JrIdeTransfer_StartWithCommandInAL:
53 ; Initialize MEMPIOVARS
54 xchg cx, ax ; IDE command to CL
55 xor ax, ax
56 mov [bp+MEMPIOVARS.bSectorsDone], al
57 mov al, [bp+IDEPACK.bSectorCount]
58 mov [bp+MEMPIOVARS.bSectorsLeft], al
59 mov al, [di+DPT_ATA.bBlockSize]
60 mov [bp+MEMPIOVARS.wSectorsInBlock], ax
61 mov [bp+MEMPIOVARS.fpDPT], di
62 mov [bp+MEMPIOVARS.fpDPT+2], ds
63
64 ; Get far pointer to Sector Access Window
65 mov dx, [di+DPT.wBasePort]
66 cmp BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_JRIDE_ISA
67 jne SHORT .GetSectorAccessWindowForXTCF
68
69 ; Get Sector Access Window for JR-IDE/ISA
70 mov di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
71 mov ds, dx ; Segment for JR-IDE/ISA
72 jmp SHORT .SectorAccessWindowLoadedToDSDI
73
74.GetSectorAccessWindowForXTCF:
75 xor di, di
76 add dl, XTCF_CONTROL_REGISTER
77 in al, dx ; Read high byte for Sector Access Window segment
78 xchg ah, al
79 mov ds, ax
80
81 ; Are we reading or writing?
82.SectorAccessWindowLoadedToDSDI:
83 test cl, 16 ; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
84 jnz SHORT WriteToSectorAccessWindow
85 cmp cl, COMMAND_WRITE_MULTIPLE
86 je SHORT WriteToSectorAccessWindow
87 ; Fall to ReadFromSectorAccessWindow
88
89;--------------------------------------------------------------------
90; ReadFromSectorAccessWindow
91; Parameters:
92; DS:DI: Ptr to Sector Access Window
93; ES:SI: Normalized ptr to buffer to receive data
94; SS:BP: Ptr to MEMPIOVARS
95; Returns:
96; DS:DI: Ptr to DPT (in RAMVARS segment)
97; AH: BIOS Error code
98; CX: Number of successfully transferred sectors
99; CF: 0 if transfer successful
100; 1 if any error
101; Corrupts registers:
102; AL, BX, DX, SI, ES
103;--------------------------------------------------------------------
104ReadFromSectorAccessWindow:
105 xchg si, di ; DS:SI = source, ES:DI = Destination
106 call WaitUntilReadyToTransferNextBlock
107 jc SHORT ReturnWithMemoryIOtransferErrorInAH
108
109 mov cx, [bp+MEMPIOVARS.wSectorsInBlock]
110 cmp [bp+MEMPIOVARS.bSectorsLeft], cl
111 jbe SHORT .ReadLastBlockFromDrive
112
113ALIGN JUMP_ALIGN
114.ReadNextBlockFromDrive:
115 call ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
116 call WaitUntilReadyToTransferNextBlock
117 jc SHORT ReturnWithMemoryIOtransferErrorInAH
118
119 ; Increment number of successfully read sectors
120 mov cx, [bp+MEMPIOVARS.wSectorsInBlock]
121 add [bp+MEMPIOVARS.bSectorsDone], cl
122 sub [bp+MEMPIOVARS.bSectorsLeft], cl
123 ja SHORT .ReadNextBlockFromDrive
124
125ALIGN JUMP_ALIGN
126.ReadLastBlockFromDrive:
127 mov cl, [bp+MEMPIOVARS.bSectorsLeft]
128 push cx
129 call ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
130
131 ; Check for errors in last block
132CheckErrorsAfterTransferringLastMemoryMappedBlock:
133 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
134 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_BSY)
135 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
136 pop cx ; [bp+MEMPIOVARS.bSectorsLeft]
137 jc SHORT ReturnWithMemoryIOtransferErrorInAH
138
139 ; All sectors successfully transferred
140 add cx, [bp+PIOVARS.bSectorsDone] ; Never sets CF
141 ret
142
143 ; Return number of successfully transferred sectors
144ReturnWithMemoryIOtransferErrorInAH:
145 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
146%ifdef USE_386
147 movzx cx, [bp+MEMPIOVARS.bSectorsDone]
148%else
149 mov ch, 0
150 mov cl, [bp+MEMPIOVARS.bSectorsDone]
151%endif
152 ret
153
154
155;--------------------------------------------------------------------
156; WriteToSectorAccessWindow
157; Parameters:
158; DS:DI: Ptr to Sector Access Window
159; ES:SI: Normalized ptr to buffer containing data
160; SS:BP: Ptr to MEMPIOVARS
161; Returns:
162; DS:DI: Ptr to DPT (in RAMVARS segment)
163; AH: BIOS Error code
164; CX: Number of successfully transferred sectors
165; CF: 0 if transfer successful
166; 1 if any error
167; Corrupts registers:
168; AL, BX, DX, SI, ES
169;--------------------------------------------------------------------
170ALIGN JUMP_ALIGN
171WriteToSectorAccessWindow:
172 push es
173 push ds
174 pop es ; ES:DI = Sector Access Window (destination)
175 pop ds ; DS:SI = Ptr to source buffer
176
177 ; Always poll when writing first block (IRQs are generated for following blocks)
178 call WaitUntilReadyToTransferNextBlock
179 jc SHORT ReturnWithMemoryIOtransferErrorInAH
180
181 mov cx, [bp+MEMPIOVARS.wSectorsInBlock]
182 cmp [bp+MEMPIOVARS.bSectorsLeft], cl
183 jbe SHORT .WriteLastBlockToDrive
184
185ALIGN JUMP_ALIGN
186.WriteNextBlockToDrive:
187 call WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
188 call WaitUntilReadyToTransferNextBlock
189 jc SHORT ReturnWithMemoryIOtransferErrorInAH
190
191 ; Increment number of successfully written WORDs
192 mov cx, [bp+MEMPIOVARS.wSectorsInBlock]
193 add [bp+MEMPIOVARS.bSectorsDone], cl
194 sub [bp+MEMPIOVARS.bSectorsLeft], cl
195 ja SHORT .WriteNextBlockToDrive
196
197ALIGN JUMP_ALIGN
198.WriteLastBlockToDrive:
199 mov cl, [bp+MEMPIOVARS.bSectorsLeft]
200 push cx
201 ePUSH_T bx, CheckErrorsAfterTransferringLastMemoryMappedBlock
202 ; Fall to WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
203
204;--------------------------------------------------------------------
205; WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
206; Parameters:
207; CX: Number of sectors in block
208; DS:SI: Normalized ptr to source buffer
209; ES:DI: Ptr to Sector Access Window
210; Returns:
211; CX, DX: Zero
212; SI: Updated
213; Corrupts registers:
214; BX
215;--------------------------------------------------------------------
216ALIGN JUMP_ALIGN
217WriteSingleBlockFromDSSIToSectorAccessWindowInESDI:
218 mov bx, di
219 mov dx, cx
220 xor cl, cl
221ALIGN JUMP_ALIGN
222.WriteBlock:
223 mov ch, SECTOR_ACCESS_WINDOW_SIZE >> 9
224 rep movsw
225 mov di, bx ; Reset for next sector
226 dec dx
227 jnz SHORT .WriteBlock
228 ret
229
230
231;--------------------------------------------------------------------
232; ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
233; Parameters:
234; CX Number of sectors in block
235; ES:DI: Normalized ptr to buffer to receive data (destination)
236; DS:SI: Ptr to Sector Access Window (source)
237; Returns:
238; CX, DX: Zero
239; DI: Updated
240; Corrupts registers:
241; BX
242;--------------------------------------------------------------------
243ALIGN JUMP_ALIGN
244ReadSingleBlockFromSectorAccessWindowInDSSItoESDI:
245 mov bx, si
246 mov dx, cx
247 xor cl, cl
248ALIGN JUMP_ALIGN
249.ReadBlock:
250 mov ch, SECTOR_ACCESS_WINDOW_SIZE >> 9
251 rep movsw
252 mov si, bx ; Reset for next sector
253 dec dx
254 jnz SHORT .ReadBlock
255 ret
256
257
258;--------------------------------------------------------------------
259; WaitUntilReadyToTransferNextBlock
260; Parameters:
261; SS:BP: Ptr to MEMPIOVARS
262; Returns:
263; AH: INT 13h Error Code
264; CF: Cleared if success, Set if error
265; Corrupts registers:
266; AL, BX, CX, DX
267;--------------------------------------------------------------------
268ALIGN JUMP_ALIGN
269WaitUntilReadyToTransferNextBlock:
270 push ds
271 push di
272 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
273 call IdeWait_IRQorDRQ ; Always polls
274 pop di
275 pop ds
276 ret
277
278
279%if SECTOR_ACCESS_WINDOW_SIZE <> 512
280 %error "SECTOR_ACCESS_WINDOW_SIZE is no longer equal to 512. JrIdeTransfer.asm needs changes."
281%endif
Note: See TracBrowser for help on using the repository browser.