Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; ----------------------------------------------------------------------------------------
- ; The decruncher jsr:s to the getCrunchedByte address when it wants to
- ; read a crunched byte. This subroutine has to preserve x and y register
- ; and must not modify the state of the carry flag.
- ; ----------------------------------------------------------------------------------------
- getCrunchedByte:
- {
- lda DecrunchDataLo
- bne skipHi
- dec DecrunchDataHi
- skipHi:
- dec DecrunchDataLo
- .export DecrunchDataLo = * + 1
- .export DecrunchDataHi = * + 2
- lda $1234
- rts
- }
- ;#define LITERAL_SEQUENCES_NOT_USED
- ; ----------------------------------------------------------------------------------------
- ; this 156 byte table area may be relocated. It may also be clobbered
- ; by other data between decrunches.
- ; ----------------------------------------------------------------------------------------
- DecrunchTable:
- .buf 156
- DecrunchTableBase = DecrunchTable
- DecrunchTableLo = DecrunchTable + 52
- DecrunchTableHi = DecrunchTable + 104
- ; ----------------------------------------------------------------------------------------
- .export exoDecrunch:
- {
- ; -------------------------------------------------------------------
- ; init zeropage, x and y regs. (12 bytes)
- ;
- ldy #0
- ldx #3
- {
- jsr getCrunchedByte
- sta ExoBitBuf - 1,x
- dex
- bne _cont
- }
- ; -------------------------------------------------------------------
- ; calculate tables (50 bytes)
- ; x and y must be #0 when entering
- ;
- nextone:
- inx
- tya
- and #$0f
- beq shortcut
- txa ; this clears reg a
- lsr ; and sets the carry flag
- ldx DecrunchTableBase-1,y
- {
- rol
- rol ExoBitsHi
- dex
- bpl _cont ; c = 0 after this (rol ExoBitsHi)
- }
- adc DecrunchTableLo-1,y
- tax
- lda ExoBitsHi
- adc DecrunchTableHi-1,y
- shortcut:
- sta DecrunchTableHi,y
- txa
- sta DecrunchTableLo,y
- ldx #4
- jsr get_bits ; clears x-reg.
- sta DecrunchTableBase,y
- iny
- cpy #52
- bne nextone
- ldy #0
- beq begin
- ; -------------------------------------------------------------------
- ; get bits (29 bytes)
- ;
- ; args:
- ; x = number of bits to get
- ; returns:
- ; a = #bits_lo
- ; x = #0
- ; c = 0
- ; z = 1
- ; ExoBitsHi = #bits_hi
- ; notes:
- ; y is untouched
- ; -------------------------------------------------------------------
- get_bits:
- lda #$00
- sta ExoBitsHi
- cpx #$01
- bcc bits_done
- bits_next:
- lsr ExoBitBuf
- bne ok
- pha
- literal_get_byte:
- jsr getCrunchedByte
- bcc literal_byte_gotten
- ror
- sta ExoBitBuf
- pla
- ok:
- rol
- rol ExoBitsHi
- dex
- bne bits_next
- bits_done:
- rts
- ; -------------------------------------------------------------------
- ; main copy loop (18(16) bytes)
- ;
- copy_next_hi:
- dex
- dec ExoDestHi
- dec ExoSrcHi
- copy_next:
- dey
- #ifndef LITERAL_SEQUENCES_NOT_USED
- bcc literal_get_byte
- #endif
- lda (ExoSrcLo),y
- literal_byte_gotten:
- sta (ExoDestLo),y
- copy_start:
- tya
- bne copy_next
- begin:
- txa
- bne copy_next_hi
- ; -------------------------------------------------------------------
- ; decruncher entry point, needs calculated tables (21(13) bytes)
- ; x and y must be #0 when entering
- ;
- #ifndef LITERAL_SEQUENCES_NOT_USED
- inx
- jsr get_bits
- tay
- bne literal_start1
- #else
- dey
- #endif
- begin2:
- inx
- jsr bits_next
- lsr
- iny
- bcc begin2
- #ifdef LITERAL_SEQUENCES_NOT_USED
- beq literal_start
- #endif
- cpy #$11
- #ifndef LITERAL_SEQUENCES_NOT_USED
- bcc sequence_start
- beq bits_done
- ; -------------------------------------------------------------------
- ; literal sequence handling (13(2) bytes)
- ;
- ldx #$10
- jsr get_bits
- literal_start1:
- sta <ExoLenLo
- ldx <ExoBitsHi
- ldy #0
- bcc literal_start
- sequence_start:
- #else
- bcs bits_done
- #endif
- ; -------------------------------------------------------------------
- ; calulate length of sequence (zp_len) (11 bytes)
- ;
- ldx DecrunchTableBase - 1,y
- jsr get_bits
- adc DecrunchTableLo - 1,y ; we have now calculated ExoLenLo
- sta ExoLenLo
- ; -------------------------------------------------------------------
- ; now do the hibyte of the sequence length calculation (6 bytes)
- lda ExoBitsHi
- adc DecrunchTableHi - 1,y ; c = 0 after this.
- pha
- ; -------------------------------------------------------------------
- ; here we decide what offset table to use (20 bytes)
- ; x is 0 here
- ;
- bne nots123
- ldy ExoLenLo
- cpy #$04
- bcc size123
- nots123:
- ldy #$03
- size123:
- ldx TableBit - 1,y
- jsr get_bits
- adc TableOffset - 1,y ; c = 0 after this.
- tay ; 1 <= y <= 52 here
- ; -------------------------------------------------------------------
- ; Here we do the dest_lo -= len_lo subtraction to prepare zp_dest
- ; but we do it backwards: a - b == (b - a - 1) ^ ~0 (C-syntax)
- ; (16(16) bytes)
- lda ExoLenLo
- literal_start: ; literal enters here with y = 0, c = 1
- sbc ExoDestLo
- bcc noborrow
- dec ExoDestHi
- noborrow:
- eor #$ff
- sta ExoDestLo
- cpy #$01 ; y < 1 then literal
- #ifndef LITERAL_SEQUENCES_NOT_USED
- bcc pre_copy
- #else
- bcc literal_get_byte
- #endif
- ; -------------------------------------------------------------------
- ; calulate absolute offset (zp_src) (27 bytes)
- ;
- ldx DecrunchTableBase,y
- jsr get_bits;
- adc DecrunchTableLo,y
- bcc skipcarry
- inc ExoBitsHi
- clc
- skipcarry:
- adc ExoDestLo
- sta ExoSrcLo
- lda ExoBitsHi
- adc DecrunchTableHi,y
- adc ExoDestHi
- sta ExoSrcHi
- ; -------------------------------------------------------------------
- ; prepare for copy loop (8(6) bytes)
- ;
- pla
- tax
- #ifndef LITERAL_SEQUENCES_NOT_USED
- sec
- pre_copy:
- ldy <ExoLenLo
- jmp copy_start
- #else
- ldy <ExoLenLo
- bcc copy_start
- #endif
- ; -------------------------------------------------------------------
- ; two small static tables (6(6) bytes)
- ;
- TableBit:
- .byte 2, 4, 4
- TableOffset:
- .byte 48, 32, 16
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement