-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecompress.asm
196 lines (152 loc) · 2.48 KB
/
decompress.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
InitLzssDecode:
ldx #NF
stx @r
stz @buf
stz @mask
.call M16
stz @infile_idx
stz @outfile_idx
lda #COMPRESSED_CIRCUIT_SIZE
sta @infile_siz
.call M8
ldx #@circuit_zip
stx @infile
lda #^circuit_zip
sta @infile+2
ldx #@decompression_buffer
stx @decompression_buffer_addr
lda #^decompression_buffer
sta @decompression_buffer_addr+2
ldx #@circuit
stx @outfile_addr
lda #^circuit
sta @outfile_addr+2
jsr @LzssDecode
rts
; get n bits from infile
; n in Y
; result in X
GetBit:
ldx #0000
getbit_loop:
lda @mask
bne @skip_fgetc
phy
ldy @infile_idx
cpy @infile_siz
bcc @continue_getbit_loop
ldx #ffff ; we return 0xffff (EOF) if infile_idx >= infile_siz
ply
bra @end_getbit
continue_getbit_loop:
lda [<infile],y
sta @buf
lda #80
sta @mask
iny
sty @infile_idx
ply
skip_fgetc:
rep #20
txa
asl
tax
sep #20
lda @mask
and @buf
beq @skip_inx
inx
skip_inx:
lsr @mask
dey
bne @getbit_loop
end_getbit:
rts
LzssDecode:
lda #20
ldy @r
iny
clear_buffer_loop:
dey
sta [<decompression_buffer_addr],y
bne @clear_buffer_loop
decode_loop:
ldy #0001
jsr @GetBit ; c = getbit(1)
cpx #ffff
beq @decode_done ; if (c == EOF)
cpx #0001
beq @bit_is_one ; if (c == 1)
; ---- c == 0
ldy #EI
jsr @GetBit
cpx #ffff
beq @decode_done
stx @i
ldy #EJ
jsr @GetBit
cpx #ffff
beq @decode_done
stx @j
jsr @BufferLoop
bra @decode_loop
bit_is_one:
; ---- c == 1
ldy #0008
jsr @GetBit
cpx #ffff
beq @decode_done
txa
ldy @outfile_idx
sta [<outfile_addr],y
ldy @r
sta [<decompression_buffer_addr],y
rep #20
; r = (r + 1) & (N - 1)
inc @r
lda #N
dec
and @r
sta @r
inc @outfile_idx
sep #20
bra @decode_loop
decode_done:
rts
BufferLoop:
inx
inx
stx @k
ldy #0000
buffer_loop:
phy
rep #20
tya
clc
adc @i
pha
lda #N
dec
and 01,s
tay
pla
sep #20
lda [<decompression_buffer_addr],y
ldy @outfile_idx
sta [<outfile_addr],y
ldy @r
sta [<decompression_buffer_addr],y
rep #20
; r = (r + 1) & (N - 1)
inc @r
lda #N
dec
and @r
sta @r
inc @outfile_idx
sep #20
ply
iny
cpy @k
bne @buffer_loop
rts