1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 by Jens Arnold
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 .section .icode,"ax",@progbits
24 .equ .ata_port, 0x20000020
27 .global copy_read_sectors
28 .type copy_read_sectors,@function
30 /* Read a number of words from the ATA data port
32 * Utilises line bursts, assumes there is at least one full line to copy.
35 * (4,%sp) - buffer address
36 * (8,%sp) - word count
39 * %a0 - current address
44 * %d2-%d6 - read buffers
49 movem.l %d2-%d6/%a2, (%sp)
50 movem.l (28, %sp), %a0-%a1
56 btst.l #0, %d0 /* 16-bit aligned? */
57 jeq .r_aligned /* yes, do word copy */
59 /* not 16-bit aligned */
60 subq.l #1, %a1 /* last byte is done unconditionally */
61 moveq.l #24, %d1 /* preload shift count */
63 move.w (%a2), %d2 /* load initial word */
66 move.b %d3, (%a0)+ /* write high byte of it, aligns dest addr */
68 btst.l #1, %d0 /* longword aligned? (testing old d0 value!) */
69 bne.b .r_end_u_w1 /* yes, skip leading word handling */
71 swap %d2 /* move initial word up */
72 move.w (%a2), %d2 /* combine with second word */
75 move.w %d3, (%a0)+ /* write bytes 2 and 3 as word */
80 and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
81 cmp.l %a0, %d0 /* any leading longwords? */
82 bls.b .r_end_u_l1 /* no: skip loop */
85 move.w (%a2), %d3 /* load first word */
86 swap %d3 /* move to upper 16 bit */
87 move.w (%a2), %d3 /* load second word */
91 or.l %d3, %d2 /* combine old low byte with new top 3 bytes */
92 move.l %d2, (%a0)+ /* store as long */
94 cmp.l %a0, %d0 /* run up to first line bound */
98 lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
101 move.w (%a2), %d3 /* load 1st word */
102 swap %d3 /* move to upper 16 bit */
103 move.w (%a2), %d3 /* load 2nd word */
107 or.l %d0, %d2 /* combine old low byte with new top 3 bytes */
108 move.w (%a2), %d4 /* load 3rd word */
109 swap %d4 /* move to upper 16 bit */
110 move.w (%a2), %d4 /* load 4th word */
114 or.l %d0, %d3 /* combine old low byte with new top 3 bytes */
115 move.w (%a2), %d5 /* load 5th word */
116 swap %d5 /* move to upper 16 bit */
117 move.w (%a2), %d5 /* load 6th word */
121 or.l %d0, %d4 /* combine old low byte with new top 3 bytes */
122 move.w (%a2), %d6 /* load 7th word */
123 swap %d6 /* move to upper 16 bit */
124 move.w (%a2), %d6 /* load 8th word */
128 or.l %d0, %d5 /* combine old low byte with new top 3 bytes */
129 movem.l %d2-%d5, (%a0) /* store line */
132 cmp.l %a0, %a1 /* run up to last line bound */
135 lea.l (12, %a1), %a1 /* readjust for longword loop */
136 cmp.l %a0, %a1 /* any trailing longwords? */
137 bls.b .r_end_u_l2 /* no: skip loop */
140 move.w (%a2), %d3 /* load first word */
141 swap %d3 /* move to upper 16 bit */
142 move.w (%a2), %d3 /* load second word */
146 or.l %d3, %d2 /* combine old low byte with new top 3 bytes */
147 move.l %d2, (%a0)+ /* store as long */
149 cmp.l %a0, %a1 /* run up to last long bound */
153 addq.l #2, %a1 /* back to final end address */
154 cmp.l %a0, %a1 /* one word left? */
157 swap %d2 /* move old word to upper 16 bits */
158 move.w (%a2), %d2 /* load final word */
161 move.w %d3, (%a0)+ /* write bytes 2 and 3 as word */
164 move.b %d2, (%a0)+ /* store final byte */
169 btst.l #1, %d0 /* longword aligned? */
170 beq.b .r_end_a_w1 /* yes, skip leading word handling */
172 move.w (%a2), (%a0)+ /* copy initial word */
177 and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
178 cmp.l %a0, %d0 /* any leading longwords? */
179 bls.b .r_end_a_l1 /* no: skip loop */
182 move.w (%a2), %d1 /* load first word */
183 swap %d1 /* move it to upper 16 bits */
184 move.w (%a2), %d1 /* load second word */
185 move.l %d1, (%a0)+ /* store as long */
186 cmp.l %a0, %d0 /* run up to first line bound */
190 lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
193 move.w (%a2), %d0 /* load 1st word */
194 swap %d0 /* move it to upper 16 bits */
195 move.w (%a2), %d0 /* load 2nd word */
196 move.w (%a2), %d1 /* load 3rd word */
197 swap %d1 /* move it to upper 16 bits */
198 move.w (%a2), %d1 /* load 4th word */
199 move.w (%a2), %d2 /* load 5th word */
200 swap %d2 /* move it to upper 16 bits */
201 move.w (%a2), %d2 /* load 6th word */
202 move.w (%a2), %d3 /* load 7th word */
203 swap %d3 /* move it to upper 16 bits */
204 move.w (%a2), %d3 /* load 8th word */
205 movem.l %d0-%d3, (%a0) /* store line */
207 cmp.l %a0, %a1 /* run up to last line bound */
210 lea.l (12, %a1), %a1 /* readjust for longword loop */
211 cmp.l %a0, %a1 /* any trailing longwords? */
212 bls.b .r_end_a_l2 /* no: skip loop */
215 move.w (%a2), %d1 /* read first word */
216 swap %d1 /* move it to upper 16 bits */
217 move.w (%a2), %d1 /* read second word */
218 move.l %d1, (%a0)+ /* store as long */
219 cmp.l %a0, %a1 /* run up to last long bound */
223 addq.l #2, %a1 /* back to final end address */
224 cmp.l %a0, %a1 /* one word left? */
227 move.w (%a2), (%a0)+ /* copy final word */
232 movem.l (%sp), %d2-%d6/%a2
237 .size copy_read_sectors,.r_end-copy_read_sectors
240 .global copy_write_sectors
241 .type copy_write_sectors,@function
243 /* Write a number of words to the ATA data port
245 * Utilises line bursts, assumes there is at least one full line to copy.
248 * (4,%sp) - buffer address
249 * (8,%sp) - word count
252 * %a0 - current address
257 * %d2-%d6 - read buffers
261 lea.l (-24, %sp), %sp
262 movem.l %d2-%d6/%a2, (%sp)
263 movem.l (28, %sp), %a0-%a1
269 btst.l #0, %d0 /* 16-bit aligned? */
270 jeq .w_aligned /* yes, do word copy */
272 /* not 16-bit aligned */
273 subq.l #1, %a1 /* last byte is done unconditionally */
274 moveq.l #24, %d1 /* preload shift count */
278 btst.l #1, %d0 /* longword aligned? (testing old d0 value!) */
279 bne.b .w_end_u_w1 /* yes, skip leading word handling */
290 and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
291 cmp.l %a0, %d0 /* any leading longwords? */
292 bls.b .w_end_u_l1 /* no: skip loop */
305 cmp.l %a0, %d0 /* run up to first line bound */
309 lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
312 movem.l (%a0), %d3-%d6
347 cmp.l %a0, %a1 /* run up to last line bound */
350 lea.l (12, %a1), %a1 /* readjust for longword loop */
351 cmp.l %a0, %a1 /* any trailing longwords? */
352 bls.b .w_end_u_l2 /* no: skip loop */
365 cmp.l %a0, %a1 /* run up to first line bound */
369 addq.l #2, %a1 /* back to final end address */
370 cmp.l %a0, %a1 /* one word left? */
390 move.w (%a0)+, (%a2) /* copy initial word */
395 and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
396 cmp.l %a0, %d0 /* any leading longwords? */
397 bls.b .w_end_a_l1 /* no: skip loop */
405 cmp.l %a0, %d0 /* run up to first line bound */
409 lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
412 movem.l (%a0), %d0-%d3
430 cmp.l %a0, %a1 /* run up to last line bound */
433 lea.l (12, %a1), %a1 /* readjust for longword loop */
434 cmp.l %a0, %a1 /* any trailing longwords? */
435 bls.b .w_end_a_l2 /* no: skip loop */
443 cmp.l %a0, %a1 /* run up to first line bound */
447 addq.l #2, %a1 /* back to final end address */
448 cmp.l %a0, %a1 /* one word left? */
451 move.w (%a0)+, (%a2) /* copy final word */
456 movem.l (%sp), %d2-%d6/%a2
461 .size copy_write_sectors,.w_end-copy_write_sectors