A2osX/LIB/LIBPAK.S.txt

760 lines
14 KiB
Plaintext
Raw Normal View History

NEW
2017-12-22 21:24:30 +00:00
PREFIX /A2OSX.BUILD
AUTO 4,1
.LIST OFF
.OP 65C02
.OR $2000
.TF /A2OSX.BUILD/LIB/LIBPAK.O
*--------------------------------------
* BITSTREAM :
2018-02-08 16:39:56 +00:00
*--------------------------------------
* 0 : SHORT3 (1)+3=4 bits
* 3 bits : index in Short3 Table
*--------------------------------------
* 10 : SHORT4 (2)+4=6 bits
* 4 bits : index in Short4 Table
*--------------------------------------
* 110 : REPn (3)+5=8 bits
* 5 bits count (1+n)
*--------------------------------------
* 1110 = BACKLINK : (4)+12+8=24 bits
* 12 bits : Offset (HI-4,LO-8)
* 8 bits : 4 + n (8 bits count) (259 max)
*--------------------------------------
* 1111 : STOREn (4) + 4 cnt + 8n....
*--------------------------------------
2018-02-09 16:02:47 +00:00
PAK.B.SHORT3 .EQ %00000000 0xxx0000
PAK.B.SHORT4 .EQ %10000000 10xxxx00
PAK.B.REPn .EQ %11000000 110xxxxx
PAK.B.BACKLINK .EQ %11100000 1110hhhhllllllllxxxxxxxx
PAK.B.STOREn .EQ %11110000 1111xxxx ...
2018-02-08 16:39:56 +00:00
*--------------------------------------
WSIZE .EQ 4096
REPMAX .EQ 32
2018-02-09 16:02:47 +00:00
STOREMAX .EQ 16
*--------------------------------------
.INB /A2OSX.BUILD/INC/MACROS.I
.INB /A2OSX.BUILD/INC/A2OSX.I
2018-02-05 16:25:25 +00:00
.INB /A2OSX.BUILD/INC/LIBPAK.I
*--------------------------------------
2018-02-08 16:39:56 +00:00
ZPSrcWPtr .EQ ZPLIB
ZPSrcPtr .EQ ZPLIB+2
ZPHdrPtr .EQ ZPLIB+14
ZPDstPtr .EQ ZPLIB+16
ZPStatPtr .EQ ZPLIB+18
*--------------------------------------
* File Header (16 Bytes)
*--------------------------------------
CS.START cld
jmp (.1,x)
.DA #$61 6502,Level 1 (65c02)
.DA #1 BIN Layout Version 1
.DA 0
.DA CS.END-CS.START
.DA 0
.DA 0
.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
.1 .DA LIB.LOAD
.DA LIB.UNLOAD
.DA Pak
.DA Unpak
.DA 0
*--------------------------------------
LIB.LOAD
LIB.UNLOAD clc
rts
2018-02-05 16:25:25 +00:00
*/--------------------------------------
* # Pak
* ## In :
* PUSHW = Src PTR
* PUSHW = Src Length
* PUSHW = Dst PTR Output Buffer
* PUSHW = Dst PTR S.PAKSTAT
*\--------------------------------------
2018-02-08 16:39:56 +00:00
* PASS #1 : BL+REP dryrun with raw BYTE store (no bit prefix) -> Dst
* if BL stat=0, disable BL in PASS #2
* BuildShortTable with DST
* PASS #2 : BL with store real prefixed S3,S4,REP & STORE -> Dst
*--------------------------------------
Pak >PULLW ZPStatPtr
>PULLA
sta ZPHdrPtr
clc
adc #S.PAKHDR
2018-02-09 16:02:47 +00:00
sta ZPDstPtr
2018-02-08 16:39:56 +00:00
>PULLA
sta ZPHdrPtr+1
adc /S.PAKHDR
2018-02-09 16:02:47 +00:00
sta ZPDstPtr+1
2018-02-08 16:39:56 +00:00
>PULLW Pak.Hdr+S.PAKHDR.LEN
>PULLW Pak.SrcPtr
2018-02-09 16:02:47 +00:00
* Reset Byte counters
ldx #0
.1 stz Pak.CntL,x
stz Pak.CntH,x
inx
bne .1
2018-02-08 16:39:56 +00:00
2018-02-09 16:02:47 +00:00
* PASS #1 : REP & BL, no store, update byte counters
2018-02-08 16:39:56 +00:00
2018-02-09 07:04:19 +00:00
jsr Pak.InitPass
2018-02-08 16:39:56 +00:00
2018-02-09 16:02:47 +00:00
stz Pak.bPass2
2018-02-08 16:39:56 +00:00
2018-02-09 07:04:19 +00:00
jsr Pak.Run
bcs .9
2018-02-05 16:25:25 +00:00
2018-02-09 07:04:19 +00:00
jsr Pak.BuildShortTable
2018-02-09 16:02:47 +00:00
* PASS #2 : REP & BL, store with S3,S4
2018-02-08 16:39:56 +00:00
2018-02-09 07:04:19 +00:00
jsr Pak.InitPass
2018-02-08 16:39:56 +00:00
2018-02-09 16:02:47 +00:00
dec Pak.bPass2
2018-02-08 16:39:56 +00:00
2018-02-09 16:02:47 +00:00
lda #$80
sta Pak.Mask Initialize properly for
2018-02-08 16:39:56 +00:00
stz Pak.Byte first "PutBit" Call
2018-02-09 16:02:47 +00:00
stz Pak.StoreCnt
2018-02-09 07:04:19 +00:00
jsr Pak.Run
bcs .9
ldy #S.PAKHDR-1
2018-02-09 16:02:47 +00:00
.2 lda Pak.Hdr,y
2018-02-09 07:04:19 +00:00
sta (ZPHdrPtr),y
dey
2018-02-09 16:02:47 +00:00
bpl .2
2018-02-08 16:39:56 +00:00
ldy #S.PAKSTAT-1
2018-02-09 16:02:47 +00:00
.3 lda Pak.Stat,y
2018-02-08 16:39:56 +00:00
sta (ZPStatPtr),y
dey
2018-02-09 16:02:47 +00:00
bpl .3
2018-02-08 16:39:56 +00:00
clc
rts
2018-02-09 07:04:19 +00:00
2018-02-08 16:39:56 +00:00
.9 lda #K.E.OOM
sec
rts
*--------------------------------------
Pak.InitPass >LDYA Pak.SrcPtr
>STYA ZPSrcPtr
>STYA Pak.WPtr
lda Pak.Hdr+S.PAKHDR.LEN
eor #$ff
sta Pak.SrcCnt
2018-02-08 16:39:56 +00:00
lda Pak.Hdr+S.PAKHDR.LEN+1
eor #$ff
sta Pak.SrcCnt+1
2018-02-08 16:39:56 +00:00
lda #$ff RepChar invalid
sta Pak.RepCnt
2018-02-09 07:04:19 +00:00
ldx #S.PAKSTAT.PASS2
2018-02-08 16:39:56 +00:00
.1 stz Pak.Stat,x Reset Stats
inx
cpx #S.PAKSTAT
bne .1
rts
*--------------------------------------
2018-02-09 07:04:19 +00:00
Pak.Run lda #$ff
2018-02-08 16:39:56 +00:00
cmp Pak.SrcCnt+1 return 255 if not $ffxx
2018-02-09 07:04:19 +00:00
bne .1
2018-02-08 16:39:56 +00:00
lda Pak.SrcCnt
eor #$ff return !xx if $ffxx
2018-02-09 07:04:19 +00:00
beq .8 0 byte left...
.1 cmp #4 less than 4 chars, give up BL
bcc .4
sta Pak.MaxReadAhead
stz Pak.BestBLLen
ldx #3
.2 inx
jsr Pak.ScanBL
bcs .3
>STYA Pak.BestBL
stx Pak.BestBLLen
cpx Pak.MaxReadAhead
bne .2
.3 lda Pak.BestBLLen
beq .4 NO BL found....
lda Pak.BestBL+1
ora #PAK.B.BACKLINK %1110 + Ofs.HI
jsr Pak.PutA
bcs .9
lda Pak.BestBL get Ofs.LO
jsr Pak.PutA
bcs .9
lda Pak.BestBLLen get back len
jsr Pak.PutA
bcs .9
lda Pak.BestBLLen
jsr Pak.SrcForward
ldx #S.PAKSTAT.BL
jsr Pak.UpdateStats
bra Pak.Run
.4 lda (ZPSrcPtr)
jsr Pak.PutA
bcs .9
lda #1
jsr Pak.SrcForward
bra Pak.Run
2018-02-09 16:02:47 +00:00
.8 lda Pak.RepCnt do we have a pending REP ?
beq .80
ora #PAK.B.REPn yes, add it
jmp Pak.PutA.1
.80 clc
2018-02-09 07:04:19 +00:00
.9 rts
2018-02-08 16:39:56 +00:00
*--------------------------------------
Pak.SrcForward pha Len
2018-02-09 07:04:19 +00:00
2018-02-08 16:39:56 +00:00
clc
adc ZPSrcPtr
sta ZPSrcPtr
bcc .1
clc
inc ZPSrcPtr+1
.1 pla
adc Pak.SrcCnt
sta Pak.SrcCnt
bcc .2
inc Pak.SrcCnt+1
.2 sec
lda ZPSrcPtr
sbc #WSIZE
tay
2018-02-08 16:39:56 +00:00
lda ZPSrcPtr+1
sbc /WSIZE
tax
2018-02-08 16:39:56 +00:00
cpy Pak.WPtr
sbc Pak.WPtr+1
2018-02-09 07:04:19 +00:00
bcc .8
2018-02-08 16:39:56 +00:00
sty Pak.WPtr
stx Pak.WPtr+1
.8 rts
*--------------------------------------
* Scan between Pak.WPtr & ZPSrcPtr-A
* Byte string at ZPSrcPtr (len A)
2018-02-09 07:04:19 +00:00
* IN : X = Byte string length
2018-02-08 16:39:56 +00:00
* OUT : CC: Y,A=offset to BL
*--------------------------------------
2018-02-09 07:04:19 +00:00
Pak.ScanBL stx Pak.WStrLen
2018-02-05 16:25:25 +00:00
2018-02-08 16:39:56 +00:00
sec
lda ZPSrcPtr WLimit=ZPSrcPtr-WStrLen
sbc Pak.WStrLen
sta Pak.WLimit
lda ZPSrcPtr+1
sbc #0
sta Pak.WLimit+1
2018-02-08 16:39:56 +00:00
lda Pak.WLimit
sec
sbc Pak.WPtr
eor #$ff
sta Pak.Cnt
lda Pak.WLimit+1
sbc Pak.WPtr+1
eor #$ff
sta Pak.Cnt+1
2018-02-05 16:25:25 +00:00
2018-02-08 16:39:56 +00:00
bcc .9 WLimit < Pak.WPtr
2018-02-08 16:39:56 +00:00
lda Pak.WPtr
sta ZPSrcWPtr
lda Pak.WPtr+1
sta ZPSrcWPtr+1
ldy #0
.1 lda (ZPSrcWPtr),y
cmp (ZPSrcPtr),y
bne .6
iny
cpy Pak.WStrLen
bne .1
sec
lda ZPSrcPtr
sbc ZPSrcWPtr
tay
lda ZPSrcPtr+1
sbc ZPSrcWPtr+1
clc
rts
.6 inc ZPSrcWPtr
bne .7
inc ZPSrcWPtr+1
.7 inc Pak.Cnt
bne .1
inc Pak.Cnt+1
bne .1
2018-02-08 16:39:56 +00:00
.9 sec
rts
*--------------------------------------
Pak.BuildShortTable
ldy #0
2018-02-08 16:39:56 +00:00
.6 stz Pak.Cnt Init best score to 0
stz Pak.Cnt+1
ldx #0
2018-02-08 16:39:56 +00:00
.7 lda Pak.Cnt
cmp Pak.CntL,x is it better at X
lda Pak.Cnt+1
sbc Pak.CntH,x
2018-02-09 16:02:47 +00:00
bcs .8 not better or equal...
2018-02-08 16:39:56 +00:00
stx Pak.Byte save new score index...
lda Pak.CntL,x
2018-02-08 16:39:56 +00:00
sta Pak.Cnt ...and value
lda Pak.CntH,x
sta Pak.Cnt+1
.8 inx
bne .7
lda Pak.Byte
2018-02-08 16:39:56 +00:00
sta Pak.Hdr+S.PAKHDR.SHORT3,y
tax
stz Pak.CntL,x Discard this entry
stz Pak.CntH,x
2018-02-08 16:39:56 +00:00
iny
cpy #24
bne .6
2018-02-05 16:25:25 +00:00
rts
2018-02-08 16:39:56 +00:00
*--------------------------------------
Pak.PutA bit Pak.RepCnt
bpl .1
2018-02-08 16:39:56 +00:00
stz Pak.RepCnt LastByte invalid...
sta Pak.LastByte
bra Pak.PutA.1 send first byte.
2018-02-08 16:39:56 +00:00
.1 cmp Pak.LastByte
beq .3
2018-02-08 16:39:56 +00:00
sta Pak.LastByte save new byte
lda Pak.RepCnt do we have a pending REP ?
beq .2
2018-02-08 16:39:56 +00:00
ora #PAK.B.REPn yes, send it
jsr Pak.PutA.1
bcs .9
ldx #S.PAKSTAT.REP
jsr Pak.UpdateStats
2018-02-08 16:39:56 +00:00
stz Pak.RepCnt
2018-02-08 16:39:56 +00:00
.2 lda Pak.LastByte
bra Pak.PutA.1
2018-02-08 16:39:56 +00:00
.3 inc Pak.RepCnt
lda Pak.RepCnt
cmp #REPMAX
bne .8
2018-02-05 16:25:25 +00:00
2018-02-08 16:39:56 +00:00
dec
ora #PAK.B.REPn
jsr Pak.PutA.1
2018-02-05 16:25:25 +00:00
bcs .9
2018-02-08 16:39:56 +00:00
lda #1
sta Pak.RepCnt
2018-02-08 16:39:56 +00:00
ldx #S.PAKSTAT.REP
jsr Pak.UpdateStats
2018-02-08 16:39:56 +00:00
.8 clc
.9 rts
2018-02-09 16:02:47 +00:00
Pak.PutA.1 bit Pak.bPass2
2018-02-09 07:04:19 +00:00
bmi .10
2018-02-09 16:02:47 +00:00
tax
inc Pak.CntL,x
bne .11
inc Pak.CntH,x
.11 inc Pak.Stat+S.PAKSTAT.PASS1
bne .12
inc Pak.Stat+S.PAKSTAT.PASS1+1
.12 clc
rts
* Pak.PutA.1 PASS #2
2018-02-09 07:04:19 +00:00
.10 ldy #7
.1 cmp Pak.Hdr+S.PAKHDR.SHORT3,y
beq .3
dey
bpl .1
2018-02-09 07:04:19 +00:00
ldy #15
.2 cmp Pak.Hdr+S.PAKHDR.SHORT4,y
beq .4
dey
bpl .2
2018-02-09 07:04:19 +00:00
bra .7
.3 tya
asl
asl
asl
asl
ora #PAK.B.SHORT3
ldy #4
ldx #S.PAKSTAT.S3
bra .8
.4 tya
asl
asl
ora #PAK.B.SHORT4
ldy #6
ldx #S.PAKSTAT.S4
bra .8
2018-02-09 16:02:47 +00:00
.7 ldx Pak.StoreCnt
sta Pak.StoreBuf,x
inx
cpx #STOREMAX
beq Pak.Flush
stx Pak.StoreCnt
clc
rts
2018-02-09 07:04:19 +00:00
.8 jsr Pak.UpdateStats
*--------------------------------------
Pak.PutYBits asl
jsr Pak.PutBit
2018-02-05 16:25:25 +00:00
bcs .9
dey
bne Pak.PutYBits
2018-02-05 16:25:25 +00:00
.9 rts
*--------------------------------------
2018-02-09 16:02:47 +00:00
Pak.Flush ldx Pak.StoreCnt
beq .8
lda #PAK.B.STOREn
ldy #4
jsr Pak.PutYBits
bcs .9
ldx #0
.1 lda Pak.StoreBuf,x
ldy #4
jsr Pak.PutYBits
bcs .9
inx
dec Pak.StoreCnt
bne .1
ldx #S.PAKSTAT.STORE
jsr Pak.UpdateStats
.8 clc
.9 rts
*--------------------------------------
* Pak.PutBit (bit in C)
*--------------------------------------
2018-02-09 16:02:47 +00:00
Pak.PutBit pha
2018-02-05 16:25:25 +00:00
2018-02-09 16:02:47 +00:00
bcc .1
lda Pak.Mask
tsb Pak.Byte
clc
2018-02-05 16:25:25 +00:00
2018-02-09 16:02:47 +00:00
.1 lsr Pak.Mask
bne .8
2018-02-05 16:25:25 +00:00
jsr Pak.PutByte
2018-02-05 16:25:25 +00:00
bcs .9
stz Pak.Byte
2018-02-09 16:02:47 +00:00
lda #$80
2018-02-09 16:02:47 +00:00
sta Pak.Mask
2018-02-05 16:25:25 +00:00
.8 pla
2018-02-09 16:02:47 +00:00
* clc
2018-02-05 16:25:25 +00:00
rts
2018-02-09 16:02:47 +00:00
.9 pla
* sec
2018-02-05 16:25:25 +00:00
rts
*--------------------------------------
2018-02-05 16:25:25 +00:00
Pak.PutByte inc Pak.DstCnt
bne .1
2018-02-05 16:25:25 +00:00
inc Pak.DstCnt+1
beq .9
2018-02-08 16:39:56 +00:00
.1 sta (ZPDstPtr)
2018-02-09 16:02:47 +00:00
2018-02-08 16:39:56 +00:00
inc ZPDstPtr
bne .2
2018-02-08 16:39:56 +00:00
inc ZPDstPtr+1
2018-02-05 16:25:25 +00:00
2018-02-08 16:39:56 +00:00
.2 inc Pak.Stat+S.PAKSTAT.PASS2
2018-02-05 16:25:25 +00:00
bne .8
2018-02-08 16:39:56 +00:00
inc Pak.Stat+S.PAKSTAT.PASS2+1
2018-02-05 16:25:25 +00:00
.8 clc
rts
.9 sec
rts
*--------------------------------------
2018-02-08 16:39:56 +00:00
Pak.UpdateStats inc Pak.Stat,x
bne .8
2018-02-08 16:39:56 +00:00
inc Pak.Stat+1,x
.8 rts
2018-02-08 16:39:56 +00:00
*/--------------------------------------
* UnPak
* In :
2018-02-08 16:39:56 +00:00
* PUSHW = Src PTR Compressed Buffer
* PUSHW = Dst PTR
*/--------------------------------------
UnZPSrcPtr .EQ ZPLIB
UnZPDstPtr .EQ ZPLIB+2
UnPak.ShrtTbl .EQ ZPLIB+4
UnPak.Cnt .EQ ZPLIB+6
*--------------------------------------
2018-02-08 16:39:56 +00:00
UnPak >PULLA Get Dst PTR LO
sec
sbc #1
2018-02-08 16:39:56 +00:00
sta UnZPDstPtr
>PULLA Get Dst PTR HI
sbc #0
2018-02-08 16:39:56 +00:00
sta UnZPDstPtr+1 setup Dst PTR-1
>PULLW UnZPSrcPtr
jsr UnPak.GetByte Get !LEN for counting up to $0000
sta UnPak.Cnt
jsr UnPak.GetByte
sta UnPak.Cnt+1
2018-02-08 16:39:56 +00:00
>LDYA UnZPSrcPtr Get PTR to Short Table.....
>STYA UnPak.ShrtTbl and save it for SHORTx
lda #8
sta UnPak.GetBit+1 Initialize properly for first "GetBit" Call
.1 inc UnPak.Cnt
bne .2
inc UnPak.Cnt+1
beq .99
.2 jsr UnPak.GetBit
bcs .4 CMD....
*---- STORE
jsr UnPak.GetBit
ldx #1
bcc .3 if CC one byte
jsr UnPak.Get4Bits CC
adc #2 range is 2->17
tax
.3 jsr UnPak.Get8Bits
jsr UnPak.PutByte
dex
bne .3
bra .1
.99 rts
*---- CMD
.4 jsr UnPak.GetBit
bcs .6 BACKLINK or REP...
*---- CMD : SHORT
lda #0
ldy #4
jsr UnPak.GetBit if CS short3
rol make offset 00000001
asl ....00000010
beq .5
dey if short3, only 3 bits
.5 jsr UnPak.GetBit
rol
dey
bne .5
tay if s3, offset is 00010xxx
lda (UnPak.ShrtTbl),y if s4, offset is 0000xxxx
jsr UnPak.PutByte
bra .1
*---- CMD : BACKLINK or REP
.6 jsr UnPak.GetBit
bcs .8 if CS -> REP
*---- CMD : BACKLINK
jsr UnPak.Get8Bits get Offset LO, (CC)
eor #$ff !offset LO
2018-02-08 16:39:56 +00:00
adc UnZPDstPtr equiv. SUB offset
sta .7+1 PTR to Backlink LO
2018-02-08 16:39:56 +00:00
lda UnZPDstPtr+1
bcs .61 if ADC sets C, no need to dec HI
dec
.61 jsr UnPak.GetBit get Offset HI in C
bcc .62
dec
.62 sta .7+2 PTR to Backlink HI
jsr UnPak.Get4Bits CC
adc #3 Backlink are ate least 3 bytes...
tax
ldy #0
.7 lda $ffff,y Self Modified code : PTR to Backlink
jsr UnPak.PutByte
iny
dex
bne .7
beq .1
*---- CMD : REP
.8 jsr UnPak.GetBit
ldx #1
bcc .9 REP 1
jsr UnPak.Get4Bits REP xxxx, CC
adc #2 range is 2->17
tax
2018-02-08 16:39:56 +00:00
.9 lda (UnZPDstPtr) Get Last Byte
jsr UnPak.PutByte
dex
bne .9
jmp .1
*--------------------------------------
UnPak.Get8Bits ldy #8
.HS 2C bit abs
UnPak.Get4Bits ldy #4
lda #0 make sure to reset A before reading less than 8 bits only
.1 jsr UnPak.GetBit and to exit with CC if even if 8 bits read
rol
dey
bne .1
rts always CC
*--------------------------------------
UnPak.GetBit ldx #$ff Self Modified code
bne .1
jsr UnPak.NxtByte
ldx #8
.1 dex
stx UnPak.GetBit+1
pha Don't trash A
2018-02-08 16:39:56 +00:00
lda (UnZPSrcPtr)
and UnPak.BitMask,x
cmp #1 if 0:CC, i>0 CS
pla
rts Bit is in C
*--------------------------------------
2018-02-08 16:39:56 +00:00
UnPak.GetByte lda (UnZPSrcPtr)
UnPak.NxtByte inc UnZPSrcPtr
bne .8
2018-02-08 16:39:56 +00:00
inc UnZPSrcPtr+1
.8 rts
*--------------------------------------
2018-02-08 16:39:56 +00:00
UnPak.PutByte inc UnZPDstPtr
bne .8
2018-02-08 16:39:56 +00:00
inc UnZPDstPtr+1
.8 sta (UnZPDstPtr)
rts
*--------------------------------------
CS.END
2018-02-08 16:39:56 +00:00
Pak.SrcPtr .BS 2
Pak.SrcCnt .BS 2
2018-02-05 16:25:25 +00:00
Pak.DstCnt .BS 2
2018-02-08 16:39:56 +00:00
Pak.RepCnt .BS 1
Pak.LastByte .BS 1
2018-02-09 16:02:47 +00:00
Pak.StoreCnt .BS 1
Pak.StoreBuf .BS STOREMAX
Pak.Mask .BS 1
Pak.Byte .BS 1
2018-02-08 16:39:56 +00:00
Pak.Cnt .BS 2
2018-02-09 16:02:47 +00:00
Pak.bPass2 .BS 1
2018-02-09 07:04:19 +00:00
Pak.MaxReadAhead .BS 1
Pak.BestBLLen .BS 1
Pak.BestBL .BS 2
2018-02-08 16:39:56 +00:00
Pak.WPtr .BS 2
Pak.WLimit .BS 2
Pak.WStrLen .BS 1
*--------------------------------------
2018-02-08 16:39:56 +00:00
Pak.CntL .BS 256
Pak.CntH .BS 256
Pak.Hdr .BS S.PAKHDR
Pak.Stat .BS S.PAKSTAT
*--------------------------------------
UnPak.BitMask .HS 8040201008040201
MAN
SAVE /A2OSX.SRC/LIB/LIBPAK.S
ASM