diff --git a/asm/6809/unlzsa1.s b/asm/6809/unlzsa1.s index 5b55862..7cf611d 100644 --- a/asm/6809/unlzsa1.s +++ b/asm/6809/unlzsa1.s @@ -1,4 +1,4 @@ -; unlzsa1.s - 6809 decompression routine for raw LZSA1 - 111 bytes +; unlzsa1.s - 6809 decompression routine for raw LZSA1 - 110 bytes ; compress with lzsa -r ; ; in: x = start of compressed data @@ -25,8 +25,7 @@ decompress_lzsa1 equ lz1token -lz1bigof ldb ,x+ ; O set: load long 16 bit (negative, signed) offset - lda ,x+ ; (little endian) +lz1bigof lda ,x+ ; O set: load MSB 16-bit (negative, signed) offest lz1gotof leau d,y ; put backreference start address in U (dst+offset) puls b ; restore token @@ -65,7 +64,6 @@ lz1cpymt lda ,u+ ; copy matched byte lz1token ldb ,x+ ; load next token into B: O|LLL|MMMM pshs b ; save it - clra ; clear A (high part of literals count) andb #$70 ; isolate LLL (embedded literals count) in B beq lz1nolt ; skip if no literals cmpb #$70 ; LITERALS_RUN_LEN? @@ -73,7 +71,7 @@ lz1token ldb ,x+ ; load next token into B: O|LLL|MMMM ldb ,x+ ; load extra literals count byte addb #$07 ; add LITERALS_RUN_LEN - bcc lz1gotlt ; if no overflow, we got the complete count, copy + bcc lz1gotla ; if no overflow, we got the complete count, copy bne lz1midlt ldb ,x+ ; load low 8 bits of little-endian literals count @@ -88,6 +86,7 @@ lz1declt lsrb ; shift literals count into place lsrb lsrb lsrb +lz1gotla clra ; clear A (high part of literals count) lz1gotlt tfr x,u tfr d,x ; transfer 16-bit count into X @@ -97,9 +96,9 @@ lz1cpylt lda ,u+ ; copy literal byte bne lz1cpylt ; loop until all literal bytes are copied tfr u,x -lz1nolt ldb ,s ; get token again, don't pop it from the stack +lz1nolt ldb ,x+ ; load either 8-bit or LSB 16-bit offset (negative, signed) + lda ,s ; get token again, don't pop it from the stack bmi lz1bigof ; test O bit (small or large offset) - ldb ,x+ ; O clear: load 8 bit (negative, signed) offset lda #$ff ; set high 8 bits bra lz1gotof diff --git a/asm/6809/unlzsa1b.s b/asm/6809/unlzsa1b.s index eff2fba..af53284 100644 --- a/asm/6809/unlzsa1b.s +++ b/asm/6809/unlzsa1b.s @@ -1,4 +1,4 @@ -; unlzsa1b.s - 6809 backward decompression routine for raw LZSA1 - 112 bytes +; unlzsa1b.s - 6809 backward decompression routine for raw LZSA1 - 113 bytes ; compress with lzsa -r -b ; ; in: x = last byte of compressed data @@ -26,11 +26,47 @@ decompress_lzsa1 leax 1,x leay 1,y + bra lz1token + +lz1bigof ldd ,--x ; O set: load long 16 bit (negative, signed) offset +lz1gotof nega ; reverse sign of offset in D + negb + sbca #0 + leau d,y ; put backreference start address in U (dst+offset) + + puls b ; restore token + + clra ; clear A (high part of match length) + andb #$0F ; isolate MMMM (embedded match length) + addb #$03 ; add MIN_MATCH_SIZE + cmpb #$12 ; MATCH_RUN_LEN? + bne lz1gotln ; no, we have the full match length, go copy + + addb ,-x ; add extra match length byte + MIN_MATCH_SIZE + MATCH_RUN_LEN + bcc lz1gotln ; if no overflow, we have the full length + bne lz1midln + + ldd ,--x ; load 16-bit len in D (low part in B, high in A) + bne lz1gotln ; check if we hit EOD (16-bit length = 0) + + rts ; done, bail + +lz1midln tfr b,a ; copy high part of len into A + ldb ,-x ; grab low 8 bits of len in B + +lz1gotln pshs x ; save source compressed data pointer + tfr d,x ; copy match length to X + +lz1cpymt lda ,-u ; copy matched byte + sta ,-y + leax -1,x ; decrement X + bne lz1cpymt ; loop until all matched bytes are copied + + puls x ; restore source compressed data pointer lz1token ldb ,-x ; load next token into B: O|LLL|MMMM pshs b ; save it - clra ; clear A (high part of literals count) andb #$70 ; isolate LLL (embedded literals count) in B beq lz1nolt ; skip if no literals cmpb #$70 ; LITERALS_RUN_LEN? @@ -38,7 +74,7 @@ lz1token ldb ,-x ; load next token into B: O|LLL|MMMM ldb ,-x ; load extra literals count byte addb #$07 ; add LITERALS_RUN_LEN - bcc lz1gotlt ; if no overflow, we got the complete count, copy + bcc lz1gotla ; if no overflow, we got the complete count, copy bne lz1midlt ldd ,--x ; load 16 bit count in D (low part in B, high in A) @@ -52,11 +88,12 @@ lz1declt lsrb ; shift literals count into place lsrb lsrb lsrb - + +lz1gotla clra ; clear A (high part of literals count) lz1gotlt tfr x,u tfr d,x ; transfer 16-bit count into X lz1cpylt lda ,-u ; copy literal byte - sta ,-y + sta ,-y leax -1,x ; decrement X and update Z flag bne lz1cpylt ; loop until all literal bytes are copied tfr u,x @@ -67,40 +104,3 @@ lz1nolt ldb ,s ; get token again, don't pop it from the stack ldb ,-x ; O clear: load 8 bit (negative, signed) offset lda #$ff ; set high 8 bits bra lz1gotof - -lz1bigof ldd ,--x ; O set: load long 16 bit (negative, signed) offset -lz1gotof nega ; reverse sign of offset in D - negb - sbca #0 - leau d,y ; put backreference start address in U (dst+offset) - - puls b ; restore token - - clra ; clear A (high part of match length) - andb #$0F ; isolate MMMM (embedded match length) - addb #$03 ; add MIN_MATCH_SIZE - cmpb #$12 ; MATCH_RUN_LEN? - bne lz1gotln ; no, we have the full match length, go copy - - addb ,-x ; add extra match length byte + MIN_MATCH_SIZE + MATCH_RUN_LEN - bcc lz1gotln ; if no overflow, we have the full length - bne lz1midln - - ldd ,--x ; load 16-bit len in D (low part in B, high in A) - bne lz1gotln ; check if we hit EOD (16-bit length = 0) - - rts ; done, bail - -lz1midln tfr b,a ; copy high part of len into A - ldb ,-x ; grab low 8 bits of len in B - -lz1gotln pshs x ; save source compressed data pointer - tfr d,x ; copy match length to X - -lz1cpymt lda ,-u ; copy matched byte - sta ,-y - leax -1,x ; decrement X - bne lz1cpymt ; loop until all matched bytes are copied - - puls x ; restore source compressed data pointer - bra lz1token ; go decode next token diff --git a/asm/6809/unlzsa2.s b/asm/6809/unlzsa2.s index e21d0cd..221abe6 100644 --- a/asm/6809/unlzsa2.s +++ b/asm/6809/unlzsa2.s @@ -1,4 +1,4 @@ -; unlzsa2.s - 6809 decompression routine for raw LZSA2 - 183 bytes +; unlzsa2.s - 6809 decompression routine for raw LZSA2 - 172 bytes ; compress with lzsa -f2 -r ; ; in: x = start of compressed data @@ -29,8 +29,7 @@ decompress_lzsa2 lz2token ldb ,x+ ; load next token into B: XYZ|LL|MMM pshs b ; save it - clra ; clear A (high part of literals count) - andb #$18 ; isolate LLL (embedded literals count) in B + andb #$18 ; isolate LL (embedded literals count) in B beq lz2nolt ; skip if no literals cmpb #$18 ; LITERALS_RUN_LEN_V2? bne lz2declt ; if not, we have the complete count, go unshift @@ -38,10 +37,10 @@ lz2token ldb ,x+ ; load next token into B: XYZ|LL|MMM bsr lz2nibl ; get extra literals length nibble in B addb #$03 ; add LITERALS_RUN_LEN_V2 cmpb #$12 ; LITERALS_RUN_LEN_V2 + 15 ? - bne lz2gotlt ; if not, we have the full literals count, go copy + bne lz2gotla ; if not, we have the full literals count, go copy addb ,x+ ; add extra literals count byte + LITERALS_RUN_LEN + 15 - bcc lz2gotlt ; if no overflow, we got the complete count, copy + bcc lz2gotla ; if no overflow, we got the complete count, copy ldb ,x+ ; load low 8 bits of little-endian literals count lda ,x+ ; load high 8 bits of literal count @@ -50,11 +49,12 @@ lz2token ldb ,x+ ; load next token into B: XYZ|LL|MMM lz2declt lsrb ; shift literals count into place lsrb lsrb - + +lz2gotla clra ; clear A (high part of literals count) lz2gotlt tfr x,u tfr d,x ; transfer 16-bit count into X lz2cpylt lda ,u+ ; copy literal byte - sta ,y+ + sta ,y+ leax -1,x ; decrement X and update Z flag bne lz2cpylt ; loop until all literal bytes are copied tfr u,x @@ -65,23 +65,18 @@ lz2nolt ldb ,s ; get token again, don't pop it from the stack bcs lz2replg ; if token's X bit is set, rep or large offset lslb ; push token's Y flag bit into carry + sex ; push token's Z flag bit into reg A (carry flag is not effected) bcs lz2offs9 ; if token's Y bit is set, 9 bits offset - lslb ; push token's Z flag bit into carry - tfr cc,a ; preserve cpu flags (to preserve carry) bsr lz2nibl ; get offset nibble in B - tfr a,cc ; restore cpu flags + lsla ; retrieve token's Z flag bit and push into carry rolb ; shift Z flag from carry into bit 0 of B eorb #$e1 ; set bits 5-7 of offset, reverse bit 0 - lda #$ff ; set bits 8-15 of offset + sex ; set bits 8-15 of offset to $FF bra lz2gotof -lz2offs9 clra ; clear A (to prepare for high 8 bits of offset) - lslb ; push token's Z flag bit into carry - rola ; shift Z flag from carry into bit 0 of A - coma ; set bits 9-15 of offset, reverse bit 8 - +lz2offs9 deca ; set bits 9-15 of offset, reverse bit 8 ldb ,x+ ; load low 8 bits of (negative, signed) offset bra lz2gotof @@ -106,30 +101,24 @@ lz2done rts lz2replg lslb ; push token's Y flag bit into carry bcs lz2rep16 ; if token's Y bit is set, rep or 16 bit offset - lslb ; push token's Z flag bit into carry - tfr cc,a ; preserve cpu flags (to preserve carry) + sex ; push token's Z flag bit into reg A bsr lz2nibl ; get offset nibble in B - tfr a,cc ; restore cpu flags - + lsla ; push token's Z flag bit into carry rolb ; shift Z flag from carry into bit 0 of B eorb #$e1 ; set bits 13-15 of offset, reverse bit 8 tfr b,a ; copy bits 8-15 of offset into A suba #$02 ; substract 512 from offset - ldb ,x+ ; load low 8 bits of (negative, signed) offset bra lz2gotof lz2rep16 bmi lz2repof ; if token's Z flag bit is set, rep match - ldd ,x++ ; load high then low 8 bits of offset -lz2gotof std ; ; in: x = last byte of compressed data @@ -31,7 +31,6 @@ decompress_lzsa2 lz2token ldb ,-x ; load next token into B: XYZ|LL|MMM pshs b ; save it - clra ; clear A (high part of literals count) andb #$18 ; isolate LLL (embedded literals count) in B beq lz2nolt ; skip if no literals cmpb #$18 ; LITERALS_RUN_LEN_V2? @@ -40,10 +39,10 @@ lz2token ldb ,-x ; load next token into B: XYZ|LL|MMM bsr lz2nibl ; get extra literals length nibble in B addb #$03 ; add LITERALS_RUN_LEN_V2 cmpb #$12 ; LITERALS_RUN_LEN_V2 + 15 ? - bne lz2gotlt ; if not, we have the full literals count, go copy + bne lz2gotla ; if not, we have the full literals count, go copy addb ,-x ; add extra literals count byte + LITERALS_RUN_LEN + 15 - bcc lz2gotlt ; if no overflow, we got the complete count, copy + bcc lz2gotla ; if no overflow, we got the complete count, copy ldd ,--x ; load 16 bit count in D (low part in B, high in A) bra lz2gotlt ; we now have the complete count, go copy @@ -51,11 +50,12 @@ lz2token ldb ,-x ; load next token into B: XYZ|LL|MMM lz2declt lsrb ; shift literals count into place lsrb lsrb - +lz2gotla clra ; clear A (high part of literals count) + lz2gotlt tfr x,u tfr d,x ; transfer 16-bit count into X lz2cpylt lda ,-u ; copy literal byte - sta ,-y + sta ,-y leax -1,x ; decrement X and update Z flag bne lz2cpylt ; loop until all literal bytes are copied tfr u,x @@ -66,22 +66,18 @@ lz2nolt ldb ,s ; get token again, don't pop it from the stack bcs lz2replg ; if token's X bit is set, rep or large offset lslb ; push token's Y flag bit into carry + sex ; push token's Z flag bit into reg A (carry flag is not effected) bcs lz2offs9 ; if token's Y bit is set, 9 bits offset - lslb ; push token's Z flag bit into carry - tfr cc,a ; preserve cpu flags (to preserve carry) bsr lz2nibl ; get offset nibble in B - tfr a,cc ; restore cpu flags + lsla ; retrieve token's Z flag bit and push into carry rolb ; shift Z flag from carry into bit 0 of B eorb #$e1 ; set bits 5-7 of offset, reverse bit 0 - lda #$ff ; set bits 8-15 of offset + sex ; set bits 8-15 of offset to $FF bra lz2gotof -lz2offs9 clra ; clear A (to prepare for high 8 bits of offset) - lslb ; push token's Z flag bit into carry - rola ; shift Z flag from carry into bit 0 of A - coma ; set bits 9-15 of offset, reverse bit 8 +lz2offs9 deca ; set bits 9-15 of offset, reverse bit 8 bra lz2lowof lz2nibct fcb $00 ; nibble ready flag @@ -105,10 +101,9 @@ lz2done rts lz2replg lslb ; push token's Y flag bit into carry bcs lz2rep16 ; if token's Y bit is set, rep or 16 bit offset - lslb ; push token's Z flag bit into carry - tfr cc,a ; preserve cpu flags (to preserve carry) + sex ; push token's Z flag bit into reg A bsr lz2nibl ; get offset nibble in B - tfr a,cc ; restore cpu flags + lsla ; retrieve token's Z flag bit and push into carry rolb ; shift Z flag from carry into bit 0 of B eorb #$e1 ; set bits 13-15 of offset, reverse bit 8 @@ -117,20 +112,19 @@ lz2replg lslb ; push token's Y flag bit into carry bra lz2lowof lz2rep16 bmi lz2repof ; if token's Z flag bit is set, rep match - + lda ,-x ; load high 8 bits of (negative, signed) offset lz2lowof ldb ,-x ; load low 8 bits of offset lz2gotof nega ; reverse sign of offset in D negb sbca #0 - std