rle.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. #define RUNCHAR 0x90
  29. uint8_t rle_decode(PGM_VOID_P in_addr, int32_t in_len, uint32_t out_addr)
  30. {
  31. uint8_t in_byte, in_repeat, last_byte;
  32. uint32_t out_len, out_len_left;
  33. printf("RLE decode len=%li addr=0x%08lx\n",in_len,out_addr);
  34. out_len_left = out_len;
  35. sram_bulk_write_start(out_addr);
  36. #define INBYTE(b) \
  37. do { \
  38. if ( --in_len < 0 ) { \
  39. return 1; \
  40. } \
  41. cli();\
  42. b = pgm_read_byte((PGM_VOID_P)in_addr++); \
  43. sei();\
  44. } while(0)
  45. #define OUTBYTE(b) \
  46. do { \
  47. sram_bulk_write(b);\
  48. sram_bulk_write_next();\
  49. out_addr++;\
  50. } while(0)
  51. /*
  52. ** Handle first byte separately (since we have to get angry
  53. ** in case of an orphaned RLE code).
  54. */
  55. INBYTE(in_byte);
  56. if (in_byte == RUNCHAR) {
  57. INBYTE(in_repeat);
  58. if (in_repeat != 0) {
  59. /* Note Error, not Incomplete (which is at the end
  60. ** of the string only). This is a programmer error.
  61. */
  62. printf("Orphaned RLE code at start\n");
  63. return 1;
  64. }
  65. OUTBYTE(RUNCHAR);
  66. } else {
  67. OUTBYTE(in_byte);
  68. }
  69. while( in_len > 0 ) {
  70. INBYTE(in_byte);
  71. if (in_len%1024==0)
  72. printf(".");
  73. if (in_byte == RUNCHAR) {
  74. INBYTE(in_repeat);
  75. if ( in_repeat == 0 ) {
  76. /* Just an escaped RUNCHAR value */
  77. OUTBYTE(RUNCHAR);
  78. } else {
  79. /* Pick up value and output a sequence of it */
  80. in_byte = last_byte; //;out_data[-1];
  81. while ( --in_repeat > 0 )
  82. OUTBYTE(in_byte);
  83. }
  84. } else {
  85. /* Normal byte */
  86. OUTBYTE(in_byte);
  87. }
  88. last_byte = in_byte;
  89. }
  90. sram_bulk_write_end();
  91. return 0;
  92. }