mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-08 20:55:17 -05:00
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
This commit is contained in:
parent
afd2f681d1
commit
2c52dee83f
3 changed files with 164 additions and 72 deletions
|
|
@ -36,8 +36,8 @@ extern char loadaddress[], dramend[];
|
|||
extern void start(void);
|
||||
|
||||
void main(void) ICODE_ATTR;
|
||||
static int ucl_nrv2e_decompress_8(const unsigned char *src, unsigned char *dst,
|
||||
unsigned long *dst_len) ICODE_ATTR;
|
||||
int ucl_nrv2e_decompress_8(const unsigned char *src, unsigned char *dst,
|
||||
unsigned long *dst_len) ICODE_ATTR;
|
||||
|
||||
/* Vector table */
|
||||
void (*vbr[]) (void) __attribute__ ((section (".vectors"))) =
|
||||
|
|
@ -50,71 +50,6 @@ void (*vbr[]) (void) __attribute__ ((section (".vectors"))) =
|
|||
|
||||
/** All subsequent functions are executed from IRAM **/
|
||||
|
||||
/* Thinned out version of the UCL 2e decompression sourcecode
|
||||
* Original (C) Markus F.X.J Oberhumer under GNU GPL license */
|
||||
#define GETBIT(bb, src, ilen) \
|
||||
(((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1)
|
||||
|
||||
static int ucl_nrv2e_decompress_8(const unsigned char *src, unsigned char *dst,
|
||||
unsigned long *dst_len)
|
||||
{
|
||||
unsigned long bb = 0;
|
||||
unsigned ilen = 0, olen = 0, last_m_off = 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned m_off, m_len;
|
||||
|
||||
while (GETBIT(bb,src,ilen))
|
||||
dst[olen++] = src[ilen++];
|
||||
|
||||
m_off = 1;
|
||||
for (;;)
|
||||
{
|
||||
m_off = m_off*2 + GETBIT(bb,src,ilen);
|
||||
if (GETBIT(bb,src,ilen))
|
||||
break;
|
||||
m_off = (m_off-1)*2 + GETBIT(bb,src,ilen);
|
||||
}
|
||||
if (m_off == 2)
|
||||
{
|
||||
m_off = last_m_off;
|
||||
m_len = GETBIT(bb,src,ilen);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_off = (m_off-3)*256 + src[ilen++];
|
||||
if (m_off == 0xffffffff)
|
||||
break;
|
||||
m_len = (m_off ^ 0xffffffff) & 1;
|
||||
m_off >>= 1;
|
||||
last_m_off = ++m_off;
|
||||
}
|
||||
if (m_len)
|
||||
m_len = 1 + GETBIT(bb,src,ilen);
|
||||
else if (GETBIT(bb,src,ilen))
|
||||
m_len = 3 + GETBIT(bb,src,ilen);
|
||||
else
|
||||
{
|
||||
m_len++;
|
||||
do {
|
||||
m_len = m_len*2 + GETBIT(bb,src,ilen);
|
||||
} while (!GETBIT(bb,src,ilen));
|
||||
m_len += 3;
|
||||
}
|
||||
m_len += (m_off > 0x500);
|
||||
{
|
||||
const unsigned char *m_pos;
|
||||
m_pos = dst + olen - m_off;
|
||||
dst[olen++] = *m_pos++;
|
||||
do dst[olen++] = *m_pos++; while (--m_len > 0);
|
||||
}
|
||||
}
|
||||
*dst_len = olen;
|
||||
|
||||
return ilen;
|
||||
}
|
||||
|
||||
#define ALIGNED_IMG_SIZE ((sizeof(image) + 3) & ~3)
|
||||
/* This will never return */
|
||||
void main(void)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue