rle.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * =====================================================================================
  3. *
  4. * ________ .__ __ ________ ____ ________
  5. * \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
  6. * / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
  7. * / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
  8. * \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
  9. * \__> \/ \/ \/ \/ \/
  10. *
  11. * www.optixx.org
  12. *
  13. *
  14. * Version: 1.0
  15. * Created: 07/21/2009 03:32:16 PM
  16. * Author: david@optixx.org
  17. *
  18. * =====================================================================================
  19. */
  20. #include <avr/io.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <avr/pgmspace.h> /* required by usbdrv.h */
  24. #include <util/delay.h> /* for _delay_ms() */
  25. #include <avr/interrupt.h> /* for sei() */
  26. #include "sram.h"
  27. #include "debug.h"
  28. #include "info.h"
  29. #define RUNCHAR 0x90
  30. uint8_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)
  31. {
  32. uint8_t in_byte, in_repeat, last_byte;
  33. uint32_t out_len, out_len_left;
  34. info("RLE decode len=%li addr=0x%08lx\n",in_len,out_addr);
  35. last_byte = 0;
  36. out_len_left = out_len;
  37. sram_bulk_write_start(out_addr);
  38. #define INBYTE(b) \
  39. do { \
  40. if ( --in_len < 0 ) { \
  41. return 1; \
  42. } \
  43. cli();\
  44. b = pgm_read_byte((PGM_VOID_P)in_addr++); \
  45. sei();\
  46. } while(0)
  47. #define OUTBYTE(b) \
  48. do { \
  49. sram_bulk_write(b);\
  50. sram_bulk_write_next();\
  51. out_addr++;\
  52. } while(0)
  53. INBYTE(in_byte);
  54. if (in_byte == RUNCHAR) {
  55. INBYTE(in_repeat);
  56. if (in_repeat != 0) {
  57. info("Orphaned RLE code at start\n");
  58. return 1;
  59. }
  60. OUTBYTE(RUNCHAR);
  61. } else {
  62. OUTBYTE(in_byte);
  63. }
  64. while( in_len > 0 ) {
  65. INBYTE(in_byte);
  66. if (in_len%1024==0)
  67. info(".");
  68. if (in_byte == RUNCHAR) {
  69. INBYTE(in_repeat);
  70. if ( in_repeat == 0 ) {
  71. /* Just an escaped RUNCHAR value */
  72. OUTBYTE(RUNCHAR);
  73. } else {
  74. /* Pick up value and output a sequence of it */
  75. in_byte = last_byte; //;out_data[-1];
  76. while ( --in_repeat > 0 )
  77. OUTBYTE(in_byte);
  78. }
  79. } else {
  80. /* Normal byte */
  81. OUTBYTE(in_byte);
  82. }
  83. last_byte = in_byte;
  84. }
  85. sram_bulk_write_end();
  86. return 0;
  87. }