249 lines
3.4 KiB
Plaintext
249 lines
3.4 KiB
Plaintext
;
|
|
; NuCrunch 1.0
|
|
; Christopher Jam
|
|
; May 2018
|
|
;
|
|
|
|
#define getByte1 \
|
|
lda (zps),y :\
|
|
inc zps+0 :\
|
|
bne *+4 :\
|
|
inc zps+1
|
|
|
|
#define getBit1 \
|
|
.( :\
|
|
asl zbs1 :\
|
|
bne nomore :\
|
|
getByte1 :\
|
|
sec :\
|
|
rol :\
|
|
sta zbs1 :\
|
|
nomore :\
|
|
.)
|
|
|
|
; get head of a pair of bits from the bitpair stream
|
|
; (must getBit2t precisely once before invoking again)
|
|
|
|
#define getBit2h \
|
|
.( :\
|
|
asl zbs2 :\
|
|
bne nomore :\
|
|
getByte1 :\
|
|
sec :\
|
|
rol :\
|
|
sta zbs2 :\
|
|
nomore :\
|
|
.)
|
|
|
|
; same, but preserving A/ trashing X.
|
|
#define getBit2hpa \
|
|
.( :\
|
|
asl zbs2 :\
|
|
bne nomore :\
|
|
tax :\
|
|
getByte1 :\
|
|
sec :\
|
|
rol :\
|
|
sta zbs2 :\
|
|
txa :\
|
|
nomore :\
|
|
.)
|
|
|
|
; get tail of a pair of bits from the bitpair stream
|
|
#define getBit2t \
|
|
asl zbs2
|
|
|
|
; get head of a quad of bits from the quad stream
|
|
; (must getBit4t precisely three times before invoking again)
|
|
|
|
#define getBit4h \
|
|
.( :\
|
|
asl zbs4 :\
|
|
bne nomore :\
|
|
getByte1 :\
|
|
sec :\
|
|
rol :\
|
|
sta zbs4 :\
|
|
nomore :\
|
|
.)
|
|
|
|
|
|
; get tail of a quad of bits from the quad stream
|
|
#define getBit4t \
|
|
asl zbs4
|
|
|
|
; note, trashes X. Also, carry is clear when done
|
|
#define getExpGoulombTail \
|
|
.( :\
|
|
ndone :\
|
|
getBit2hpa :\
|
|
rol :\
|
|
getBit2t :\
|
|
bcs ndone :\
|
|
.)
|
|
|
|
#define getExpGoulombTail_odd_aligned \
|
|
.( :\
|
|
ndone :\
|
|
getBit2t :\
|
|
rol :\
|
|
getBit2hpa :\
|
|
bcs ndone :\
|
|
.)
|
|
|
|
#ifdef NUCRUNCH_ALIGN_FOR_SPEED
|
|
.dsb <-$63-*,0 ; place decode_copy on a page boundary
|
|
#endif
|
|
|
|
decrunch_zpa=$e0 ;9 bytes required
|
|
.(
|
|
zbs1 = decrunch_zpa+$00 ; 1 byte
|
|
zbs2 = decrunch_zpa+$01 ; 1 byte
|
|
zbs4 = decrunch_zpa+$02 ; 1 byte
|
|
zpc = decrunch_zpa+$03 ; 2 bytes
|
|
zps = decrunch_zpa+$05 ; 2 bytes
|
|
zpd = decrunch_zpa+$07 ; 2 bytes
|
|
|
|
offsetm1 = zpc ; these are aliased, as never need both
|
|
|
|
|
|
+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 zpd+0
|
|
jsr get_byte
|
|
sta zpd+1
|
|
|
|
decode_literal
|
|
|
|
; get count [ExpGoulomb0+1] in x
|
|
ldx#1
|
|
getBit1
|
|
bcc ret1
|
|
lda#1
|
|
getExpGoulombTail
|
|
tax
|
|
ret1
|
|
|
|
literal_loop
|
|
lda (zps),y
|
|
sta (zpd),y
|
|
iny
|
|
dex
|
|
bne literal_loop
|
|
|
|
; carry is clear either from bcc above or _getExpGoulombTail above
|
|
tya
|
|
adc zps
|
|
sta zps
|
|
bcc *+5
|
|
inc zps+1
|
|
clc
|
|
tya
|
|
adc zpd
|
|
sta zpd
|
|
bcc *+4
|
|
inc zpd+1
|
|
ldy#0
|
|
|
|
; literal is always followed by copy
|
|
|
|
decode_copy
|
|
getBit2h
|
|
bcc short_offset
|
|
lda#1
|
|
getExpGoulombTail_odd_aligned
|
|
adc#255
|
|
sta offsetm1+1
|
|
getByte1
|
|
sta offsetm1
|
|
jmp got_high
|
|
|
|
short_offset
|
|
lda#0
|
|
sta offsetm1+1
|
|
|
|
;ExpGoulomb k=3
|
|
getBit4h
|
|
lda#1
|
|
bcc no_tail
|
|
getExpGoulombTail_odd_aligned
|
|
no_tail
|
|
adc#255
|
|
|
|
getBit4t
|
|
rol
|
|
getBit4t
|
|
rol
|
|
getBit4t
|
|
rol
|
|
sta offsetm1
|
|
got_high
|
|
|
|
ldx#1
|
|
getBit2t
|
|
bcc length_two
|
|
lda#1
|
|
getExpGoulombTail
|
|
tax
|
|
cpx#255
|
|
beq end_of_segment ; copy length of 256 marks end of segment
|
|
length_two
|
|
|
|
; note carry is clear at this point; good as we want to subtract (offsetm1+1)
|
|
lda zpd
|
|
sbc offsetm1
|
|
sta zpc
|
|
|
|
lda zpd+1
|
|
sbc offsetm1+1
|
|
sta zpc+1
|
|
|
|
lda (zpc),y
|
|
sta (zpd),y
|
|
copy_loop
|
|
iny
|
|
copy_src
|
|
lda (zpc),y
|
|
copy_dst
|
|
sta (zpd),y
|
|
dex
|
|
bne copy_loop
|
|
tya
|
|
|
|
; carry will be set from SBC above
|
|
adc zpd
|
|
sta zpd
|
|
bcc *+4
|
|
inc zpd+1
|
|
|
|
ldy#0
|
|
getBit1
|
|
bcs jmp_decode_copy
|
|
jmp decode_literal
|
|
jmp_decode_copy
|
|
jmp decode_copy
|
|
|
|
get_byte
|
|
getByte1
|
|
end_of_file
|
|
rts
|
|
end_of_segment
|
|
lda offsetm1
|
|
cmp#0
|
|
beq end_of_file
|
|
jmp next_segment
|
|
|
|
.)
|
|
decrunch_end
|