1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 by Jens Arnold
11 * Copyright (C) 2010 by Marcin Bukat (byte swaps)
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
26 move.l %a3, %d7 | d7 = 0x00FF00FF
27 and.l \dn, %d7 | d7 = .B.D
28 eor.l %d7, \dn | dn = A.C.
29 lsl.l #8, %d7 | d7 = B.D.
30 lsr.l #8, \dn | d3 = .A.C
31 or.l %d7, \dn | dn = BADC
34 .equ .ata_port, 0x20000020
35 .equ .swapmask, 0x00FF00FF
37 .section .icode,"ax",@progbits
40 .global copy_read_sectors
41 .type copy_read_sectors,@function
43 /* Read a number of words from the ATA data port
45 * Utilises line bursts, assumes there is at least one full line to copy.
48 * (4,%sp) - buffer address
49 * (8,%sp) - word count
52 * %a0 - current address
57 * %d2-%d6 - read buffers
59 * #ifdef ATA_SWAP_WORDS
60 * %d7 - byte swap scrach
61 * %a3 - byte swap mask
68 movem.l %d2-%d7/%a2-%a3, (%sp)
69 movem.l (36, %sp), %a0-%a1
73 movem.l %d2-%d6/%a2, (%sp)
74 movem.l (28, %sp), %a0-%a1
81 btst.l #0, %d0 /* 16-bit aligned? */
82 jeq .r_aligned /* yes, do word copy */
84 /* not 16-bit aligned */
85 subq.l #1, %a1 /* last byte is done unconditionally */
86 moveq.l #24, %d1 /* preload shift count */
88 move.w (%a2), %d2 /* load initial word */
95 move.b %d3, (%a0)+ /* write high byte of it, aligns dest addr */
97 btst.l #1, %d0 /* longword aligned? (testing old d0 value!) */
98 bne.b .r_end_u_w1 /* yes, skip leading word handling */
103 move.w %d2, (%a0)+ /* write bytes 2 and 3 as word */
107 swap %d2 /* move initial word up */
108 move.w (%a2), %d2 /* combine with second word */
111 move.w %d3, (%a0)+ /* write bytes 2 and 3 as word */
117 and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
118 cmp.l %a0, %d0 /* any leading longwords? */
119 bls.b .r_end_u_l1 /* no: skip loop */
122 move.w (%a2), %d3 /* load first word */
123 swap %d3 /* move to upper 16 bit */
124 move.w (%a2), %d3 /* load second word */
126 #ifdef ATA_SWAP_WORDS
133 or.l %d3, %d2 /* combine old low byte with new top 3 bytes */
134 move.l %d2, (%a0)+ /* store as long */
136 cmp.l %a0, %d0 /* run up to first line bound */
140 lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
143 move.w (%a2), %d3 /* load 1st word */
144 swap %d3 /* move to upper 16 bit */
145 move.w (%a2), %d3 /* load 2nd word */
147 #ifdef ATA_SWAP_WORDS
154 or.l %d0, %d2 /* combine old low byte with new top 3 bytes */
155 move.w (%a2), %d4 /* load 3rd word */
156 swap %d4 /* move to upper 16 bit */
157 move.w (%a2), %d4 /* load 4th word */
159 #ifdef ATA_SWAP_WORDS
166 or.l %d0, %d3 /* combine old low byte with new top 3 bytes */
167 move.w (%a2), %d5 /* load 5th word */
168 swap %d5 /* move to upper 16 bit */
169 move.w (%a2), %d5 /* load 6th word */
171 #ifdef ATA_SWAP_WORDS
178 or.l %d0, %d4 /* combine old low byte with new top 3 bytes */
179 move.w (%a2), %d6 /* load 7th word */
180 swap %d6 /* move to upper 16 bit */
181 move.w (%a2), %d6 /* load 8th word */
183 #ifdef ATA_SWAP_WORDS
190 or.l %d0, %d5 /* combine old low byte with new top 3 bytes */
191 movem.l %d2-%d5, (%a0) /* store line */
194 cmp.l %a0, %a1 /* run up to last line bound */
197 lea.l (12, %a1), %a1 /* readjust for longword loop */
198 cmp.l %a0, %a1 /* any trailing longwords? */
199 bls.b .r_end_u_l2 /* no: skip loop */
202 move.w (%a2), %d3 /* load first word */
203 swap %d3 /* move to upper 16 bit */
204 move.w (%a2), %d3 /* load second word */
206 #ifdef ATA_SWAP_WORDS
213 or.l %d3, %d2 /* combine old low byte with new top 3 bytes */
214 move.l %d2, (%a0)+ /* store as long */
216 cmp.l %a0, %a1 /* run up to last long bound */
220 blo.b .r_end_u_w2 /* one word left? */
222 #ifdef ATA_SWAP_WORDS
226 move.w %d2, (%a0)+ /* write bytes 2 and 3 as word */
230 move.b %d2, (%a0)+ /* store final byte */
233 swap %d2 /* move old word to upper 16 bits */
234 move.w (%a2), %d2 /* load final word */
237 move.w %d3, (%a0)+ /* write bytes 2 and 3 as word */
239 move.b %d2, (%a0)+ /* store final byte */
245 btst.l #1, %d0 /* longword aligned? */
246 beq.b .r_end_a_w1 /* yes, skip leading word handling */
248 #ifdef ATA_SWAP_WORDS
249 move.w (%a2), %d7 /* copy initial word after byte swap */
254 move.w (%a2), (%a0)+ /* copy initial word */
259 and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
260 cmp.l %a0, %d0 /* any leading longwords? */
261 bls.b .r_end_a_l1 /* no: skip loop */
264 move.w (%a2), %d1 /* load first word */
265 swap %d1 /* move it to upper 16 bits */
266 move.w (%a2), %d1 /* load second word */
268 #ifdef ATA_SWAP_WORDS
272 move.l %d1, (%a0)+ /* store as long */
273 cmp.l %a0, %d0 /* run up to first line bound */
277 lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
280 move.w (%a2), %d0 /* load 1st word */
281 swap %d0 /* move it to upper 16 bits */
282 move.w (%a2), %d0 /* load 2nd word */
283 move.w (%a2), %d1 /* load 3rd word */
284 swap %d1 /* move it to upper 16 bits */
285 move.w (%a2), %d1 /* load 4th word */
286 move.w (%a2), %d2 /* load 5th word */
287 swap %d2 /* move it to upper 16 bits */
288 move.w (%a2), %d2 /* load 6th word */
289 move.w (%a2), %d3 /* load 7th word */
290 swap %d3 /* move it to upper 16 bits */
291 move.w (%a2), %d3 /* load 8th word */
293 #ifdef ATA_SWAP_WORDS
300 movem.l %d0-%d3, (%a0) /* store line */
302 cmp.l %a0, %a1 /* run up to last line bound */
305 lea.l (12, %a1), %a1 /* readjust for longword loop */
306 cmp.l %a0, %a1 /* any trailing longwords? */
307 bls.b .r_end_a_l2 /* no: skip loop */
310 move.w (%a2), %d1 /* read first word */
311 swap %d1 /* move it to upper 16 bits */
312 move.w (%a2), %d1 /* read second word */
314 #ifdef ATA_SWAP_WORDS
318 move.l %d1, (%a0)+ /* store as long */
319 cmp.l %a0, %a1 /* run up to last long bound */
323 blo.b .r_end_a_w2 /* one word left? */
325 #ifdef ATA_SWAP_WORDS
326 move.w (%a2), %d7 /* copy final word after byte swap */
331 move.w (%a2), (%a0)+ /* copy final word */
336 #ifdef ATA_SWAP_WORDS
337 movem.l (%sp), %d2-%d7/%a2-%a3
340 movem.l (%sp), %d2-%d6/%a2
346 .size copy_read_sectors,.r_end-copy_read_sectors
349 .global copy_write_sectors
350 .type copy_write_sectors,@function
352 /* Write a number of words to the ATA data port
354 * Utilises line bursts, assumes there is at least one full line to copy.
357 * (4,%sp) - buffer address
358 * (8,%sp) - word count
361 * %a0 - current address
366 * %d2-%d6 - read buffers
368 * #ifdef ATA_SWAP_WORDS
375 #ifdef ATA_SWAP_WORDS
376 lea.l (-32, %sp), %sp
377 movem.l %d2-%d7/%a2-%a3, (%sp)
378 movem.l (36, %sp), %a0-%a1
381 lea.l (-24, %sp), %sp
382 movem.l %d2-%d6/%a2, (%sp)
383 movem.l (28, %sp), %a0-%a1
390 btst.l #0, %d0 /* 16-bit aligned? */
391 jeq .w_aligned /* yes, do word copy */
393 /* not 16-bit aligned */
394 subq.l #1, %a1 /* last byte is done unconditionally */
395 moveq.l #24, %d1 /* preload shift count */
399 btst.l #1, %d0 /* longword aligned? (testing old d0 value!) */
400 bne.b .w_end_u_w1 /* yes, skip leading word handling */
407 #ifdef ATA_SWAP_WORDS
408 move.l %d3, %d7 /* byte swap low word of %d3 */
419 and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
420 cmp.l %a0, %d0 /* any leading longwords? */
421 bls.b .w_end_u_l1 /* no: skip loop */
430 #ifdef ATA_SWAP_WORDS
439 cmp.l %a0, %d0 /* run up to first line bound */
443 lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
446 movem.l (%a0), %d3-%d6
453 #ifdef ATA_SWAP_WORDS
466 #ifdef ATA_SWAP_WORDS
479 #ifdef ATA_SWAP_WORDS
492 #ifdef ATA_SWAP_WORDS
501 cmp.l %a0, %a1 /* run up to last line bound */
504 lea.l (12, %a1), %a1 /* readjust for longword loop */
505 cmp.l %a0, %a1 /* any trailing longwords? */
506 bls.b .w_end_u_l2 /* no: skip loop */
515 #ifdef ATA_SWAP_WORDS
524 cmp.l %a0, %a1 /* run up to first line bound */
528 blo.b .w_end_u_w2 /* one word left? */
535 #ifdef ATA_SWAP_WORDS
542 #ifdef ATA_SWAP_WORDS
561 #ifdef ATA_SWAP_WORDS
562 move.w (%a0)+, %d1 /* copy initial word bytes swaped */
569 move.w (%a0)+, (%a2) /* copy initial word */
575 and.l #0xFFFFFFF0,%d0 /* d0 == first line bound */
576 cmp.l %a0, %d0 /* any leading longwords? */
577 bls.b .w_end_a_l1 /* no: skip loop */
582 #ifdef ATA_SWAP_WORDS
590 cmp.l %a0, %d0 /* run up to first line bound */
594 lea.l (-14, %a1), %a1 /* adjust end addr. to 16 bytes/pass */
597 movem.l (%a0), %d0-%d3
600 #ifdef ATA_SWAP_WORDS
623 cmp.l %a0, %a1 /* run up to last line bound */
626 lea.l (12, %a1), %a1 /* readjust for longword loop */
627 cmp.l %a0, %a1 /* any trailing longwords? */
628 bls.b .w_end_a_l2 /* no: skip loop */
633 #ifdef ATA_SWAP_WORDS
641 cmp.l %a0, %a1 /* run up to first line bound */
645 blo.b .w_end_a_w2 /* one word left? */
647 #ifdef ATA_SWAP_WORDS
648 move.w (%a0)+, %d0 /* copy final word after byte swap */
655 move.w (%a0)+, (%a2) /* copy final word */
661 #ifdef ATA_SWAP_WORDS
662 movem.l (%sp), %d2-%d7/%a2-%a3
665 movem.l (%sp), %d2-%d6/%a2
671 .size copy_write_sectors,.w_end-copy_write_sectors