Subversion Repositories pentevo

Rev

Rev 6 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include <avr/io.h>
  2. #include <avr/pgmspace.h>
  3.  
  4. #include "mytypes.h"
  5. #include "main.h"
  6. #include "depacker_dirty.h"
  7.  
  8.  
  9. UWORD dbpos; // current position in buffer (wrappable)
  10.  
  11. UBYTE bitstream;
  12. UBYTE bitcount;
  13.  
  14.  
  15.  
  16.  
  17. void depacker_dirty(void)
  18. {
  19.         UBYTE j;
  20.  
  21.         UBYTE bits;
  22.         WORD disp;
  23.  
  24.  
  25.         dbpos=0;
  26.  
  27.         // get first byte of packed file and write to output
  28.         put_byte(NEXT_BYTE);
  29.  
  30.  
  31.         // second byte goes to bitstream
  32.         bitstream=NEXT_BYTE;
  33.         bitcount=8;
  34.  
  35.  
  36.         // actual depacking loop!
  37.         do
  38.         {
  39.                 j=0;
  40.  
  41.                 // get 1st bit - either OUTBYTE or beginning of LZ code
  42.                 if( get_bits_dirty(1) )
  43.                 { // OUTBYTE
  44.                         put_byte(NEXT_BYTE);
  45.                 }
  46.                 else
  47.                 { // LZ code
  48.                         switch( get_bits_dirty(2) )
  49.                         {
  50.                         case 0: // 000
  51.                                 repeat( 0xFFF8|get_bits_dirty(3) ,1);
  52.                                 break;
  53.                         case 1: // 001
  54.                                 repeat( 0xFF00|NEXT_BYTE ,2);
  55.                                 break;
  56.                         case 2: // 010
  57.                                 repeat(get_bigdisp_dirty(),3);
  58.                                 break;
  59.                         case 3: // 011
  60.                                 // extract num of length bits
  61.                                 do j++; while( !get_bits_dirty(1) );
  62.  
  63.                                 if( j<8 ) // check for exit code
  64.                                 {
  65.                                         // get length bits itself
  66.                                         bits=get_bits_dirty(j);
  67.                                         disp=get_bigdisp_dirty();
  68.                                         repeat(disp,2+(1<<j)+bits);
  69.                                 }
  70.                                 break;
  71.                         }
  72.                 }
  73.  
  74.         } while( j<8 );
  75.  
  76.  
  77.         if( (DBMASK&dbpos) )
  78.         {
  79.                 put_buffer(DBMASK&dbpos);
  80.         }
  81.  
  82. }
  83.  
  84.  
  85.  
  86.  
  87. void repeat(WORD disp,UBYTE len)
  88. { // repeat len bytes with disp displacement (negative)
  89.   // uses dbpos & dbuf
  90.  
  91.         UBYTE i; // since length is no more than 255
  92.  
  93.         for(i=0;i<len;i++)
  94.         {
  95.                 put_byte(dbuf[DBMASK&(dbpos+disp)]);
  96.         }
  97. }
  98.  
  99.  
  100.  
  101.  
  102. void put_byte(UBYTE byte)
  103. {
  104.         dbuf[dbpos]=byte;
  105.         dbpos = DBMASK & (dbpos+1);
  106.  
  107.         if( !dbpos )
  108.         {
  109.                 put_buffer(DBSIZE);
  110.         }
  111. }
  112.  
  113.  
  114. UBYTE get_bits_dirty(UBYTE numbits)
  115. { // gets bits in a byte-wise style, no checks
  116.   // numbits must be >0
  117.  
  118.         UBYTE bits;
  119.  
  120.         bits=0;
  121.  
  122.         do
  123.         {
  124.                 if( !(bitcount--) )
  125.                 {
  126.                         bitcount=7;
  127.                         bitstream=NEXT_BYTE;
  128.                 }
  129.  
  130.                 bits = (bits<<1)|(bitstream>>7); // all shifts byte-wise
  131.                 bitstream<<=1;
  132.  
  133.         } while (--numbits);
  134.  
  135.         return bits;
  136. }
  137.  
  138. WORD get_bigdisp_dirty(void)
  139. { // fetches 'big' displacement (-1..-4352)
  140.   // returns negative displacement
  141.  
  142.         UBYTE bits;
  143.  
  144.         if( get_bits_dirty(1) )
  145.         { // longer displacement
  146.                 bits=get_bits_dirty(4);
  147.                 return (((0xF0|bits)-1)<<8)|NEXT_BYTE;
  148.         }
  149.         else
  150.         { // shorter displacement
  151.                 return 0xFF00|NEXT_BYTE;
  152.         }
  153. }
  154.  
  155.