Dekompresor dla Shrinkler
CODE: xxl, fox (29/03/2021) ENTRY: SOURCE and DESTINATION adress store in unshrinkler_src and unshrinkler_dst unshrinkler_PARITY equ 0 ; wersja no parity (wydajniejsza dla 8-bitowców); 1 - wersja oryginalna unshrinkler_zp equ $xx ; 18 bytes on ZP unshrinkler_data equ $xxxx ; 6/8 pages for decompressor (6 - no parity) mwa #packed_data_addr unshrinkler_zp mwa #unpacked_addr unshrinkler_zp+2 jsr unshrinkler jmp * ; ==================================================== unshrinkler ?src equ unshrinkler_zp ?dst equ unshrinkler_zp+2 ?copy equ unshrinkler_zp+4 ?factor equ unshrinkler_zp+4 ?tabs equ unshrinkler_zp+6 ?number equ unshrinkler_zp+8 ?cp equ unshrinkler_zp+10 ?d2 equ unshrinkler_zp+12 ?d3 equ unshrinkler_zp+14 ?frac equ unshrinkler_zp+16 ?srcBits equ unshrinkler_zp+18 ?probs equ unshrinkler_data ?probsRef equ unshrinkler_data+$200+$200*unshrinkler_PARITY ?probsLength equ ?probsRef ?probsOffset equ ?probsRef+$200 ldx #>[?probsOffset+$100] ldy #1 sty ?d3 dey sty ?d3+1 ift .lo(unshrinkler_data)==0 sty ?tabs els lda #.lo(unshrinkler_data) sta ?tabs eif tya ?initPage stx ?tabs+1 ?initByte sta (?tabs),y iny bne ?initByte sta ?srcBits ; eventually $80 eor #$80 dex cpx #>unshrinkler_data bcs ?initPage tax ; #0 ?literal ldy #1 ?literalBit jsr ?getBit tya rol @ tay bcc ?literalBit sta (?dst,x) ; X=0 inc ?dst bne ?storeSamePage inc ?dst+1 ?storeSamePage jsr ?getKind bcc ?literal lda #>?probsRef jsr ?getBitFrom bcc ?readOffset ?readLength lda #>?probsLength jsr ?getNumber lda #$ff ?offsetL equ *-1 adc ?dst ; C=0 sta ?copy lda #$ff ?offsetH equ *-1 adc ?dst+1 sta ?copy+1 ldx ?number+1 beq ?copyRemainder ?copyPage lda (?copy),y sta (?dst),y iny bne ?copyPage inc ?copy+1 inc ?dst+1 dex bne ?copyPage ?copyRemainder ldx ?number beq ?copyDone ?copyByte lda (?copy),y sta (?dst),y iny dex bne ?copyByte tya clc adc ?dst sta ?dst bcc ?copyDone inc ?dst+1 ?copyDone jsr ?getKind bcc ?literal ?readOffset lda #>?probsOffset jsr ?getNumber lda #3 sbc ?number ; C=0 sta ?offsetL tya ; #0 sbc ?number+1 sta ?offsetH bcc ?readLength rts ; finish ?getNumber sta ?tabs+1 lda #1 sta ?number sty ?number+1 ; #0 ?getNumberCount iny iny jsr ?getBit bcs ?getNumberCount ?getNumberBit dey jsr ?getBit rol ?number rol ?number+1 dey bne ?getNumberBit rts ?getKind ldy #0 ift unshrinkler_PARITY lda ?dst and #1 asl @ adc #>?probs els lda #>?probs eif ?getBitFrom sta ?tabs+1 bne ?getBit ; always ?readBit asl ?d3 rol ?d3+1 asl ?srcBits bne ?gotBit lda (?src,x) ; X=0 inc ?src bne ?readSamePage inc ?src+1 ?readSamePage rol @ ; C=1 sta ?srcBits ?gotBit rol ?d2 rol ?d2+1 ?getBit lda ?d3+1 bpl ?readBit lda (?tabs),y sta ?factor+1 sta ?frac+1 inc ?tabs+1 lda (?tabs),y sta ?factor ldx #4 ?computeFrac lsr ?frac+1 ror @ dex bne ?computeFrac sta ?frac txa ; #0 sta ?cp+1 ldx #16 ?mulLoop lsr ?factor+1 ror ?factor bcc ?mulNext clc adc ?d3 pha lda ?cp+1 adc ?d3+1 sta ?cp+1 pla ?mulNext ror ?cp+1 ror @ dex bne ?mulLoop sta ?cp eor #$ff sec adc ?d2 tax lda ?d2+1 sbc ?cp+1 bcs ?zero ldx ?cp lda ?cp+1 bcc ?setD3 ; always ?zero stx ?d2 sta ?d2+1 lda ?d3 sbc ?cp ; C=1 tax lda ?d3+1 sbc ?cp+1 ?setD3 stx ?d3 sta ?d3+1 php lda (?tabs),y sbc ?frac sta (?tabs),y dec ?tabs+1 lda (?tabs),y sbc ?frac+1 plp bcs ?retZero sbc #$ef ; C=0 sec dta {ldx #} ?retZero clc sta (?tabs),y ldx #0 rts
use: Shrinkler.exe -d -p -9 source destination.shk
Shrinkler 4.6 No parity
zobacz: https://github.com/atari8xxl/unShrinkler
zobacz: https://www.pouet.net/prod.php?which=64851
zobacz: https://github.com/askeksa/Shrinkler