Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

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