272 lines
3.8 KiB
Plaintext
272 lines
3.8 KiB
Plaintext
;
|
|
; 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 -/
|
|
|
|
#define getByte0 \
|
|
dec zps+0 :\
|
|
bne *+7 :\
|
|
jsr nextPage:\
|
|
bvc *+4 :\
|
|
lda (zps),y :\
|
|
|
|
#define _getByte0 \
|
|
bit zps+0 :\
|
|
bne *+4 :\
|
|
dec zps+1 :\
|
|
dec zps+0 :\
|
|
lda (zps),y :\
|
|
|
|
#if 0
|
|
#define getByte1 jsr get_byte
|
|
#else
|
|
#define getByte1 getByte0
|
|
#endif
|
|
|
|
|
|
#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 :\
|
|
.)
|
|
|
|
#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 <-$79-*,0 ; place decode_copy on a page boundary
|
|
#endif
|
|
|
|
decrunch_zpa=$e0 ;7 bytes required
|
|
decrunch
|
|
.(
|
|
zps = decrunch_zpa+$00
|
|
zbs1 = decrunch_zpa+$02
|
|
zbs2 = decrunch_zpa+$03
|
|
zbs4 = decrunch_zpa+$04
|
|
offsetm1= decrunch_zpa+$05
|
|
|
|
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 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#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)
|
|
lda copy_dst+1
|
|
adc offsetm1
|
|
sta copy_src+1
|
|
|
|
lda copy_dst+2
|
|
adc offsetm1+1
|
|
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_byte
|
|
getByte0
|
|
end_of_file
|
|
rts
|
|
end_of_segment
|
|
lda offsetm1
|
|
cmp#0
|
|
beq end_of_file
|
|
jmp next_segment
|
|
nextPage
|
|
lda (zps),y
|
|
dec zps+1
|
|
clv
|
|
rts
|
|
|
|
.)
|
|
decrunch_end
|