jsr getbyt
sta elzpb+1 jsr getbyt ; exec address
sta lo+1 ; lo
jsr getbyt
sta hi+1 ; hi
jsr getbyt ; rleUsed
ldx #0
tay
t1 beq t2 ; Y == 0 ?
jsr getbyt
sta rletabl,x
inx
dey
bne t1
t2 lda #$80 ; setup bit store - $80 means empty
sta bitstr+1
jmp main
getbyt jsr getnew
bitstr lda #0
ror
rts
newesc ldy esc+1 ; remember the old code (top bits for escaped byte)
escB0 ldx #2 ; ** PARAMETER 0..8
jsr getchkf ; get & save the new escape code
sta esc+1
tya ; pre-set the bits
; Fall through and get the rest of the bits.
noesc ldx #6 ; ** PARAMETER 8..0
jsr getchkf
jsr putch ; output the escaped/normal byte
; Fall through and check the escape bits again
main ldy #0 ; Reset to a defined state
tya ; A = 0
escB1 ldx #2 ; ** PARAMETER 0..8
jsr getchkf ; X = 0
esc cmp #0
bne noesc
; Fall through to packed code
jsr getval ; X = 0
sta LZPOS+1 ; xstore - save the length for a later time
lsr ; cmp #1 ; LEN == 2 ? (A is never 0)
bne lz77 ; LEN != 2 -> LZ77
;tya ; A = 0
jsr get1bit ; X = 0
lsr ; bit -> C, A = 0
bcc lz77_2 ; A=0 -> LZPOS+1
;***FALL THRU***
; e..e01
jsr get1bit ; X = 0
lsr ; bit -> C, A = 0
bcc newesc ; e..e010
;***FALL THRU***
; e..e011
srle iny ; Y is 1 bigger than MSB loops
jsr getval ; Y is 1, get len, X = 0
sta LZPOS+1 ; xstore - Save length LSB
mg1 cmp #64 ; ** PARAMETER 63-64 -> C clear, 64-64 -> C set..
bcc chrcode ; short RLE, get bytecode
longrle ldx #2 ; ** PARAMETER 111111xxxxxx
jsr getbits ; get 3/2/1 more bits to get a full byte, X = 0
sta LZPOS+1 ; xstore - Save length LSB
jsr getval ; length MSB, X = 0
tay ; Y is 1 bigger than MSB loops
chrcode jsr getval ; Byte Code, X = 0
tax ; this is executed most of the time anyway
lda rletabl-1,x ; Saves one jump if done here (loses one txa)
cpx #32 ; 31-32 -> C clear, 32-32 -> C set..
bcc t3 ; 1..31, we got the right byte from the table
; Ranks 32..64 (11111°xxxxx), get byte..
txa ; get back the value (5 valid bits)
ldx #3
jsr getbits ; get 3 more bits to get a full byte, X = 0
t3 ldx LZPOS+1 ; xstore - get length LSB
inx ; adjust for cpx#$ff;bne -> bne
dorle jsr putch
dex
bne dorle ; xstore 0..255 -> 1..256
dey
bne dorle ; Y was 1 bigger than wanted originally
mainbeq beq main ; reverse condition -> jump always
lz77 jsr getval ; X = 0
mg21 cmp #127 ; ** PARAMETER Clears carry (is maximum value)
bne noeof
; EOF
hi ldx #0
lo ldy #0
rts
noeof sbc #0 ; C is clear -> subtract 1 (1..126 -> 0..125)
elzpb ldx #0 ; ** PARAMETER (more bits to get)
jsr getchkf ; clears Carry, X = 0
lz77_2 sta LZPOS+2 ; offset MSB
jsr getbyte ; clears Carry, X = 0
; Note: Already eor:ed in the compressor..
;eor #255 ; offset LSB 2's complement -1 (i.e. -X = ~X+1)
adc OUTPOS ; -offset -1 + curpos (C is clear)
ldx LZPOS+1 ; xstore = LZLEN (read before it's overwritten)
sta LZPOS+1
lda OUTPOS+1
sbc LZPOS+2 ; takes C into account
sta LZPOS+2 ; copy X+1 number of chars from LZPOS to OUTPOS
;ldy #0 ; Y was 0 originally, we don't change it
inx ; adjust for cpx#$ff;bne -> bne
lzloop
LZPOS lda $aaaa,y
jsr putch ; Note: must be copied forwards!
iny ; Y does not wrap because X=0..255 and Y initially 0
dex
bne lzloop ; X loops, (256,1..255)
beq mainbeq ; jump through another beq (-1 byte, +3 cycles)
getnew pha ; 1 Byte/3 cycles
INPOS = *+1
lda $aaaa ; ** PARAMETER
inc INPOS
bne t4
inc INPOS+1
t4 sec
rol ; Shift out the next bit and
; shift in C=1 (last bit marker)
sta bitstr+1 ; bitstr initial value = $80 == empty
pla ; 1 Byte/4 cycles
rts
; 25+12 = 37
; getval : Gets a 'static huffman coded' value
; ** Scratches X, returns the value in A **
getval inx ; X <- 1
txa ; set the top bit (value is 1..255)
gv0 asl bitstr+1
bne t5
jsr getnew
t5 bcc getchk ; got 0-bit
inx
mg cpx #7 ; ** PARAMETER unary code maximum length + 1
bne gv0
beq getchk ; inverse condition -> jump always
; getval: 18 bytes
; 15 + 17*n + 6+15*n+12 + 36*n/8 = 33 + 32*n + 36*n/8 cycles
; getbits: Gets X bits from the stream
; ** Scratches X, returns the value in A **
getbyte ldx #7
get1bit inx ;2
getbits asl bitstr+1
bne t6
jsr getnew
t6 rol ;2
getchk dex ;2 more bits to get ?
getchkf bne getbits ;2/3
clc ;2 return carry cleared
rts ;6+6
OUTPOS = *+1 ; ZP
putch sta $aaaa ; ** parameter
inc OUTPOS ; ZP
bne t7
inc OUTPOS+1 ; ZP
t7 rts
rletabl .byte 0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0