ys2-intro/loader/tools/tinycrunch_v1.2/tc_decode.s

128 lines
2.2 KiB
ArmAsm
Raw Normal View History

2025-11-13 11:07:39 -05:00
.export decrunch
.ifdef TC_NO_HEADER
.define sp tc_sp
.define dp tc_dp
.exportzp tc_sp, tc_dp
.endif
.define sbx axs
DECOMPVARS = 4 ; 6 bytes
dp=DECOMPVARS + 0 ; 4
sp=DECOMPVARS + 2 ; 6 ; sp must follow dp, cf init code
cs=DECOMPVARS + 4 ; 8
.ifdef TC_BLOCK_INTERFACE
.import tc_getblock
.endif
.ifdef TC_NO_HEADER
decrunch_done:
.else
decrunch:
stx sp+1
ldy#2
init_loop:
sta dp,y ;first iter stores sp-low :D
.ifdef TC_BLOCK_INTERFACE
; read three blocks ahead,
; - one because literal strings read up to 128 bytes past sp
; - two more to absorb up to 256 blocks worth of read 254 bytes/use 256 bytes
tya
pha
jsr tc_getblock
pla
tay
.endif
lda (sp),y
dey
bpl init_loop
pha
lda#$02
bne update_sp
decrunch_done:
pla
iny
sta(dp),y ; overwrite EOF sentinal for in place decompression
.endif
rts
literal_run:
literal_loop:
iny
lda(sp),y
sta(dp),y
dex
bmi literal_loop
tya
pha
clc
increase_dp_by_a_and_sp_by_tos_plus_one:
adc dp
sta dp
bcc :+
inc dp+1
:
pla
update_sp:
sec
adc sp
sta sp
bcc :+
inc sp+1
.ifdef TC_BLOCK_INTERFACE
jsr tc_getblock
.endif
:
.ifdef TC_NO_HEADER
decrunch:
.endif
next_command:
ldy#0
lax(sp),y
beq decrunch_done
; literal: x = 128+length-1
; near copy: a = %11xxxxxx
; far copy: a|0xf8 = >(~(offset-1)), x = 8*(length-2) | (some low bits)
asl
bcc far_copy
bpl literal_run
near_copy:
ldx#$07 ; clear high byte of -ve offset. Also ensures copy_loop doesn't loop.
.byt $f0 ; beq (not taken) to skip over the iny
far_copy:
iny
; carry is set for near_copy, clear for far_copy
lda(sp),y ;fetch second byte (or for near copy, refetch first). This is low 8 bits of offset.
adc dp
sta cs
txa
ora#$f8
adc dp+1
sta cs+1
tya
pha ; save opcode length to stack
ldy#1
lda(cs),y
sta(dp),y
copy_loop:
iny
lda(cs),y
sta(dp),y
txa ; spend an extra 2 cycles per byte here to save 10 in the bitfield extraction. A win on average
sbx#8
bpl copy_loop
tya
bcc increase_dp_by_a_and_sp_by_tos_plus_one ; always taken.
edecrunch: