NEW AUTO 3,1 .LIST OFF .OP 65C02 .OR $2000 .TF lib/libpak *-------------------------------------- .INB inc/macros.i .INB inc/a2osx.i .INB inc/libpak.i *-------------------------------------- STATS .EQ 0 *-------------------------------------- ZPSrcPtr .EQ ZPLIB ZPDstPtr .EQ ZPLIB+2 ZPStatPtr .EQ ZPLIB+4 ZPSrcBLPtr .EQ ZPLIB+6 ZPCnt .EQ ZPLIB+8 ZPBLCnt .EQ ZPLIB+10 *-------------------------------------- * 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 .DO STATS=1 L.MSG.Stats .DA MSG.Stats L.MSG.TopBytes .DA MSG.TopBytes .FIN .DA 0 *-------------------------------------- LIB.LOAD LIB.UNLOAD clc rts */-------------------------------------- * # Pak * ##ASM * `>PUSHW StatPtr` * `>PUSHW DstPtr` * `>PUSHW SrcLen` * `>PUSHW SrcPtr` * `>LIBCALL hLIBPAK,Pak` * ## RETURN VALUE * CC, Y,A = CLEN * CS, Pak failure *\-------------------------------------- Pak >PULLW Pak.SrcPtr >PULLW Pak.Shnk+S.PAKSHNK.ULEN >PULLW ZPDstPtr >PULLW ZPStatPtr * Reset Byte counters ldx #0 .1 stz Pak.CntL,x stz Pak.CntH,x inx bne .1 ldx #S.PAKSTAT.PASS2+1 .2 stz Pak.Stat,x Reset Stats dex bpl .2 * PASS #1 : no store, update byte counters stz Pak.bPass2 jsr Pak.Out.Init Initialize properly for first "PutBit" Call bcs .9 jsr Pak.Run jsr Pak.ComputeLenBits jsr Pak.BuildTOPTable .DO STATS=1 jsr Pak.PrintStats .FIN * PASS #2 : store with TOP bytes dec Pak.bPass2 jsr Pak.Out.Init Initialize properly for first "PutBit" Call bcs .9 jsr Pak.Run bcs .9 jsr Pak.Out.Close bcs .9 ldy #S.PAKSTAT-1 .7 lda Pak.Stat,y sta (ZPStatPtr),y dey bpl .7 .DO STATS=1 jsr Pak.PrintStats .FIN >LDYA Pak.Stat+S.PAKSTAT.PASS2 clc .DO STATS=1 rts .FIN .9 .DO STATS=1 jsr Pak.PrintStats sec .FIN rts *-------------------------------------- Pak.Out.Init lda Pak.Shnk+S.PAKSHNK.ULEN eor #$ff sta Pak.SrcCnt sta Pak.DstCnt lda Pak.Shnk+S.PAKSHNK.ULEN+1 eor #$ff sta Pak.SrcCnt+1 sta Pak.DstCnt+1 bit Pak.bPass2 bpl .8 lda Pak.Shnk+S.PAKSHNK.BLBITS jsr Pak.Out.PutByte bcs .9 lda Pak.Shnk+S.PAKSHNK.ULEN jsr Pak.Out.PutByte bcs .9 lda Pak.Shnk+S.PAKSHNK.ULEN+1 jsr Pak.Out.PutByte bcs .9 lda Pak.Shnk+S.PAKSHNK.TOPCNT jsr Pak.Out.PutByte bcs .9 tax ldy #0 .1 lda Pak.Shnk+S.PAKSHNK.TOPBYTES,y jsr Pak.Out.PutByte bcs .9 iny dex bne .1 lda #$80 sta Pak.Out.Mask stz Pak.Out.Byte .8 clc .9 rts *-------------------------------------- Pak.Run >LDYA Pak.SrcPtr >STYA ZPSrcPtr stz Pak.BL.Longest stz Pak.BL.Farest stz Pak.BL.Farest+1 ldx #S.PAKSTAT.TOP8 .1 stz Pak.Stat,x Reset Stats inx cpx #S.PAKSTAT bne .1 Pak.Run.1 inc Pak.SrcCnt bne .1 inc Pak.SrcCnt+1 beq .8 0 byte left... .1 jsr Pak.ScanBL bcs .20 jsr Pak.PutBL bcs .9 ldy Pak.BestBLLen .6 tya clc adc ZPSrcPtr sta ZPSrcPtr bcc .7 inc ZPSrcPtr+1 .7 tya clc adc Pak.SrcCnt sta Pak.SrcCnt bcc .1 inc Pak.SrcCnt+1 bmi .1 .8 clc .9 rts .20 lda (ZPSrcPtr) Not found... jsr Pak.PutByte8 bcs .9 inc ZPSrcPtr bne Pak.Run.1 inc ZPSrcPtr+1 bra Pak.Run.1 *-------------------------------------- Pak.ScanBL >LDYA Pak.SrcPtr Start at beginning of Src buf >STYA ZPSrcBLPtr lda #$ff sta Pak.bBLFound stz Pak.BestBLLen .1 lda ZPSrcBLPtr sec sbc ZPSrcPtr sta ZPBLCnt lda ZPSrcBLPtr+1 sbc ZPSrcPtr+1 sta ZPBLCnt+1 ZPSrcBLPtr < !BlCnt < ZPSrcPtr bcs .8 ZPSrcBLPtr = ZPSrcPtr, exit >LDYA Pak.SrcCnt make sure not going past End Buffer >STYA ZPCnt while reading ahead ldy #0 ...or Y = BL.MAX .2 inc ZPBLCnt bne .3 inc ZPBLCnt+1 beq .6 ZPSrcBLPtr = ZPSrcPtr .3 inc ZPCnt bne .4 inc ZPCnt+1 beq .6 Last Src Data .4 lda (ZPSrcPtr),y cmp (ZPSrcBLPtr),y bne .6 End of string matching .5 iny cpy #BL.MAX bne .2 Max BL len .6 cpy #BL.MIN bcc .7 not long enough cpy Pak.BestBLLen bcc .7 not better ... * beq .7 !!! same...but closer !!! sty Pak.BestBLLen lda ZPSrcPtr sec sbc ZPSrcBLPtr sta Pak.BestBL lda ZPSrcPtr+1 sbc ZPSrcBLPtr+1 sta Pak.BestBL+1 stz Pak.bBLFound .7 inc ZPSrcBLPtr bne .1 inc ZPSrcBLPtr+1 bra .1 .8 rol Pak.bBLFound rts *-------------------------------------- Pak.ComputeLenBits ldx #0 lda Pak.BL.Longest beq .10 ldx #3 dec dec dec beq .10 ldx #8 .1 asl bcs .10 dex bra .1 .10 stx Pak.BL.LenBits ldx #0 ldy #0 lda Pak.BL.Farest+1 beq .22 ldy #8 ldx #8 .2 asl bcs .4 dey bra .2 .22 lda Pak.BL.Farest beq .4 ldx #8 .3 asl bcs .4 dex bra .3 .4 stx Pak.BL.OfsBitsL sty Pak.BL.OfsBitsH lda Pak.BL.LenBits asl asl asl asl adc Pak.BL.OfsBitsL adc Pak.BL.OfsBitsH ora #$80 sta Pak.Shnk+S.PAKSHNK.BLBITS rts *-------------------------------------- Pak.BuildTOPTable ldy #0 .1 stz Pak.Cnt Init best score to 0 stz Pak.Cnt+1 sec ror Pak.bStop ldx #0 .2 lda Pak.CntL,x ora Pak.CntH,x beq .3 stz Pak.bStop lda Pak.Cnt cmp Pak.CntL,x is it better at X lda Pak.Cnt+1 sbc Pak.CntH,x bcs .3 not better or equal... stx Pak.Top.Best save new score index... lda Pak.CntL,x sta Pak.Cnt ...and value lda Pak.CntH,x sta Pak.Cnt+1 .3 inx bne .2 bit Pak.bStop bmi .8 lda Pak.Top.Best sta Pak.Shnk+S.PAKSHNK.TOPBYTES,y tax stz Pak.CntL,x Discard this entry stz Pak.CntH,x iny cpy #TOP.MAX bne .1 .8 sty Pak.Shnk+S.PAKSHNK.TOPCNT Pak.BuildTOPTable.RTS rts *-------------------------------------- Pak.PutBL ldx #S.PAKSTAT.BL jsr Pak.UpdateStats lda Pak.BestBLLen cmp Pak.BL.Longest bcc .1 sta Pak.BL.Longest .1 ldy Pak.BestBL cpy Pak.BL.Farest lda Pak.BestBL+1 pha sbc Pak.BL.Farest+1 pla bcc .2 >STYA Pak.BL.Farest .2 bit Pak.bPass2 bmi .3 ldx #S.PAKSTAT.PASS1 Assume 1 BL worse case is 3 bytes jsr Pak.UpdateStats jsr Pak.UpdateStats jsr Pak.UpdateStats clc rts .3 ldy #PAK.B.BL.W lda #PAK.B.BL jsr Pak.Out.PutYBits bcs Pak.BuildTOPTable.RTS ldy Pak.BL.OfsBitsL lda Pak.BestBL jsr Pak.Out.PutYBits bcs Pak.BuildTOPTable.RTS ldy Pak.BL.OfsBitsH beq .4 lda Pak.BestBL+1 jsr Pak.Out.PutYBits bcs Pak.BuildTOPTable.RTS .4 ldy Pak.BL.LenBits lda Pak.BestBLLen dec dec dec jmp Pak.Out.PutYBits *-------------------------------------- Pak.PutByte8 bit Pak.bPass2 bmi Pak.PutByte8.2 .5 tax inc Pak.CntL,x bne .6 inc Pak.CntH,x .6 ldx #S.PAKSTAT.BYTE8 jsr Pak.UpdateStats ldx #S.PAKSTAT.PASS1 jsr Pak.UpdateStats clc rts Pak.PutByte8.2 ldy Pak.Shnk+S.PAKSHNK.TOPCNT beq .2 No TOP Table .1 cmp Pak.Shnk+S.PAKSHNK.TOPBYTES-1,y beq .3 dey bne .1 .2 ldx #S.PAKSTAT.BYTE8 jsr Pak.UpdateStats pha ldy #PAK.B.BYTE8.W lda #PAK.B.BYTE8 jsr Pak.Out.PutYBits pla bcs .9 ldy #8 jmp Pak.Out.PutYBits .3 dey Range 0-31 tya lsr lsr lsr tax Range 0-3 tya and #7 ora TOP.Bits,x ldy TOP.BitCnt,x .4 pha lda TOP.Stat,x tax jsr Pak.UpdateStats pla jmp Pak.Out.PutYBits .9 rts *-------------------------------------- Pak.Out.Close bit Pak.Out.Mask bmi .8 lda Pak.Out.Byte bra Pak.Out.PutByte .8 clc rts *-------------------------------------- Pak.Out.PutYBits phy .1 cpy #8 beq .2 asl iny bra .1 .2 ply .3 asl pha bcc .4 lda Pak.Out.Mask tsb Pak.Out.Byte .4 lsr Pak.Out.Mask bcc .5 ror Pak.Out.Mask lda Pak.Out.Byte stz Pak.Out.Byte jsr Pak.Out.PutByte .5 pla bcs .9 dey bne .3 * clc rts .9 lda #E.BUF sec rts *-------------------------------------- Pak.Out.PutByte inc Pak.DstCnt bne .1 inc Pak.DstCnt+1 beq .9 .1 sta (ZPDstPtr) inc ZPDstPtr bne .2 inc ZPDstPtr+1 .2 inc Pak.Stat+S.PAKSTAT.PASS2 bne .8 inc Pak.Stat+S.PAKSTAT.PASS2+1 .8 clc rts .9 lda #E.BUF sec rts *-------------------------------------- Pak.UpdateStats inc Pak.Stat,x bne .8 inc Pak.Stat+1,x .8 rts *-------------------------------------- .DO STATS=1 Pak.PrintStats lda Pak.BL.OfsBitsL clc adc Pak.BL.OfsBitsH >PUSHA >PUSHW Pak.BL.Farest >PUSHB Pak.BL.LenBits >PUSHB Pak.BL.Longest >PUSHW Pak.Stat+S.PAKSTAT.BL ldx #S.PAKSTAT.BYTE8 .1 >PUSHW Pak.Stat,x dex dex bpl .1 >PUSHW Pak.Shnk+S.PAKSHNK.ULEN >PUSHBI 23 >LDYA L.MSG.Stats >SYSCALL PrintF ldx #TOP.MAX-1 .2 >PUSHB Pak.Shnk+S.PAKSHNK.TOPBYTES,x dex bpl .2 >PUSHB Pak.Shnk+S.PAKSHNK.TOPCNT >PUSHBI TOP.MAX+1 >LDYA L.MSG.TopBytes >SYSCALL PrintF bit Pak.bPass2 bpl .9 >DEBUG .9 rts .FIN *-------------------------------------- CS.END *-------------------------------------- .DO STATS=1 MSG.Stats .CS "\r\nLength : %5D\r\n" .CS "Pass 1 : %5D\r\n" .CS "Pass 2 : %5D\r\n" .CS "Top 8 : %5D\r\n" .CS "Top 16 : %5D\r\n" .CS "Top 24 : %5D\r\n" .CS "Top 32 : %5D\r\n" .CS "Byte 8 : %5D\r\n" .CZ "BL : %5D, Longest : %d (%d bits), Farest : %D (%d bits)\r\n" MSG.TopBytes .CS "Top : (%2d) %h.%h.%h.%h.%h.%h.%h.%h %h.%h.%h.%h.%h.%h.%h.%h\r\n" .CZ " %h.%h.%h.%h.%h.%h.%h.%h %h.%h.%h.%h.%h.%h.%h.%h\r\n" .FIN TOP.Bits .DA #PAK.B.TOP8,#PAK.B.TOP16,#PAK.B.TOP24,#PAK.B.TOP32 TOP.BitCnt .DA #PAK.B.TOP8.W,#PAK.B.TOP16.W,#PAK.B.TOP24.W,#PAK.B.TOP32.W TOP.Stat .DA #S.PAKSTAT.TOP8,#S.PAKSTAT.TOP16,#S.PAKSTAT.TOP24,#S.PAKSTAT.TOP32 *-------------------------------------- Pak.SrcPtr .BS 2 Pak.SrcCnt .BS 2 Pak.DstCnt .BS 2 Pak.bPass2 .BS 1 Pak.BL.Longest .BS 1 Pak.BL.Farest .BS 2 Pak.BL.LenBits .BS 1 Pak.BL.OfsBitsL .BS 1 Pak.BL.OfsBitsH .BS 1 Pak.bBLFound .BS 1 Pak.BestBLLen .BS 1 Pak.BestBL .BS 2 Pak.Top.Best .BS 1 Pak.Cnt .BS 2 Pak.bStop .BS 1 Pak.Out.Byte .BS 1 Pak.Out.Mask .BS 1 *-------------------------------------- Pak.CntL .BS 256 Pak.CntH .BS 256 Pak.Shnk .BS S.PAKSHNK Pak.Stat .BS S.PAKSTAT *-------------------------------------- MAN SAVE usr/src/lib/libpak.s ASM