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

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

Changes:

  • Minor optimizations to the JR-IDE/ISA code.
  • Some cleanups (the MemoryMappedIDE folder and Bootmenu_SwapDrives.txt were deleted).
File size: 8.1 KB
RevLine 
[400]1; Project name : XTIDE Universal BIOS
2; Description : Memory mapped IDE Device transfer functions.
3
4;
[412]5; XTIDE Universal BIOS and Associated Tools
[400]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.
[412]12;
[400]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
[412]16; GNU General Public License for more details.
[400]17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
[412]18;
[400]19
20; Structure containing variables for PIO transfer functions.
21; This struct must not be larger than IDEPACK without INTPACK.
22struc MEMPIOVARS
23 .wSectorsInBlock resb 2 ; 0, Block size in sectors
24 .bSectorsLeft resb 1 ; 2, Sectors left to transfer
25 .bSectorsDone resb 1 ; 3, Number of sectors xferred
26 resb 3 ; 4, 5, 6
27 resb 1 ; 7, IDEPACK.bDeviceControl
28 .fpDPT resb 4 ; 8, Far pointer to DPT
29endstruc
30
31
32; Section containing code
33SECTION .text
34
35;--------------------------------------------------------------------
36; JrIdeTransfer_StartWithCommandInAL
37; Parameters:
38; AL: IDE command that was used to start the transfer
39; (all PIO read and write commands including Identify Device)
40; ES:SI: Ptr to normalized data buffer
41; DS:DI: Ptr to DPT (in RAMVARS segment)
42; SS:BP: Ptr to IDEPACK
43; Returns:
44; AH: INT 13h Error Code
45; CX: Number of successfully transferred sectors
46; CF: Cleared if success, Set if error
47; Corrupts registers:
48; AL, BX, DX, SI, ES
49;--------------------------------------------------------------------
50ALIGN JUMP_ALIGN
51JrIdeTransfer_StartWithCommandInAL:
52 push cs ; We push CS here (segment of SAW) and later pop it to DS (reads) or ES (writes)
53
54 ; Initialize PIOVARS
55 xor cx, cx
56 mov [bp+MEMPIOVARS.bSectorsDone], cl
57 mov cl, [bp+IDEPACK.bSectorCount]
58 mov [bp+MEMPIOVARS.bSectorsLeft], cl
59 mov cl, [di+DPT_ATA.bBlockSize]
60 mov [bp+MEMPIOVARS.wSectorsInBlock], cx
61 mov [bp+MEMPIOVARS.fpDPT], di
62 mov [bp+MEMPIOVARS.fpDPT+2], ds
63
64 ; Are we reading or writing?
65 test al, 16 ; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
66 jnz SHORT WriteToSectorAccessWindow
67 cmp al, COMMAND_WRITE_MULTIPLE
68 je SHORT WriteToSectorAccessWindow
69 ; Fall to ReadFromSectorAccessWindow
70
71;--------------------------------------------------------------------
72; ReadFromSectorAccessWindow
73; Parameters:
74; Stack: Segment part of ptr to Sector Access Window
75; ES:SI: Normalized ptr to buffer to receive data
76; SS:BP: Ptr to MEMPIOVARS
77; Returns:
78; DS:DI: Ptr to DPT (in RAMVARS segment)
79; AH: BIOS Error code
80; CX: Number of successfully transferred sectors
81; CF: 0 if transfer successful
82; 1 if any error
83; Corrupts registers:
84; AL, BX, DX, SI, ES
85;--------------------------------------------------------------------
86ReadFromSectorAccessWindow:
87 pop ds ; CS -> DS
88 mov di, si ; ES:DI = destination
89 mov si, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET ; DS:SI = source
90
91 call WaitUntilReadyToTransferNextBlock
92 jc SHORT ReturnWithMemoryIOtransferErrorInAH
93
94 mov cx, [bp+MEMPIOVARS.wSectorsInBlock]
[412]95 cmp [bp+MEMPIOVARS.bSectorsLeft], cl
96 jbe SHORT .ReadLastBlockFromDrive
[400]97
98ALIGN JUMP_ALIGN
99.ReadNextBlockFromDrive:
100 call ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
101 call WaitUntilReadyToTransferNextBlock
102 jc SHORT ReturnWithMemoryIOtransferErrorInAH
103
104 ; Increment number of successfully read sectors
105 mov cx, [bp+MEMPIOVARS.wSectorsInBlock]
[412]106 add [bp+MEMPIOVARS.bSectorsDone], cl
[400]107 sub [bp+MEMPIOVARS.bSectorsLeft], cl
[412]108 ja SHORT .ReadNextBlockFromDrive
[400]109
110ALIGN JUMP_ALIGN
111.ReadLastBlockFromDrive:
112 mov cl, [bp+MEMPIOVARS.bSectorsLeft]
113 call ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
114
115 ; Check for errors in last block
116CheckErrorsAfterTransferringLastMemoryMappedBlock:
117 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
118 mov bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
119 call IdeWait_PollStatusFlagInBLwithTimeoutInBH
120
121 ; Return number of successfully transferred sectors
122ReturnWithMemoryIOtransferErrorInAH:
123 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
124%ifdef USE_386
[412]125 movzx cx, [bp+MEMPIOVARS.bSectorsDone]
[400]126%else
127 mov ch, 0
128 mov cl, [bp+MEMPIOVARS.bSectorsDone]
129%endif
130 ret
131
132
133;--------------------------------------------------------------------
134; WriteToSectorAccessWindow
135; Parameters:
136; Stack: Segment part of ptr to Sector Access Window
137; ES:SI: Normalized ptr to buffer containing data
138; SS:BP: Ptr to MEMPIOVARS
139; Returns:
140; DS:DI: Ptr to DPT (in RAMVARS segment)
141; AH: BIOS Error code
142; CX: Number of successfully transferred sectors
143; CF: 0 if transfer successful
144; 1 if any error
145; Corrupts registers:
146; AL, BX, DX, SI, ES
147;--------------------------------------------------------------------
148ALIGN JUMP_ALIGN
149WriteToSectorAccessWindow:
150 push es
151 pop ds
152 pop es ; CS -> ES
153 mov di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
154
155 ; Always poll when writing first block (IRQs are generated for following blocks)
156 call WaitUntilReadyToTransferNextBlock
157 jc SHORT ReturnWithMemoryIOtransferErrorInAH
158
159 mov cx, [bp+MEMPIOVARS.wSectorsInBlock]
[412]160 cmp [bp+MEMPIOVARS.bSectorsLeft], cl
161 jbe SHORT .WriteLastBlockToDrive
[400]162
163ALIGN JUMP_ALIGN
164.WriteNextBlockToDrive:
165 call WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
166 call WaitUntilReadyToTransferNextBlock
167 jc SHORT ReturnWithMemoryIOtransferErrorInAH
168
169 ; Increment number of successfully written WORDs
170 mov cx, [bp+MEMPIOVARS.wSectorsInBlock]
[412]171 add [bp+MEMPIOVARS.bSectorsDone], cl
[400]172 sub [bp+MEMPIOVARS.bSectorsLeft], cl
[412]173 ja SHORT .WriteNextBlockToDrive
[400]174
175ALIGN JUMP_ALIGN
176.WriteLastBlockToDrive:
177 mov cl, [bp+MEMPIOVARS.bSectorsLeft]
178 ePUSH_T bx, CheckErrorsAfterTransferringLastMemoryMappedBlock
179 ; Fall to WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
180
181;--------------------------------------------------------------------
182; WriteSingleBlockFromDSSIToSectorAccessWindowInESDI
183; Parameters:
184; CX: Number of sectors in block
185; DS:SI: Normalized ptr to source buffer
186; ES:DI: Ptr to Sector Access Window
187; Returns:
188; CX, DX: Zero
189; SI: Updated
190; Corrupts registers:
191; BX
192;--------------------------------------------------------------------
193ALIGN JUMP_ALIGN
194WriteSingleBlockFromDSSIToSectorAccessWindowInESDI:
195 mov bx, di
196 mov dx, cx
197 xor cl, cl
198ALIGN JUMP_ALIGN
199.WriteBlock:
200 mov ch, JRIDE_SECTOR_ACCESS_WINDOW_SIZE >> 9
201 rep movsw
202 mov di, bx ; Reset for next sector
203 dec dx
204 jnz SHORT .WriteBlock
205 ret
206
207
208;--------------------------------------------------------------------
209; ReadSingleBlockFromSectorAccessWindowInDSSItoESDI
210; Parameters:
211; CX Number of sectors in block
212; ES:DI: Normalized ptr to buffer to receive data (destination)
213; DS:SI: Ptr to Sector Access Window (source)
214; Returns:
215; CX, DX: Zero
216; DI: Updated
217; Corrupts registers:
218; BX
219;--------------------------------------------------------------------
220ALIGN JUMP_ALIGN
221ReadSingleBlockFromSectorAccessWindowInDSSItoESDI:
222 mov bx, si
223 mov dx, cx
224 xor cl, cl
225ALIGN JUMP_ALIGN
226.ReadBlock:
227 mov ch, JRIDE_SECTOR_ACCESS_WINDOW_SIZE >> 9
228 rep movsw
229 mov si, bx ; Reset for next sector
230 dec dx
231 jnz SHORT .ReadBlock
232 ret
233
234
235;--------------------------------------------------------------------
236; WaitUntilReadyToTransferNextBlock
237; Parameters:
238; SS:BP: Ptr to MEMPIOVARS
239; Returns:
240; AH: INT 13h Error Code
241; CF: Cleared if success, Set if error
242; Corrupts registers:
243; AL, BX, CX, DX
244;--------------------------------------------------------------------
245ALIGN JUMP_ALIGN
246WaitUntilReadyToTransferNextBlock:
247 push ds
248 push di
249 lds di, [bp+MEMPIOVARS.fpDPT] ; DPT now in DS:DI
250 call IdeWait_IRQorDRQ ; Always polls
251 pop di
252 pop ds
253 ret
254
255
256%if JRIDE_SECTOR_ACCESS_WINDOW_SIZE <> 512
[412]257 %error "JRIDE_SECTOR_ACCESS_WINDOW_SIZE is no longer equal to 512. JrIdeTransfer.asm needs changes."
[400]258%endif
Note: See TracBrowser for help on using the repository browser.