-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexomizer_depacker.asm
531 lines (488 loc) · 12.4 KB
/
exomizer_depacker.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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
set_depacker_source ;a/x/y = low/mid/high
sta src+1
txa
and #%00111111
clc
adc #$40
sta src+2
txa
lsr
lsr
lsr
lsr
lsr
lsr
sta tmp1
tya
asl
asl
clc
adc tmp1
sta block2+1
sta block3+1
rts
;--------------------------------------------------
set_depacker_dest ;a/x/y = low/mid/high
sta dest+1
txa
and #%00111111
clc
adc #$40
sta dest+2
txa
lsr
lsr
lsr
lsr
lsr
lsr
sta tmp2
tya
asl
asl
clc
adc tmp2
sta block+1
rts
;--------------------------------------------------
tmp1 .byte $00
tmp2 .byte $00
tmp3 .byte $00
;--------------------------------------------------
depack
sei
.byte $32,$dd
block3 lda #$01
.byte $32,$00
cli
jsr init_decruncher
;--------------------------------------------------
depack_loop
sei
.byte $32,$dd
block lda #$08 ; start at $020000
.byte $32,$00
cli
more_data
jsr get_decrunched_byte
; sta $d020
bcs end
dest sta $4000
jsr statusbar
inc dest+1
bne more_data
inc dest+2
lda dest+2
cmp #$80
bne more_data
lda #$40
sta dest+2
inc block+1
jmp depack_loop
end
sei ;sets segment $01 back to $004000-$007fff
.byte $32,$dd
lda #$01
.byte $32,$00
cli
rts
;--------------------------------------------------
statusbar
lda $0334
cmp #0
bne +
lda $0335
cmp #28
bne +
bra plok
+
inc $0334
bne +
inc $0335
+
rts
plok
lda #0
sta $0334
sta $0335
positie=*+1
ldx #0
lda #190
sta $0400+(16*40)+7,x
sta $0400+(17*40)+7,x
sta $0400+(18*40)+7,x
inc positie
rts
;--------------------------------------------------
get_crunched_byte
php
lda block+1
sta offset+1
sei
.byte $32,$dd
block2 lda #$01
.byte $32,$00
cli
src lda $1000
sta stash+1
inc src+1
bne off
inc src+2
off
lda src+2
cmp #$80
bne off2
lda #$40
sta src+2
inc block2+1
off2
sei
.byte $32,$dd
offset lda #$01
.byte $32,$00
cli
stash lda #$00
plp
rts
;
; Copyright (c) 2002, 2003 Magnus Lind.
;
; This software is provided 'as-is', without any express or implied warranty.
; In no event will the authors be held liable for any damages arising from
; the use of this software.
;
; Permission is granted to anyone to use this software for any purpose,
; including commercial applications, and to alter it and redistribute it
; freely, subject to the following restrictions:
;
; 1. The origin of this software must not be misrepresented; you must not
; claim that you wrote the original software. If you use this software in a
; product, an acknowledgment in the product documentation would be
; appreciated but is not required.
;
; 2. Altered source versions must be plainly marked as such, and must not
; be misrepresented as being the original software.
;
; 3. This notice may not be removed or altered from any distribution.
;
; 4. The names of this software and/or it's copyright holders may not be
; used to endorse or promote products derived from this software without
; specific prior written permission.
;
; -------------------------------------------------------------------
; the circular buffer needs to be page aligned, so only the high-bytes
; of the buffer start and len is imported to enforce this.
; the data that are to be decrunched must not have been crunched with
; a maximum offset size greater than the buffer size. use the -m option
; with a value of (buffer_len_hi * 256) or less.
; -------------------------------------------------------------------
;.import buffer_start_hi: absolute
;.import buffer_len_hi: absolute
buffer_start_hi = $c0 ; $0400
buffer_len_hi = $10 ;-> $07ff
; -------------------------------------------------------------------
; The decruncher jsr:s to the get_crunched_byte address when it wants to
; read a crunched byte. This subroutine has to preserve x and y register
; and must not modify the state of the carry flag.
; -------------------------------------------------------------------
;.import get_crunched_byte
; -------------------------------------------------------------------
; this subsoutine is called before decrunching. It initializes the
; decruncher zeropage locations and precalculates the decrunch tables.
; -------------------------------------------------------------------
;.export init_decruncher
; -------------------------------------------------------------------
; this function is the heart of the decruncher. Call this whenever you
; want a decrunched byte. It will return it in the accumulator. It will
; also destroy the values in y and x reg and mess up the status flags.
; This function will not change the interrupt status bit and it will not
; modify the memory configuration.
; -------------------------------------------------------------------
;.export get_decrunched_byte
; -------------------------------------------------------------------
; zero page addresses used
; -------------------------------------------------------------------
zp_src_hi = $10
zp_src_lo = zp_src_hi + 1
zp_src_bi = zp_src_hi + 2
zp_bitbuf = zp_src_hi + 3
zp_len_lo = $14
zp_len_hi = zp_len_lo + 1
zp_bits_lo = $16
zp_bits_hi = zp_bits_lo + 1
zp_dest_hi = $18
zp_dest_lo = zp_dest_hi + 1 ; dest addr lo
zp_dest_bi = zp_dest_hi + 2 ; dest addr hi
;sload = $f0
; -------------------------------------------------------------------
; symbolic names for constants
; -------------------------------------------------------------------
buffer_end_hi = buffer_start_hi + buffer_len_hi
tabl_bi = decrunch_table
tabl_lo = decrunch_table + 52
tabl_hi = decrunch_table + 104
; -------------------------------------------------------------------
; get a crunshed byte
; -------------------------------------------------------------------
;get_crunched_byte = getbyte
; end_of_data needs to point to the address just after the address
; of the last byte of crunched data.
; -------------------------------------------------------------------
; -------------------------------------------------------------------
; no code below this comment has to be modified in order to generate
; a working decruncher of this source file.
; However, you may want to relocate the tables last in the file to a
; more suitable address.
; -------------------------------------------------------------------
; -------------------------------------------------------------------
; jsr this label to init the decruncher, it will init used zeropage
; zero page locations and the decrunch tables
; no constraints on register content, however the
; decimal flag has to be #0 (it almost always is, otherwise do a cld)
; -------------------------------------------------------------------
init_decruncher
; jsr get_crunched_byte
; sta write+1
; jsr get_crunched_byte
; sta write+2
jsr get_crunched_byte
sta zp_bitbuf
ldx #0
stx zp_dest_lo
stx zp_dest_hi
stx zp_len_lo
stx zp_len_hi
ldy #0
; -------------------------------------------------------------------
; calculate tables (49 bytes)
; x and y must be #0 when entering
;
_init_nextone
inx
tya
and #$0f
beq _init_shortcut ; starta på ny sekvens
txa ; this clears reg a
lsr ; and sets the carry flag
ldx zp_bits_lo
_init_rolle
rol
rol zp_bits_hi
dex
bpl _init_rolle ; c = 0 after this (rol zp_bits_hi)
adc tabl_lo-1,y
tax
lda zp_bits_hi
adc tabl_hi-1,y
_init_shortcut
sta tabl_hi,y
txa
sta tabl_lo,y
ldx #4
jsr _bit_get_bits ; clears x-reg.
sta tabl_bi,y
iny
cpy #52
bne _init_nextone
_do_exit
rts
; -------------------------------------------------------------------
; decrunch one byte
;
.align 4
get_decrunched_byte
ldy zp_len_lo
bne _do_sequence
ldx zp_len_hi
bne _do_sequence2
jsr _bit_get_bit1
beq _get_sequence
; -------------------------------------------------------------------
; literal handling (13 bytes)
;
jsr get_crunched_byte
bcc _do_literal
; -------------------------------------------------------------------
; count zero bits + 1 to get length table index (10 bytes)
; y = x = 0 when entering
;
_get_sequence
_seq_next1
iny
jsr _bit_get_bit1
beq _seq_next1
cpy #$11
bcs _do_exit
; -------------------------------------------------------------------
; calulate length of sequence (zp_len) (17 bytes)
;
ldx tabl_bi - 1,y
jsr _bit_get_bits
adc tabl_lo - 1,y
sta zp_len_lo
lda zp_bits_hi
adc tabl_hi - 1,y
sta zp_len_hi
; -------------------------------------------------------------------
; here we decide what offset table to use (20 bytes)
; x is 0 here
;
bne _seq_nots123
ldy zp_len_lo
cpy #$04
bcc _seq_size123
_seq_nots123
ldy #$03
_seq_size123
ldx tabl_bit - 1,y
jsr _bit_get_bits
adc tabl_off - 1,y
tay
; -------------------------------------------------------------------
; calulate absolute offset (zp_src) (27 bytes)
;
ldx tabl_bi,y
jsr _bit_get_bits;
adc tabl_lo,y
bcc _seq_skipcarry
inc zp_bits_hi
clc
_seq_skipcarry
adc zp_dest_lo
sta zp_src_lo
lda zp_bits_hi
adc tabl_hi,y
adc zp_dest_hi
; -------------------------------------------------------------------
bule1
cmp #<buffer_len_hi ; buffer_len_hi
bcc _seq_offset_ok
bule2
sbc #<buffer_len_hi ; buffer_len_hi
clc
; -------------------------------------------------------------------
_seq_offset_ok
sta zp_src_hi
bust
adc #<buffer_start_hi ;buffer_start_hi
sta zp_src_bi
_do_sequence
ldy #0
_do_sequence2
ldx zp_len_lo
bne _seq_len_dec_lo
dec zp_len_hi
_seq_len_dec_lo
dec zp_len_lo
; -------------------------------------------------------------------
ldx zp_src_lo
bne _seq_src_dec_lo
ldx zp_src_hi
bne _seq_src_dec_hi
; ------- handle buffer wrap problematics here ----------------------
bule3
ldx #<buffer_len_hi ; buffer_len_hi
stx zp_src_hi
buen1
ldx #<buffer_end_hi ; buffer_end_hi
stx zp_src_bi
; -------------------------------------------------------------------
_seq_src_dec_hi
dec zp_src_hi
dec zp_src_bi
_seq_src_dec_lo
dec zp_src_lo
; -------------------------------------------------------------------
lda (zp_src_lo),y
; -------------------------------------------------------------------
_do_literal
ldx zp_dest_lo
bne _seq_dest_dec_lo
ldx zp_dest_hi
bne _seq_dest_dec_hi
; ------- handle buffer wrap problematics here ----------------------
bule4
ldx #<buffer_len_hi ; buffer_len_hi
stx zp_dest_hi
buen2
ldx #<buffer_end_hi ; buffer_end_hi
stx zp_dest_bi
; -------------------------------------------------------------------
_seq_dest_dec_hi
dec zp_dest_hi
dec zp_dest_bi
_seq_dest_dec_lo
dec zp_dest_lo
; -------------------------------------------------------------------
sta (zp_dest_lo),y
clc
rts
; -------------------------------------------------------------------
; two small static tables (6 bytes)
;
tabl_bit
.byte 2,4,4
tabl_off
.byte 48,32,16
; -------------------------------------------------------------------
; get x + 1 bits (1 byte)
;
_bit_get_bit1
inx
; -------------------------------------------------------------------
; get bits (31 bytes)
;
; args:
; x = number of bits to get
; returns:
; a = #bits_lo
; x = #0
; c = 0
; zp_bits_lo = #bits_lo
; zp_bits_hi = #bits_hi
; notes:
; y is untouched
; other status bits are set to (a == #0)
; -------------------------------------------------------------------
_bit_get_bits
lda #$00
sta zp_bits_lo
sta zp_bits_hi
cpx #$01
bcc _bit_bits_done
lda zp_bitbuf
_bit_bits_next
lsr
bne _bit_ok
jsr get_crunched_byte
ror
_bit_ok
rol zp_bits_lo
rol zp_bits_hi
dex
bne _bit_bits_next
sta zp_bitbuf
lda zp_bits_lo
_bit_bits_done
rts
; -------------------------------------------------------------------
; end of decruncher
; -------------------------------------------------------------------
; -------------------------------------------------------------------
; this 156 byte table area may be relocated. It may also be clobbered
; by other data between decrunches.
; -------------------------------------------------------------------
decrunch_table
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0
; -------------------------------------------------------------------
; end of decruncher
; -------------------------------------------------------------------