rle.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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. info("RLE decode len=%li addr=0x%08lx\n", in_len, out_addr);
  34. last_byte = 0;
  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. INBYTE(in_byte);
  52. if (in_byte == RUNCHAR) {
  53. INBYTE(in_repeat);
  54. if (in_repeat != 0) {
  55. info("Orphaned RLE code at start\n");
  56. return 1;
  57. }
  58. OUTBYTE(RUNCHAR);
  59. } else {
  60. OUTBYTE(in_byte);
  61. }
  62. while (in_len > 0) {
  63. INBYTE(in_byte);
  64. if (in_len % 1024 == 0)
  65. info(".");
  66. if (in_byte == RUNCHAR) {
  67. INBYTE(in_repeat);
  68. if (in_repeat == 0) {
  69. /*
  70. * Just an escaped RUNCHAR value
  71. */
  72. OUTBYTE(RUNCHAR);
  73. } else {
  74. /*
  75. * Pick up value and output a sequence of it
  76. */
  77. in_byte = last_byte; // ;out_data[-1];
  78. while (--in_repeat > 0)
  79. OUTBYTE(in_byte);
  80. }
  81. } else {
  82. /*
  83. * Normal byte
  84. */
  85. OUTBYTE(in_byte);
  86. }
  87. last_byte = in_byte;
  88. }
  89. sram_bulk_write_end();
  90. return 0;
  91. }