From ac85195bb80adbd8c578a34a32fb8859fa57542a Mon Sep 17 00:00:00 2001 From: David Voswinkel Date: Mon, 3 Aug 2009 22:18:34 +0200 Subject: [PATCH] add huffman encoding ontop of the rle --- avr/usbload/huffman-decode.c | 12 ++++---- avr/usbload/main.c | 37 +++++++--------------- avr/usbload/rle.c | 59 ++++++++++++++++++++++++++++++++++++ avr/usbload/rle.h | 1 + 4 files changed, 77 insertions(+), 32 deletions(-) diff --git a/avr/usbload/huffman-decode.c b/avr/usbload/huffman-decode.c index 89f5c48..8fce15d 100644 --- a/avr/usbload/huffman-decode.c +++ b/avr/usbload/huffman-decode.c @@ -18,12 +18,12 @@ */ +#include "huffman-decode.h" #include #include #include #include -#include "huffman-decode.h" #include "info.h" #include "debug.h" @@ -44,7 +44,7 @@ #define ALLOC_ERROR {} -#undef BLOCK_ALLOC 1 +#undef BLOCK_ALLOC typedef struct { int16_t value; @@ -125,9 +125,9 @@ uint8_t build_tree(huffman_dec_ctx_t* ctx){ if(treesize>0x1ff) return 2; #if BLOCK_ALLOC - ctx->tree = calloc(2*treesize-1, sizeof(node_t)); + ctx->tree = malloc((2*treesize-1) * sizeof(node_t)); #else - ctx->tree = calloc(1, sizeof(node_t)); + ctx->tree = malloc(sizeof(node_t)); #endif ((node_t*)(ctx->tree))->value = V_NODE; uint16_t depth=0; @@ -166,7 +166,7 @@ uint8_t build_tree(huffman_dec_ctx_t* ctx){ #if BLOCK_ALLOC current->left=&(((node_t*)(ctx->tree))[treeindex++]); #else - current->left=calloc(1, sizeof(node_t)); + current->left=malloc(sizeof(node_t)); #endif ((node_t*)(current->left))->value = V_NODE; } @@ -179,7 +179,7 @@ uint8_t build_tree(huffman_dec_ctx_t* ctx){ #if BLOCK_ALLOC current->right=&(((node_t*)(ctx->tree))[treeindex++]); #else - current->right=calloc(1, sizeof(node_t)); + current->right=malloc( sizeof(node_t)); #endif ((node_t*)(current->right))->value=V_NODE; } diff --git a/avr/usbload/main.c b/avr/usbload/main.c index 9a0facb..8e933d9 100644 --- a/avr/usbload/main.c +++ b/avr/usbload/main.c @@ -370,18 +370,17 @@ uint16_t read_byte_pgm(uint16_t addr){ return pgm_read_byte((PGM_VOID_P)addr); } -uint16_t read_byte_ee(uint16_t addr){ - return eeprom_read_byte((uint8_t*)addr); -} - - -void decompress(PGM_VOID_P addr, uint16_t(*fp)(uint16_t)){ +void decompress_huffman(PGM_VOID_P addr, uint16_t(*fp)(uint16_t)){ uint16_t c; uint32_t i = 0; huffman_dec_ctx_t ctx; + info("ok1\n"); huffman_dec_init(&ctx, fp); + info("ok2\n"); huffman_dec_set_addr(&ctx, (uint16_t)addr); + info("ok3\n"); while(1){ + info("ok4\n"); i++; c=huffman_dec_byte(&ctx); if (i%1024==0) @@ -394,15 +393,6 @@ void decompress(PGM_VOID_P addr, uint16_t(*fp)(uint16_t)){ } } -void decompress_huffman(void){ - info("Decompress Rom %p to 0x000000\n",(void*)_rom); - sram_bulk_write_start(0x000000); - decompress(&_rom,read_byte_pgm); - sram_bulk_write_end(); - info("Done\n"); -} - - void send_reset(){ info("Reset Snes\n"); @@ -464,18 +454,13 @@ void boot_startup_rom(){ snes_lorom(); info("Set Snes lowrom \n"); -/* - info("Set Snes hirom\n"); - snes_hirom(); - - info("Disable snes WR\n"); - snes_wr_disable(); - info("IRQ off\n"); - snes_irq_lo(); - snes_irq_off(); -*/ - rle_decode(&_rom, ROM_SIZE, 0x000000); + info("Huffman decompress to 0x010000\n",(void*)_rom); + sram_bulk_write_start(0x010000); + decompress_huffman(&_rom,read_byte_pgm); + sram_bulk_write_end(); + info("RLE decompress to 0x000000\n",(void*)_rom); + rle_decode_sram(0x010000, ROM_RLE_SIZE, 0x000000); dump_memory(0x10000 - 0x100, 0x10000); snes_reset_hi(); diff --git a/avr/usbload/rle.c b/avr/usbload/rle.c index e9f2e86..3e21a98 100644 --- a/avr/usbload/rle.c +++ b/avr/usbload/rle.c @@ -96,3 +96,62 @@ uint8_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr) return 0; } + +uint8_t rle_decode_sram(uint32_t in_addr, int32_t in_len, uint32_t out_addr) +{ + uint8_t in_byte, in_repeat, last_byte; + uint32_t out_len, out_len_left; + info("RLE decode len=%li addr=0x%08lx\n",in_len,out_addr); + last_byte = 0; + out_len_left = out_len; +#define INBYTE(b) \ + do { \ + if ( --in_len < 0 ) { \ + return 1; \ + } \ + b = sram_read(in_addr);\ + in_addr++;\ + } while(0) + +#define OUTBYTE(b) \ + do { \ + sram_write(out_addr,b);\ + out_addr++;\ + } while(0) + + INBYTE(in_byte); + + if (in_byte == RUNCHAR) { + INBYTE(in_repeat); + if (in_repeat != 0) { + info("Orphaned RLE code at start\n"); + return 1; + } + OUTBYTE(RUNCHAR); + } else { + OUTBYTE(in_byte); + } + + while( in_len > 0 ) { + INBYTE(in_byte); + if (in_len%1024==0) + info("."); + if (in_byte == RUNCHAR) { + INBYTE(in_repeat); + if ( in_repeat == 0 ) { + /* Just an escaped RUNCHAR value */ + OUTBYTE(RUNCHAR); + } else { + /* Pick up value and output a sequence of it */ + in_byte = last_byte; //;out_data[-1]; + while ( --in_repeat > 0 ) + OUTBYTE(in_byte); + } + } else { + /* Normal byte */ + OUTBYTE(in_byte); + } + last_byte = in_byte; + } + return 0; +} diff --git a/avr/usbload/rle.h b/avr/usbload/rle.h index 9e25601..62ce82f 100644 --- a/avr/usbload/rle.h +++ b/avr/usbload/rle.h @@ -24,5 +24,6 @@ #include uint8_t rle_decode(PGM_VOID_P in_addr,uint32_t in_len, uint32_t out_addr); +uint8_t rle_decode_sram(uint32_t in_addr, int32_t in_len, uint32_t out_addr); #endif