diff options
author | Jens Arnold <amiconn@rockbox.org> | 2008-10-28 21:07:53 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2008-10-28 21:07:53 +0000 |
commit | 2c52dee83f5c796fe471e6fab15dea17a2f508ff (patch) | |
tree | 4f90ccd3c1d5785385fea9144e5011b1943acfcd /firmware/decompressor/decompressor.c | |
parent | afd2f681d18e574442f8569f1a722d5d39d79b78 (diff) | |
download | rockbox-2c52dee83f5c796fe471e6fab15dea17a2f508ff.tar.gz rockbox-2c52dee83f5c796fe471e6fab15dea17a2f508ff.zip |
Self-extractor for on-disk firmware image: UCL decompressor in SH1 assembler - less than half the size of the compiled C function, and ~45% faster.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18904 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/decompressor/decompressor.c')
-rw-r--r-- | firmware/decompressor/decompressor.c | 69 |
1 files changed, 2 insertions, 67 deletions
diff --git a/firmware/decompressor/decompressor.c b/firmware/decompressor/decompressor.c index cec82b8b09..11888ef272 100644 --- a/firmware/decompressor/decompressor.c +++ b/firmware/decompressor/decompressor.c | |||
@@ -36,8 +36,8 @@ extern char loadaddress[], dramend[]; | |||
36 | extern void start(void); | 36 | extern void start(void); |
37 | 37 | ||
38 | void main(void) ICODE_ATTR; | 38 | void main(void) ICODE_ATTR; |
39 | static int ucl_nrv2e_decompress_8(const unsigned char *src, unsigned char *dst, | 39 | int ucl_nrv2e_decompress_8(const unsigned char *src, unsigned char *dst, |
40 | unsigned long *dst_len) ICODE_ATTR; | 40 | unsigned long *dst_len) ICODE_ATTR; |
41 | 41 | ||
42 | /* Vector table */ | 42 | /* Vector table */ |
43 | void (*vbr[]) (void) __attribute__ ((section (".vectors"))) = | 43 | void (*vbr[]) (void) __attribute__ ((section (".vectors"))) = |
@@ -50,71 +50,6 @@ void (*vbr[]) (void) __attribute__ ((section (".vectors"))) = | |||
50 | 50 | ||
51 | /** All subsequent functions are executed from IRAM **/ | 51 | /** All subsequent functions are executed from IRAM **/ |
52 | 52 | ||
53 | /* Thinned out version of the UCL 2e decompression sourcecode | ||
54 | * Original (C) Markus F.X.J Oberhumer under GNU GPL license */ | ||
55 | #define GETBIT(bb, src, ilen) \ | ||
56 | (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1) | ||
57 | |||
58 | static int ucl_nrv2e_decompress_8(const unsigned char *src, unsigned char *dst, | ||
59 | unsigned long *dst_len) | ||
60 | { | ||
61 | unsigned long bb = 0; | ||
62 | unsigned ilen = 0, olen = 0, last_m_off = 1; | ||
63 | |||
64 | for (;;) | ||
65 | { | ||
66 | unsigned m_off, m_len; | ||
67 | |||
68 | while (GETBIT(bb,src,ilen)) | ||
69 | dst[olen++] = src[ilen++]; | ||
70 | |||
71 | m_off = 1; | ||
72 | for (;;) | ||
73 | { | ||
74 | m_off = m_off*2 + GETBIT(bb,src,ilen); | ||
75 | if (GETBIT(bb,src,ilen)) | ||
76 | break; | ||
77 | m_off = (m_off-1)*2 + GETBIT(bb,src,ilen); | ||
78 | } | ||
79 | if (m_off == 2) | ||
80 | { | ||
81 | m_off = last_m_off; | ||
82 | m_len = GETBIT(bb,src,ilen); | ||
83 | } | ||
84 | else | ||
85 | { | ||
86 | m_off = (m_off-3)*256 + src[ilen++]; | ||
87 | if (m_off == 0xffffffff) | ||
88 | break; | ||
89 | m_len = (m_off ^ 0xffffffff) & 1; | ||
90 | m_off >>= 1; | ||
91 | last_m_off = ++m_off; | ||
92 | } | ||
93 | if (m_len) | ||
94 | m_len = 1 + GETBIT(bb,src,ilen); | ||
95 | else if (GETBIT(bb,src,ilen)) | ||
96 | m_len = 3 + GETBIT(bb,src,ilen); | ||
97 | else | ||
98 | { | ||
99 | m_len++; | ||
100 | do { | ||
101 | m_len = m_len*2 + GETBIT(bb,src,ilen); | ||
102 | } while (!GETBIT(bb,src,ilen)); | ||
103 | m_len += 3; | ||
104 | } | ||
105 | m_len += (m_off > 0x500); | ||
106 | { | ||
107 | const unsigned char *m_pos; | ||
108 | m_pos = dst + olen - m_off; | ||
109 | dst[olen++] = *m_pos++; | ||
110 | do dst[olen++] = *m_pos++; while (--m_len > 0); | ||
111 | } | ||
112 | } | ||
113 | *dst_len = olen; | ||
114 | |||
115 | return ilen; | ||
116 | } | ||
117 | |||
118 | #define ALIGNED_IMG_SIZE ((sizeof(image) + 3) & ~3) | 53 | #define ALIGNED_IMG_SIZE ((sizeof(image) + 3) & ~3) |
119 | /* This will never return */ | 54 | /* This will never return */ |
120 | void main(void) | 55 | void main(void) |