Subversion Repositories pentevo

Rev

Rev 129 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6 lvd 1
#include <avr/io.h>
2
#include <avr/pgmspace.h>
129 chrv 3
 
4
#include "mytypes.h"
5
#include "main.h"
6 lvd 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