292 lines
6 KiB
NASM
292 lines
6 KiB
NASM
|
|
; SHORT+IRQLOAD 354 bytes
|
|||
|
|
; no rle =~ -83 bytes -> 271
|
|||
|
|
; fixed params =~ -48 bytes -> 306
|
|||
|
|
; 223 bytes
|
|||
|
|
|
|||
|
|
SHORT = 0 ;1 ; assume file is ok
|
|||
|
|
IRQLOAD = 0 ;1
|
|||
|
|
|
|||
|
|
processor 6502
|
|||
|
|
|
|||
|
|
|
|||
|
|
LZPOS EQU $9e ; 2 ZeroPage temporaries
|
|||
|
|
bitstr EQU $fb ; 1 temporary (does not need to be ZP)
|
|||
|
|
|
|||
|
|
|
|||
|
|
ORG $c000
|
|||
|
|
|
|||
|
|
; Call with X = HI of packed data, Y = LO of packed data
|
|||
|
|
; Returns exec address in X = HI and Y = LO
|
|||
|
|
; Carry will be set for error, cleared for OK
|
|||
|
|
#if SHORT == 0
|
|||
|
|
sei
|
|||
|
|
lda #$35
|
|||
|
|
sta 1
|
|||
|
|
#endif
|
|||
|
|
#if IRQLOAD
|
|||
|
|
;jsr initloader
|
|||
|
|
#else
|
|||
|
|
; Setup read pointer
|
|||
|
|
sty INPOS
|
|||
|
|
stx INPOS+1
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
#if SHORT
|
|||
|
|
ldx #5
|
|||
|
|
222$ jsr getbyt ; skip 'p', 'u', endAddr HI&LO, leave starting escape in A
|
|||
|
|
dex
|
|||
|
|
bne 222$
|
|||
|
|
#else
|
|||
|
|
jsr getbyt ; 'p'
|
|||
|
|
cmp #112
|
|||
|
|
beq 9$
|
|||
|
|
sec ; error
|
|||
|
|
jmp eof2
|
|||
|
|
9$ jsr getbyt ; 'u'
|
|||
|
|
cmp #117
|
|||
|
|
beq 8$
|
|||
|
|
sec ; error
|
|||
|
|
jmp eof2
|
|||
|
|
8$ jsr getbyt ; skip endAddr
|
|||
|
|
jsr getbyt
|
|||
|
|
jsr getbyt
|
|||
|
|
#endif
|
|||
|
|
sta esc+1 ; starting escape
|
|||
|
|
|
|||
|
|
jsr getbyt ; read startAddr
|
|||
|
|
sta OUTPOS
|
|||
|
|
jsr getbyt
|
|||
|
|
sta OUTPOS+1
|
|||
|
|
jsr getbyt ; read # of escape bits
|
|||
|
|
sta escB0+1
|
|||
|
|
sta escB1+1
|
|||
|
|
lda #8
|
|||
|
|
sec
|
|||
|
|
sbc escB1+1
|
|||
|
|
sta noesc+1 ; 8-escBits
|
|||
|
|
|
|||
|
|
jsr getbyt
|
|||
|
|
sta mg+1 ; maxGamma + 1
|
|||
|
|
lda #9
|
|||
|
|
sec
|
|||
|
|
sbc mg+1 ; 8 - maxGamma == (8 + 1) - (maxGamma + 1)
|
|||
|
|
sta longrle+1
|
|||
|
|
jsr getbyt
|
|||
|
|
sta mg1+1 ; (1<<maxGamma)
|
|||
|
|
asl
|
|||
|
|
clc
|
|||
|
|
sbc #0
|
|||
|
|
sta mg21+1 ; (2<<maxGamma) - 1
|
|||
|
|
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
|
|||
|
|
0$ beq 1$ ; Y == 0 ?
|
|||
|
|
jsr getbyt
|
|||
|
|
sta table,x
|
|||
|
|
inx
|
|||
|
|
dey
|
|||
|
|
bne 0$
|
|||
|
|
1$ ; setup bit store - $80 means empty
|
|||
|
|
lda #$80
|
|||
|
|
sta bitstr
|
|||
|
|
jmp main
|
|||
|
|
|
|||
|
|
getbyt jsr getnew
|
|||
|
|
lda bitstr
|
|||
|
|
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 ; 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 ; 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 ; 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 table-1,x ; Saves one jump if done here (loses one txa)
|
|||
|
|
|
|||
|
|
cpx #16 ; 32 ; 31-32 -> C clear, 32-32 -> C set..
|
|||
|
|
bcc 1$ ; 1..31, we got the right byte from the table
|
|||
|
|
|
|||
|
|
; Ranks 32..64 (11111<31>xxxxx), get byte..
|
|||
|
|
txa ; get back the value (5 valid bits)
|
|||
|
|
ldx #4 ;3
|
|||
|
|
jsr getbits ; get 3 more bits to get a full byte, X = 0
|
|||
|
|
|
|||
|
|
1$ ldx LZPOS ; 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
|
|||
|
|
eof
|
|||
|
|
#if SHORT == 0
|
|||
|
|
; EOF
|
|||
|
|
eof clc
|
|||
|
|
eof2 lda #$37
|
|||
|
|
sta 1
|
|||
|
|
cli
|
|||
|
|
#endif
|
|||
|
|
#if IRQLOAD
|
|||
|
|
;jsr endloader
|
|||
|
|
lo = .+1
|
|||
|
|
hi = .+2
|
|||
|
|
jmp $aaaa
|
|||
|
|
#else
|
|||
|
|
hi ldx #0
|
|||
|
|
lo ldy #0
|
|||
|
|
rts
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
|
|||
|
|
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+1 ; 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 ; xstore = LZLEN (read before it's overwritten)
|
|||
|
|
sta LZPOS
|
|||
|
|
|
|||
|
|
lda OUTPOS+1
|
|||
|
|
sbc LZPOS+1 ; takes C into account
|
|||
|
|
sta LZPOS+1 ; 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 lda (LZPOS),y ; using abs,y is 3 bytes longer, only 1 cycle/byte faster
|
|||
|
|
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
|
|||
|
|
|
|||
|
|
#if IRQLOAD
|
|||
|
|
;jsr READBYTE ; should not change X or Y, return byte in A
|
|||
|
|
; An implementation would first check if any bytes are available
|
|||
|
|
; and if not, transfer a block from drive.
|
|||
|
|
#else
|
|||
|
|
INPOS = *+1
|
|||
|
|
lda $aaaa ; ** PARAMETER
|
|||
|
|
inc INPOS
|
|||
|
|
bne 0$
|
|||
|
|
inc INPOS+1
|
|||
|
|
#endif
|
|||
|
|
0$ sec
|
|||
|
|
rol ; Shift out the next bit and
|
|||
|
|
; shift in C=1 (last bit marker)
|
|||
|
|
sta bitstr ; 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
|
|||
|
|
bne 1$
|
|||
|
|
jsr getnew
|
|||
|
|
1$ 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
|
|||
|
|
bne 1$
|
|||
|
|
jsr getnew
|
|||
|
|
1$ 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 0$
|
|||
|
|
inc OUTPOS+1 ; ZP
|
|||
|
|
0$ rts
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
table dc.b 0,0,0,0,0,0,0
|
|||
|
|
dc.b 0,0,0,0,0,0,0,0
|
|||
|
|
;dc.b 0,0,0,0,0,0,0,0
|
|||
|
|
;dc.b 0,0,0,0,0,0,0,0
|
|||
|
|
|