Created
          February 19, 2021 23:45 
        
      - 
      
- 
        Save JettMonstersGoBoom/b1a15a5b7392599e336a211bbb16240c to your computer and use it in GitHub Desktop. 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | // https://github.com/emmanuel-marty/apultra | |
| // ported to Kick asm | |
| // can depack from other banks now | |
| // can't cross over 64kb | |
| .segment ZP | |
| apl_bitbuf: .byte 0 | |
| apl_offset: .dword 0 | |
| apl_winptr: .dword 0 | |
| apl_srcptr: .dword 0 | |
| apl_dstptr: .dword 0 | |
| .label apl_length = apl_winptr | |
| .macro APL_INC_PAGE() { | |
| inc <apl_srcptr + 1 | |
| } | |
| .macro APL_GET_SRC() { | |
| lda ((apl_srcptr)),z | |
| inc <apl_srcptr + 0 | |
| bne skip | |
| APL_INC_PAGE() | |
| skip: | |
| } | |
| .macro APUltraUnpack(source,dest) { | |
| lda #<source | |
| ldy #>source | |
| sta apl_srcptr | |
| sty apl_srcptr+1 | |
| lda #<dest | |
| ldy #>dest | |
| sta apl_dstptr | |
| sty apl_dstptr+1 | |
| jsr APUltraDecompressRoutine | |
| } | |
| .segment CODE | |
| APUltraDecompressRoutine: | |
| { | |
| ldz #0 // Initialize source index_ | |
| stz apl_winptr+2 | |
| stz apl_winptr+3 | |
| stz apl_offset+2 | |
| stz apl_offset+3 | |
| lda #$80 // Initialize an empty | |
| sta <apl_bitbuf // bit-buffer_ | |
| // | |
| // 0 bbbbbbbb - One byte from compressed data, i_e_ a "literal"_ | |
| // | |
| _literal: APL_GET_SRC() | |
| _write_byte: | |
| ldx #0 // LWM=0_ | |
| sta ((apl_dstptr)),z // Write the byte directly to | |
| inc <apl_dstptr + 0 // the output_ | |
| bne _next_tag | |
| inc <apl_dstptr + 1 | |
| _next_tag: | |
| asl <apl_bitbuf // 0 bbbbbbbb | |
| bne _skip0 | |
| jsr _load_bit | |
| _skip0: | |
| bcc _literal | |
| _skip1: | |
| asl <apl_bitbuf // 1 0 <offset> <length> | |
| bne _skip2 | |
| jsr _load_bit | |
| _skip2: | |
| bcc _copy_large | |
| asl <apl_bitbuf // 1 1 0 dddddddn | |
| bne _skip3 | |
| jsr _load_bit | |
| _skip3: | |
| bcc _copy_normal | |
| // 1 1 1 dddd - Copy 1 byte within 15 bytes (or zero)_ | |
| _copy_short: | |
| lda #$10 | |
| _nibble_loop: | |
| asl <apl_bitbuf | |
| bne _skip4 | |
| pha | |
| jsr _load_bit | |
| pla | |
| _skip4: | |
| rol | |
| bcc _nibble_loop | |
| beq _write_byte // Offset=0 means write zero_ | |
| eor #$FF // Read the byte directly from | |
| taz // the destination window_ | |
| inz | |
| dec <apl_dstptr + 1 | |
| lda ((apl_dstptr)),z | |
| inc <apl_dstptr + 1 | |
| ldz #0 | |
| beq _write_byte | |
| // | |
| // 1 1 0 dddddddn - Copy 2 or 3 within 128 bytes_ | |
| // | |
| _copy_normal: | |
| APL_GET_SRC() // 1 1 0 dddddddn | |
| lsr | |
| beq _finished // Offset 0 == EOF_ | |
| sta <apl_offset + 0 // Preserve offset_ | |
| stz <apl_offset + 1 | |
| tza // Y == 0_ | |
| tax // Bits 8__15 of length_ | |
| adc #2 // Bits 0___7 of length_ | |
| bne _do_match // NZ from previous ADC_ | |
| // | |
| // Subroutines for byte & bit handling_ | |
| // | |
| _get_gamma: | |
| lda #1 // Get a gamma-coded value_ | |
| _gamma_loop: | |
| asl <apl_bitbuf | |
| bne _skip5 | |
| pha | |
| jsr _load_bit | |
| pla | |
| _skip5: | |
| rol | |
| rol <apl_length + 1 | |
| asl <apl_bitbuf | |
| bne _skip6 | |
| pha | |
| jsr _load_bit | |
| pla | |
| _skip6: | |
| bcs _gamma_loop | |
| _finished: | |
| rts // All decompressed! | |
| // | |
| // 1 0 <offset> <length> - gamma-coded LZSS pair_ | |
| // | |
| _copy_large: | |
| jsr _get_gamma // Bits 8__15 of offset (min 2)_ | |
| stz <apl_length + 1 // Clear hi-byte of length_ | |
| cpx #1 // CC if LWM==0, CS if LWM==1_ | |
| sbc #2 // -3 if LWM==0, -2 if LWM==1_ | |
| bcs _normal_pair // CC if LWM==0 && offset==2_ | |
| jsr _get_gamma // Get length (A=lo-byte & CC)_ | |
| ldx <apl_length + 1 | |
| bcc _do_match // Use previous Offset_ | |
| _normal_pair: | |
| sta <apl_offset + 1 // Save bits 8__15 of offset_ | |
| APL_GET_SRC() | |
| sta <apl_offset + 0 // Save bits 0___7 of offset_ | |
| jsr _get_gamma // Get length (A=lo-byte & CC)_ | |
| ldx <apl_length + 1 | |
| ldz <apl_offset + 1 // If offset < 256_ | |
| beq _lt256 | |
| cpz #$7D // If offset >= 32000, length += 2_ | |
| bcs _match_plus2 | |
| cpz #$05 // If offset >= 1280, length += 1_ | |
| bcs _match_plus1 | |
| bcc _do_match | |
| _lt256: | |
| ldz <apl_offset + 0 // If offset < 128, length += 2_ | |
| bmi _do_match | |
| sec // aPLib gamma returns with CC_ | |
| _match_plus2: | |
| adc #1 // CS, so ADC #2_ | |
| bcs _match_plus256 | |
| _match_plus1: | |
| adc #0 // CS, so ADC #1, or CC if fall | |
| bcc _do_match // through from _match_plus2_ | |
| _match_plus256: | |
| inx | |
| _do_match: | |
| eor #$FF // Negate the lo-byte of length | |
| taz // and check for zero_ | |
| inz | |
| beq _calc_addr | |
| eor #$FF | |
| inx // Increment # of pages to copy_ | |
| clc // Calc destination for partial | |
| adc <apl_dstptr + 0 // page_ | |
| sta <apl_dstptr + 0 | |
| lda <apl_dstptr + 1 | |
| bcs _calc_addr | |
| dec <apl_dstptr + 1 | |
| _calc_addr: | |
| sec // Calc address of match_ | |
| lda <apl_dstptr + 0 | |
| sbc <apl_offset + 0 | |
| sta <apl_winptr + 0 | |
| lda <apl_dstptr + 1 | |
| sbc <apl_offset + 1 | |
| sta <apl_winptr + 1 | |
| _copy_page: | |
| lda ((apl_winptr)),z | |
| sta ((apl_dstptr)),z | |
| inz | |
| bne _copy_page | |
| inc <apl_winptr + 1 | |
| inc <apl_dstptr + 1 | |
| dex // Any full pages left to copy? | |
| bne _copy_page | |
| inx // LWM=1_ | |
| jmp _next_tag | |
| // | |
| // Subroutines for byte & bit handling_ | |
| // | |
| _load_bit: | |
| APL_GET_SRC() // Reload an empty bit-buffer | |
| rol // from the compressed source_ | |
| sta <apl_bitbuf | |
| rts | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment