rle.c 2.7 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. #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. /*
  72. * Just an escaped RUNCHAR value
  73. */
  74. OUTBYTE(RUNCHAR);
  75. } else {
  76. /*
  77. * Pick up value and output a sequence of it
  78. */
  79. in_byte = last_byte; // ;out_data[-1];
  80. while (--in_repeat > 0)
  81. OUTBYTE(in_byte);
  82. }
  83. } else {
  84. /*
  85. * Normal byte
  86. */
  87. OUTBYTE(in_byte);
  88. }
  89. last_byte = in_byte;
  90. }
  91. sram_bulk_write_end();
  92. return 0;
  93. }