; ; An experimental tiny-compressor ; ; SLJ 7/02 ; ; written using DASM ; processor 6502 org $0801 ;Code at $4000 bitcount = $2b ;$01 initially (basic text) dest = $73 ;$7ae6 initially (CHRGET routine -- inc $7a) point = $fa count = $fc temp = $fe CHROUT = $ffd2 CHRIN = $ffcf CLRCHN = $ffcc SETNAM = $ffbd SETLFS = $ffba OPEN = $ffc0 CLOSE = $ffc3 LOAD = $ffd5 SAVE = $ffd8 CHKIN = $ffc6 CHKOUT = $ffc9 ;-------------------- ; basic header ;-------------------- word 2059 word 2002 byte $9e,"2061",00,00,00 Start lda #00 sta $d021 lda #$40 ;Control msg only sta $9d jsr GetFile jsr SetJump jsr Profile jsr PressKey jsr Compress jsr OutputFile lda #13 jsr $ffd2 jsr PressKey ; lda #jump ; sta jump+2 ; lda #$01 ; sta $2d ; sta $2b ; lda #$08 ; sta $2c ; lda #$0d ; ldx #$0a ; ldy #00 ; jmp entry lda #00 sta $9d jmp $ff8a ;------------------------------ ; Profile -- find most common ; bytes and best bit count ;------------------------------ Profile subroutine jsr Working ldx #00 txa .l1 sta $c000,x sta $c100,x sta $c200,x sta $c300,x sta $c400,x inx bne .l1 jsr CountBytes ; ; Find the best choice of n=number of bits to use ; ; formula is bytes = literals + (total + (n-1)*cbytes)/8 + 2^(n-1) ; where ; total = total number of bytes ; cbytes= number of compressed bytes ; literals = total - cbytes ; and the last +2^(n-1) is for storing the lookup table ; BestBits subroutine lda #$ff sta bestlen+1 ; lda endaddr ; sec ; sbc startaddr ; sta len ; lda endaddr+1 ; sbc startaddr+1 ; sta len+1 jsr STROUT byte "BIT PERFORMANCE: BYTES IN=$",00 lda len+1 ldx len jsr HEX16 lda #13 jsr $ffd2 ldx #2 ;n=2..6 .loop ldy twotab-1,x ;.y = 2^(x-1) jsr AddCBytes ;(total+(n-1)*cbytes)/8 lda len sec sbc $c300,y ;total-cbytes pha lda len+1 sbc $c400,y sta temp pla clc adc count sta count lda temp adc count+1 sta count+1 ;total number of bytes reduced tya clc adc count ;+ 2^(n-1) storage sta count bcc .c0 inc count+1 .c0 lda count clc adc #lookup adc #00 sta bitdest+2 lda bitdest+1 sec sbc #decompress sta temp+1 lda temp clc adc #codedest sta temp+1 lda temp ;.X=$0a initially, starts at +1 sec sbc #$0b sta src+1 lda temp+1 sbc #00 sta src+2 ;bitstream location + offset lda #8 sta cbit lda #$40 ;Code loaded to $4000 sta point+1 lda #00 sta point .loop ldy #00 lda (point),y jsr EncodeByte inc point bne .c1 lda #"." jsr $ffd2 inc point+1 .c1 lda point cmp endaddr lda point+1 sbc endaddr+1 bcc .loop jsr BitDone lda #13 jmp $ffd2 ; ; Encode a byte, code or literal ; EncodeByte subroutine ldy bestn ldx twotab-1,y ;2^(n-1) .l1 dex bmi .literal cmp lookup,x ;see if in table bne .l1 .code txa ;.x = lookup number ldx #9 .l2 asl ;left-justify bits dex cpx bestn bne .l2 clc bcc .out .literal sec ldx #9 .out jsr BitOut asl dex bne .out rts ; ; Output a single bit ; cbit byte 00 BitOut subroutine bitdest rol $6000 dec cbit bne .rts pha lda #8 sta cbit inc bitdest+1 bne .pla inc bitdest+2 .pla pla .rts rts bitjsr jsr BitOut ;C clear BitDone lda cbit cmp #8 bcc bitjsr rts ;--------------------------- ; Output the final file ;--------------------------- OutputFile subroutine jsr STROUT byte 13 byte "OUTPUT FILENAME? ",00 jsr GetName ldx $b7 ldy #00 .l0 lda .txt,y sta $0200,x inx iny cpy #4 bne .l0 stx $b7 ;filename length ldx $ba lda #8 ldy #8 jsr SETLFS jsr OPEN bcs .error ldx #8 jsr CHKOUT lda #$26 ;load address jsr CHROUT lda #$03 jsr CHROUT lda #decompress sta point+1 .l1 ldy #00 lda (point),y jsr CHROUT inc point bne .c1 inc point+1 .c1 lda point cmp bitdest+1 ;end of file lda point+1 sbc bitdest+2 bcc .l1 .error .close lda #8 jsr CLOSE jmp CLRCHN .txt byte ",P,W" ;--------------------------- ; Copy the decompression subroutine to its dest ;--------------------------- CopyDecompress subroutine ldx #