272 lines
3.5 KiB
ArmAsm
272 lines
3.5 KiB
ArmAsm
;
|
|
; NuCrunch 0.1
|
|
; Christopher Jam
|
|
; February 2016
|
|
;
|
|
|
|
; next byte is fetched from mem[ mem[zps+1]*256+(mem[zps]-1)%256 ]
|
|
; ie, init pointer to start byte then increment low byte of pointer.
|
|
; Low byte is decremented before each fetch, then if it hits zero the high byte is predecremented for the next fetch
|
|
; note that getByte requires y to be zero
|
|
; also note that this mangled pointer is a tad inimical to the literal fetches -/
|
|
;
|
|
; This is the compact version with much less aggressive inlining. Will be slower.
|
|
|
|
.export decrunch_next_group
|
|
.export decrunch
|
|
.export decrunch_end
|
|
|
|
|
|
|
|
.define getByte1 jsr get_byte
|
|
|
|
|
|
.macro getBit1
|
|
jsr get_bit_1
|
|
.endmacro
|
|
|
|
|
|
|
|
; get head of a pair of bits from the bitpair stream
|
|
; (must getBit2t precisely once before invoking again)
|
|
|
|
.macro getBit2h
|
|
.local nomore
|
|
asl zbs2
|
|
bne nomore
|
|
getByte1
|
|
sec
|
|
rol
|
|
sta zbs2
|
|
nomore:
|
|
.endmacro
|
|
|
|
; same, but preserving A/ trashing X.
|
|
.macro getBit2hpa
|
|
jsr get_bit_2hpa
|
|
.endmacro
|
|
|
|
.macro getBit2t
|
|
asl zbs2
|
|
.endmacro
|
|
|
|
; get head of a quad of bits from the quad stream
|
|
; (must getBit4t precisely three times before invoking again)
|
|
|
|
.macro getBit4h
|
|
.local nomore
|
|
asl zbs4
|
|
bne nomore
|
|
getByte1
|
|
sec
|
|
rol
|
|
sta zbs4
|
|
nomore:
|
|
.endmacro
|
|
|
|
|
|
; get tail of a quad of bits from the quad stream
|
|
.macro getBit4t
|
|
asl zbs4
|
|
.endmacro
|
|
|
|
; note, trashes X. Also, carry is clear when done
|
|
.macro getExpGoulombTail
|
|
.local ndone
|
|
ndone:
|
|
getBit2hpa
|
|
rol
|
|
getBit2t
|
|
bcs ndone
|
|
.endmacro
|
|
|
|
.macro getExpGoulombTail_odd_aligned
|
|
.local ndone
|
|
ndone:
|
|
getBit2t
|
|
rol
|
|
getBit2hpa
|
|
bcs ndone
|
|
.endmacro
|
|
|
|
|
|
decrunch_zpa =$e0 ;6 bytes required
|
|
|
|
|
|
zps = decrunch_zpa+$00
|
|
zbs1 = decrunch_zpa+$02
|
|
zbs2 = decrunch_zpa+$03
|
|
zbs4 = decrunch_zpa+$04
|
|
offsetm1h = decrunch_zpa+$05
|
|
|
|
|
|
|
|
decrunch:
|
|
|
|
stx zps+0
|
|
sta zps+1
|
|
ldy #0
|
|
sty zbs1
|
|
sty zbs2
|
|
sty zbs4
|
|
|
|
|
|
decrunch_next_group:
|
|
ldy #0
|
|
next_segment:
|
|
jsr get_byte
|
|
sta copy_dst+1
|
|
jsr get_byte
|
|
sta copy_dst+2
|
|
|
|
decode_literal:
|
|
|
|
getEG0p1: ;get count [eg0+1] in x
|
|
ldx#1
|
|
getBit1
|
|
lda#1
|
|
bcc ret1
|
|
lda#1
|
|
getExpGoulombTail
|
|
tax
|
|
ret1:
|
|
txa
|
|
sec
|
|
eor#255
|
|
adc copy_dst+1
|
|
sta copy_dst+1
|
|
sta literal_dst+1
|
|
bcs *+5
|
|
dec copy_dst+2
|
|
lda copy_dst+2
|
|
sta literal_dst+2
|
|
|
|
|
|
|
|
literal_loop:
|
|
literal_src:
|
|
getByte1
|
|
literal_dst:
|
|
sta $f000,x
|
|
dex
|
|
bne literal_loop
|
|
|
|
|
|
; literal is always followed by copy
|
|
|
|
decode_copy:
|
|
getBit2h
|
|
bcc short_offset
|
|
lda#1
|
|
getExpGoulombTail_odd_aligned
|
|
adc#255
|
|
sta offsetm1h
|
|
getByte1
|
|
jmp got_high
|
|
|
|
short_offset:
|
|
lda#0
|
|
sta offsetm1h
|
|
|
|
;ExpGoulomb k=3
|
|
getBit4h
|
|
lda#1
|
|
bcc no_tail
|
|
getExpGoulombTail_odd_aligned
|
|
no_tail:
|
|
adc#255
|
|
|
|
getBit4t
|
|
rol
|
|
getBit4t
|
|
rol
|
|
getBit4t
|
|
rol
|
|
got_high:
|
|
pha
|
|
|
|
ldx#2
|
|
getBit2t
|
|
bcc length_two
|
|
lda#1
|
|
getExpGoulombTail
|
|
tax
|
|
inx
|
|
beq end_of_segment ; copy length of 256 marks end of segment
|
|
length_two:
|
|
|
|
txa
|
|
eor#255
|
|
sec
|
|
adc copy_dst+1
|
|
sta copy_dst+1
|
|
bcs *+6
|
|
dec copy_dst+2
|
|
sec
|
|
|
|
; note carry is set at this point; good as we want to add (offsetm1+1)
|
|
pla
|
|
adc copy_dst+1
|
|
sta copy_src+1
|
|
|
|
lda copy_dst+2
|
|
adc offsetm1h
|
|
sta copy_src+2
|
|
|
|
copy_loop:
|
|
copy_src:
|
|
lda $f000,x
|
|
copy_dst:
|
|
sta $f000,x
|
|
dex
|
|
bne copy_loop
|
|
|
|
|
|
ldy#0
|
|
getBit1
|
|
bcs jmp_decode_copy
|
|
jmp decode_literal
|
|
jmp_decode_copy:
|
|
jmp decode_copy
|
|
|
|
get_bit_1:
|
|
asl zbs1
|
|
bne :+
|
|
getByte1
|
|
sec
|
|
rol
|
|
sta zbs1
|
|
:
|
|
rts
|
|
get_bit_2hpa:
|
|
asl zbs2
|
|
bne :+
|
|
tax
|
|
getByte1
|
|
sec
|
|
rol
|
|
sta zbs2
|
|
txa
|
|
: rts
|
|
|
|
get_byte:
|
|
dec zps+0
|
|
beq load_decrement_return
|
|
load_and_return:
|
|
lda (zps),y
|
|
rts
|
|
|
|
load_decrement_return:
|
|
lda (zps),y
|
|
dec zps+1
|
|
|
|
end_of_file:
|
|
rts
|
|
|
|
end_of_segment:
|
|
pla
|
|
cmp#0
|
|
beq end_of_file
|
|
jmp next_segment
|
|
|