summaryrefslogtreecommitdiff
path: root/firmware/target/sh/archos/descramble.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/sh/archos/descramble.S')
-rw-r--r--firmware/target/sh/archos/descramble.S119
1 files changed, 119 insertions, 0 deletions
diff --git a/firmware/target/sh/archos/descramble.S b/firmware/target/sh/archos/descramble.S
new file mode 100644
index 0000000000..70b133460f
--- /dev/null
+++ b/firmware/target/sh/archos/descramble.S
@@ -0,0 +1,119 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2004 by Jens Arnold
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20 .section .icode,"ax",@progbits
21
22 .align 2 /* this aligns to 2^2=4 byte bounday */
23 .global _descramble
24 .type _descramble,@function
25
26/* Descramble a block of byte data, from source to dest, processing len
27 * bytes. Size only limited by the len argument. Note that len must
28 * be an even multiple of 4 (something rolo_load() already assumes.
29 * (Does the Archos firmware loader also require that?).
30 *
31 * Returns the 16-bit "sum" checksum of the descrambled data.
32 *
33 * Arguments:
34 * r4 - source (unsigned char*)
35 * r5 - dest (unsigned char*)
36 * r6 - len (unsigned int)
37 *
38 * Register usage:
39 * r0 - data
40 * r1 - temp
41 * r2 - checksum
42 * r3 - current src address
43 * r4 - source
44 * r5 - dest
45 * r6 - len -> source_end
46 * r7 - dest_end
47 * r8 - len / 4
48 */
49
50_descramble:
51 mov.l r8,@-r15
52 mov r6,r8
53 shlr2 r8 /* r8 = len / 4 */
54 mov r5,r7
55 add r6,r7 /* dest_end = dest + len */
56 add r4,r6 /* source_end = source + len */
57 mov r4,r3 /* addr = source */
58 mov #0,r2 /* checksum = 0 */
59
60.loop:
61 mov.b @r3,r0 /* data = *addr */
62 add r8,r3 /* addr += len / 4 */
63 extu.b r0,r0 /* zero extend data byte */
64 swap.b r0,r1 /* byte swap low word to temp */
65 or r1,r0 /* r0's two lower bytes now identical */
66 shlr r0 /* -> this equals "rotr.b r0" now */
67 not r0,r0 /* negate */
68 extu.b r0,r0 /* zero extend low byte (only needed for sum) */
69 mov.b r0,@r5 /* *dest = data */
70 add r0,r2 /* checksum += data */
71 add #1,r5 /* dest++ */
72 cmp/hi r3,r6 /* addr < source_end ? */
73 bt .loop
74
75 add #1,r4 /* source++ */
76 mov r4,r3 /* addr = source */
77 cmp/hi r5,r7 /* dest < dest_end */
78 bt .loop
79
80/* 15 clock cycles if no reset of source address, 19 if reset,
81 * avg. 16 cycles per byte. Magnus' Version needed 17-22 cycles per byte
82 */
83
84 mov.l @r15+,r8
85 rts
86 extu.w r2,r0
87
88
89/* Move len bytes from source to dest (which must be suitably aligned for
90 * long moves) and jump to dest + 0x200.
91 *
92 * Arguments:
93 * r4 - source
94 * r5 - dest
95 * r6 - len
96 */
97
98 .align 2
99 .global _rolo_restart
100 .type _rolo_restart,@function
101
102_rolo_restart:
103 mov r5,r0
104 sub r4,r0 /* r0 = dest - source */
105 add #-4,r0 /* adjust for early increment */
106 add r4,r6 /* r6 = source + len */
107
108.copy: /* loop takes 6 cycles per longword */
109 mov.l @r4+,r1
110 cmp/hi r4,r6
111 mov.l r1,@(r0,r4)
112 bt .copy
113
114 mov.l @r5+,r0 /* start address from image */
115 jmp @r0
116 mov.l @r5+,r15 /* stack pointer from image */
117
118.end:
119 .size _descramble,.end-_descramble