mirror of
https://github.com/deater/dos33fsprogs.git
synced 2024-06-26 00:29:29 +00:00
compression_test: finally got exomizer working
This commit is contained in:
parent
94bc946a4c
commit
bff16e6de7
|
@ -1,5 +1,14 @@
|
||||||
|
; this one is from passport
|
||||||
|
|
||||||
|
; This source code is altered and is not the original version found on
|
||||||
|
; the Exomizer homepage.
|
||||||
|
; It contains modifications made by qkumba to depack a packed file
|
||||||
|
; optionally crunched forward, and additional modifications by 4am
|
||||||
|
; for an optional progress UI.
|
||||||
;
|
;
|
||||||
; Copyright (c) 2002 - 2020 Magnus Lind.
|
; Original copyright statement follows:
|
||||||
|
;
|
||||||
|
; Copyright (c) 2002 - 2018 Magnus Lind.
|
||||||
;
|
;
|
||||||
; This software is provided 'as-is', without any express or implied warranty.
|
; This software is provided 'as-is', without any express or implied warranty.
|
||||||
; In no event will the authors be held liable for any damages arising from
|
; In no event will the authors be held liable for any damages arising from
|
||||||
|
@ -23,64 +32,6 @@
|
||||||
; used to endorse or promote products derived from this software without
|
; used to endorse or promote products derived from this software without
|
||||||
; specific prior written permission.
|
; specific prior written permission.
|
||||||
;
|
;
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; Known quirks:
|
|
||||||
; Can't handle a sequence reference that ends at $ffff. It is left in
|
|
||||||
; since it is a corner case and fixing it impacts negatively on
|
|
||||||
; performance or backwards compatibility.
|
|
||||||
; A simple way to work around this is to not decrunch to address $ffff.
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; Controls if the shared get_bits routines should be inlined or not.
|
|
||||||
;INLINE_GET_BITS=1
|
|
||||||
.IFNDEF INLINE_GET_BITS
|
|
||||||
INLINE_GET_BITS = 0
|
|
||||||
.ENDIF
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; if literal sequences is not used (the data was crunched with the -c
|
|
||||||
; flag) then the following line can be uncommented for shorter and.
|
|
||||||
; slightly faster code.
|
|
||||||
;LITERAL_SEQUENCES_NOT_USED = 1
|
|
||||||
.IFNDEF LITERAL_SEQUENCES_NOT_USED
|
|
||||||
LITERAL_SEQUENCES_NOT_USED = 0
|
|
||||||
.ENDIF
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; if the sequence length is limited to 256 (the data was crunched with
|
|
||||||
; the -M256 flag) then the following line can be uncommented for
|
|
||||||
; shorter and slightly faster code.
|
|
||||||
;MAX_SEQUENCE_LENGTH_256 = 1
|
|
||||||
.IFNDEF MAX_SEQUENCE_LENGTH_256
|
|
||||||
MAX_SEQUENCE_LENGTH_256 = 0
|
|
||||||
.ENDIF
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; if the sequence length 3 has its own offset table (the data was
|
|
||||||
; crunched with the -P+16 flag) then the following
|
|
||||||
; line must be uncommented.
|
|
||||||
;EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE = 1
|
|
||||||
.IFNDEF EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE
|
|
||||||
EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE = 0
|
|
||||||
.ENDIF
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; if sequence offsets are not reused (the data was crunched with the
|
|
||||||
; -P-32 flag) then the following line must be uncommented. Uncommenting the
|
|
||||||
; line will also result in shorter and slightly faster code.
|
|
||||||
;DONT_REUSE_OFFSET = 1
|
|
||||||
.IFNDEF DONT_REUSE_OFFSET
|
|
||||||
DONT_REUSE_OFFSET = 0
|
|
||||||
.ENDIF
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; if decrunching forwards then the following line must be uncommented.
|
|
||||||
;DECRUNCH_FORWARDS = 1
|
|
||||||
.IFNDEF DECRUNCH_FORWARDS
|
|
||||||
DECRUNCH_FORWARDS = 0
|
|
||||||
.ENDIF
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; if split encoding is used (the data is crunched with the -E flag)
|
|
||||||
; then the following line must be uncommented.
|
|
||||||
;ENABLE_SPLIT_ENCODING = 1
|
|
||||||
.IFNDEF ENABLE_SPLIT_ENCODING
|
|
||||||
ENABLE_SPLIT_ENCODING = 0
|
|
||||||
.ENDIF
|
|
||||||
|
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; The decruncher jsr:s to the get_crunched_byte address when it wants to
|
; The decruncher jsr:s to the get_crunched_byte address when it wants to
|
||||||
; read a crunched byte into A. This subroutine has to preserve X and Y
|
; read a crunched byte into A. This subroutine has to preserve X and Y
|
||||||
|
@ -88,65 +39,73 @@ ENABLE_SPLIT_ENCODING = 0
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
;.import get_crunched_byte
|
;.import get_crunched_byte
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; This function is the heart of the decruncher. (for non split crunched files)
|
; this function is the heart of the decruncher.
|
||||||
; It initializes the decruncher zeropage locations and precalculates the
|
; It initializes the decruncher zeropage locations and precalculates the
|
||||||
; decrunch tables and decrunches the data
|
; decrunch tables and decrunches the data
|
||||||
; This function will not change the interrupt status bit and it will not
|
; This function will not change the interrupt status bit and it will not
|
||||||
; modify the memory configuration.
|
; modify the memory configuration.
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
.export decrunch
|
;.export decrunch
|
||||||
.IF ENABLE_SPLIT_ENCODING <> 0
|
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; To decrunch files crunched with the split feature (-E) you can't use the
|
; Controls if the shared get_bits routines should be inlined or not.
|
||||||
; decrunch function. Instead you call the split_decrunch function. But you
|
;INLINE_GET_BITS=1
|
||||||
; can only do this if the decrunch table contains the encoding used by the
|
|
||||||
; file you are decrunching. To generate the correct content for the decrunch
|
|
||||||
; table call set the get_crunched_byte function to point to the encoding data
|
|
||||||
; and then call the split_gentable function.
|
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
.export split_gentable
|
; if literal sequences is not used (the data was crunched with the -c
|
||||||
.export split_decrunch
|
; flag) then the following line can be uncommented for shorter and.
|
||||||
.ENDIF
|
; slightly faster code.
|
||||||
|
;LITERAL_SEQUENCES_NOT_USED = 1
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; if the sequence length is limited to 256 (the data was crunched with
|
||||||
|
; the -M256 flag) then the following line can be uncommented for
|
||||||
|
; shorter and slightly faster code.
|
||||||
|
;MAX_SEQUENCE_LENGTH_256 = 1
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; if the sequence length 3 has its own offset table then the following
|
||||||
|
; line can be uncommented for in some situations slightly better
|
||||||
|
; compression at the cost of a larger decrunch table.
|
||||||
|
EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE = 1
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; optional progress UI
|
||||||
|
.ifndef SHOW_PROGRESS_DURING_DECRUNCH
|
||||||
|
SHOW_PROGRESS_DURING_DECRUNCH = 0
|
||||||
|
.endif
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; zero page addresses used
|
; zero page addresses used
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
zp_len_lo = $9e
|
zp_len_lo = $a7
|
||||||
zp_len_hi = $9f
|
zp_len_hi = $a8
|
||||||
|
|
||||||
zp_src_lo = $ae
|
zp_src_lo = $ae
|
||||||
zp_src_hi = zp_src_lo + 1
|
zp_src_hi = zp_src_lo + 1
|
||||||
|
|
||||||
zp_bits_hi = $a7
|
zp_bits_hi = $fc
|
||||||
.IF DONT_REUSE_OFFSET = 0
|
|
||||||
zp_ro_state = $a8
|
|
||||||
.ENDIF
|
|
||||||
|
|
||||||
zp_bitbuf = $fd
|
zp_bitbuf = $fd
|
||||||
zp_dest_lo = zp_bitbuf + 1 ; dest addr lo
|
zp_dest_lo = zp_bitbuf + 1 ; dest addr lo
|
||||||
zp_dest_hi = zp_bitbuf + 2 ; dest addr hi
|
zp_dest_hi = zp_bitbuf + 2 ; dest addr hi
|
||||||
|
|
||||||
.IF EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE <> 0
|
.ifdef EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE
|
||||||
encoded_entries = 68
|
encoded_entries = 68
|
||||||
.ELSE
|
.else
|
||||||
encoded_entries = 52
|
encoded_entries = 52
|
||||||
.ENDIF
|
.endif
|
||||||
|
|
||||||
tabl_bi = decrunch_table
|
tabl_bi = decrunch_table
|
||||||
tabl_lo = decrunch_table + encoded_entries
|
tabl_lo = decrunch_table + encoded_entries
|
||||||
tabl_hi = decrunch_table + encoded_entries * 2
|
tabl_hi = decrunch_table + encoded_entries * 2
|
||||||
|
|
||||||
;; refill bits is always inlined
|
;; refill bits is always inlined
|
||||||
.MACRO mac_refill_bits
|
.macro mac_refill_bits
|
||||||
pha
|
pha
|
||||||
jsr get_crunched_byte
|
jsr get_crunched_byte
|
||||||
rol
|
rol
|
||||||
sta zp_bitbuf
|
sta zp_bitbuf
|
||||||
pla
|
pla
|
||||||
.ENDMACRO
|
.endmacro
|
||||||
|
|
||||||
.MACRO mac_get_bits
|
.ifdef INLINE_GET_BITS
|
||||||
.IF INLINE_GET_BITS <> 0
|
.macro mac_get_bits
|
||||||
.SCOPE
|
|
||||||
adc #$80 ; needs c=0, affects v
|
adc #$80 ; needs c=0, affects v
|
||||||
asl
|
asl
|
||||||
bpl gb_skip
|
bpl gb_skip
|
||||||
|
@ -164,26 +123,11 @@ gb_get_hi:
|
||||||
sta zp_bits_hi
|
sta zp_bits_hi
|
||||||
jsr get_crunched_byte
|
jsr get_crunched_byte
|
||||||
skip:
|
skip:
|
||||||
.ENDSCOPE
|
.endmacro
|
||||||
.ELSE
|
.else
|
||||||
|
.macro mac_get_bits
|
||||||
jsr get_bits
|
jsr get_bits
|
||||||
.ENDIF
|
.endmacro
|
||||||
.ENDMACRO
|
|
||||||
|
|
||||||
.MACRO mac_init_zp
|
|
||||||
.SCOPE
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; init zeropage and x reg. (8 bytes)
|
|
||||||
;
|
|
||||||
init_zp:
|
|
||||||
jsr get_crunched_byte
|
|
||||||
sta zp_bitbuf - 1,x
|
|
||||||
dex
|
|
||||||
bne init_zp
|
|
||||||
.ENDSCOPE
|
|
||||||
.ENDMACRO
|
|
||||||
|
|
||||||
.IF INLINE_GET_BITS = 0
|
|
||||||
get_bits:
|
get_bits:
|
||||||
adc #$80 ; needs c=0, affects v
|
adc #$80 ; needs c=0, affects v
|
||||||
asl
|
asl
|
||||||
|
@ -202,7 +146,7 @@ gb_get_hi:
|
||||||
sec
|
sec
|
||||||
sta zp_bits_hi
|
sta zp_bits_hi
|
||||||
jmp get_crunched_byte
|
jmp get_crunched_byte
|
||||||
.ENDIF
|
.endif
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; no code below this comment has to be modified in order to generate
|
; no code below this comment has to be modified in order to generate
|
||||||
; a working decruncher of this source file.
|
; a working decruncher of this source file.
|
||||||
|
@ -214,25 +158,42 @@ gb_get_hi:
|
||||||
; jsr this label to decrunch, it will in turn init the tables and
|
; jsr this label to decrunch, it will in turn init the tables and
|
||||||
; call the decruncher
|
; call the decruncher
|
||||||
; no constraints on register content, however the
|
; no constraints on register content, however the
|
||||||
; decimal flag has to be cleared (it almost always is, otherwise do a cld)
|
; decimal flag has to be #0 (it almost always is, otherwise do a cld)
|
||||||
decrunch:
|
decrunch:
|
||||||
.IF ENABLE_SPLIT_ENCODING <> 0
|
|
||||||
ldx #3
|
.if SHOW_PROGRESS_DURING_DECRUNCH = 1
|
||||||
jsr internal_gentable
|
lda $FBB3
|
||||||
jmp normal_decrunch
|
cmp #$EA
|
||||||
split_gentable:
|
bne +
|
||||||
ldx #1
|
lda #$A1 ; use ! instead of | for initial spinner animation
|
||||||
internal_gentable:
|
sta progress_char+1
|
||||||
jsr split_init_zp
|
sta progress_char+5
|
||||||
.ELSE
|
+
|
||||||
ldx #3
|
|
||||||
mac_init_zp
|
|
||||||
.ENDIF
|
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; calculate tables (64 bytes) + get_bits macro
|
; show initial on-screen progress UI
|
||||||
; x must be #0 when entering
|
;
|
||||||
|
ldy #7
|
||||||
|
init_progress_loop:
|
||||||
|
lda progress_char,y
|
||||||
|
jsr show_one_progress_char
|
||||||
|
dey
|
||||||
|
bpl init_progress_loop
|
||||||
|
done_init_progress_loop:
|
||||||
|
.endif
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; init zeropage, x and y regs. (12 bytes)
|
||||||
;
|
;
|
||||||
ldy #0
|
ldy #0
|
||||||
|
ldx #3
|
||||||
|
init_zp:
|
||||||
|
jsr get_crunched_byte
|
||||||
|
sta zp_bitbuf - 1,x
|
||||||
|
dex
|
||||||
|
bne init_zp
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; calculate tables (62 bytes) + get_bits macro
|
||||||
|
; x and y must be #0 when entering
|
||||||
|
;
|
||||||
clc
|
clc
|
||||||
table_gen:
|
table_gen:
|
||||||
tax
|
tax
|
||||||
|
@ -271,7 +232,7 @@ rolled:
|
||||||
bmi no_fixup_lohi
|
bmi no_fixup_lohi
|
||||||
lda zp_len_hi
|
lda zp_len_hi
|
||||||
stx zp_len_hi
|
stx zp_len_hi
|
||||||
.BYTE $24
|
.byte $24
|
||||||
no_fixup_lohi:
|
no_fixup_lohi:
|
||||||
txa
|
txa
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
|
@ -279,57 +240,60 @@ no_fixup_lohi:
|
||||||
cpy #encoded_entries
|
cpy #encoded_entries
|
||||||
bne table_gen
|
bne table_gen
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
.IF ENABLE_SPLIT_ENCODING <> 0
|
|
||||||
rts
|
|
||||||
split_decrunch:
|
|
||||||
ldx #3
|
|
||||||
jsr split_init_zp
|
|
||||||
; X reg must be 0 here
|
|
||||||
sec
|
|
||||||
normal_decrunch:
|
|
||||||
.ENDIF
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; prepare for main decruncher
|
; prepare for main decruncher
|
||||||
.IF DONT_REUSE_OFFSET = 0
|
|
||||||
ror zp_ro_state
|
|
||||||
sec
|
|
||||||
.ENDIF
|
|
||||||
ldy zp_dest_lo
|
ldy zp_dest_lo
|
||||||
stx zp_dest_lo
|
stx zp_dest_lo
|
||||||
stx zp_bits_hi
|
stx zp_bits_hi
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; copy one literal byte to destination (11 bytes)
|
; copy one literal byte to destination (11(10) bytes)
|
||||||
;
|
;
|
||||||
|
.ifndef FORWARD_DECRUNCHING
|
||||||
|
FORWARD_DECRUNCHING = 1
|
||||||
|
.endif
|
||||||
|
.if FORWARD_DECRUNCHING = 0
|
||||||
literal_start1:
|
literal_start1:
|
||||||
.IF DECRUNCH_FORWARDS = 0
|
|
||||||
tya
|
tya
|
||||||
bne no_hi_decr
|
bne no_hi_decr
|
||||||
dec zp_dest_hi
|
dec zp_dest_hi
|
||||||
.IF DONT_REUSE_OFFSET = 0
|
|
||||||
dec zp_src_hi
|
|
||||||
.ENDIF
|
|
||||||
no_hi_decr:
|
no_hi_decr:
|
||||||
dey
|
dey
|
||||||
.ENDIF
|
|
||||||
jsr get_crunched_byte
|
jsr get_crunched_byte
|
||||||
sta (zp_dest_lo),y
|
sta (zp_dest_lo),y
|
||||||
.IF DECRUNCH_FORWARDS <> 0
|
|
||||||
|
.if SHOW_PROGRESS_DURING_DECRUNCH = 1
|
||||||
|
; periodically update on-screen progress UI
|
||||||
|
dec progress_counter
|
||||||
|
bne dont_update_progress_ui
|
||||||
|
tya
|
||||||
|
pha
|
||||||
|
ldy progress_index
|
||||||
|
lda progress_char,y
|
||||||
|
jsr show_one_progress_char
|
||||||
|
inc progress_index
|
||||||
|
lda progress_index
|
||||||
|
and #$07
|
||||||
|
sta progress_index
|
||||||
|
tay
|
||||||
|
lda #$20
|
||||||
|
jsr show_one_progress_char
|
||||||
|
pla
|
||||||
|
tay
|
||||||
|
dont_update_progress_ui:
|
||||||
|
.endif
|
||||||
|
.else
|
||||||
|
literal_start1:
|
||||||
|
jsr get_crunched_byte
|
||||||
|
sta (zp_dest_lo),y
|
||||||
iny
|
iny
|
||||||
bne skip_hi_incr
|
bne no_hi_incr
|
||||||
inc zp_dest_hi
|
inc zp_dest_hi
|
||||||
.IF DONT_REUSE_OFFSET = 0
|
no_hi_incr:
|
||||||
inc zp_src_hi
|
.endif
|
||||||
.ENDIF
|
|
||||||
skip_hi_incr:
|
|
||||||
.ENDIF
|
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; fetch sequence length index (15 bytes)
|
; fetch sequence length index (15 bytes)
|
||||||
; x must be #0 when entering and contains the length index + 1
|
; x must be #0 when entering and contains the length index + 1
|
||||||
; when exiting or 0 for literal byte
|
; when exiting or 0 for literal byte
|
||||||
next_round:
|
next_round:
|
||||||
.IF DONT_REUSE_OFFSET = 0
|
|
||||||
ror zp_ro_state
|
|
||||||
.ENDIF
|
|
||||||
dex
|
dex
|
||||||
lda zp_bitbuf
|
lda zp_bitbuf
|
||||||
no_literal1:
|
no_literal1:
|
||||||
|
@ -349,13 +313,13 @@ nofetch8:
|
||||||
; check for decrunch done and literal sequences (4 bytes)
|
; check for decrunch done and literal sequences (4 bytes)
|
||||||
;
|
;
|
||||||
cpx #$11
|
cpx #$11
|
||||||
.IF INLINE_GET_BITS <> 0
|
.ifdef INLINE_GET_BITS
|
||||||
bcc skip_jmp
|
bcc skip_jmp
|
||||||
jmp exit_or_lit_seq
|
jmp exit_or_lit_seq
|
||||||
skip_jmp:
|
skip_jmp:
|
||||||
.ELSE
|
.else
|
||||||
bcs exit_or_lit_seq
|
bcs exit_or_lit_seq
|
||||||
.ENDIF
|
.endif
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; calulate length of sequence (zp_len) (18(11) bytes) + get_bits macro
|
; calulate length of sequence (zp_len) (18(11) bytes) + get_bits macro
|
||||||
;
|
;
|
||||||
|
@ -363,7 +327,7 @@ skip_jmp:
|
||||||
mac_get_bits
|
mac_get_bits
|
||||||
adc tabl_lo - 1,x ; we have now calculated zp_len_lo
|
adc tabl_lo - 1,x ; we have now calculated zp_len_lo
|
||||||
sta zp_len_lo
|
sta zp_len_lo
|
||||||
.IF MAX_SEQUENCE_LENGTH_256 = 0
|
.ifndef MAX_SEQUENCE_LENGTH_256
|
||||||
lda zp_bits_hi
|
lda zp_bits_hi
|
||||||
adc tabl_hi - 1,x ; c = 0 after this.
|
adc tabl_hi - 1,x ; c = 0 after this.
|
||||||
sta zp_len_hi
|
sta zp_len_hi
|
||||||
|
@ -372,32 +336,15 @@ skip_jmp:
|
||||||
; z-flag reflects zp_len_hi here
|
; z-flag reflects zp_len_hi here
|
||||||
;
|
;
|
||||||
ldx zp_len_lo
|
ldx zp_len_lo
|
||||||
.ELSE
|
.else
|
||||||
tax
|
tax
|
||||||
.ENDIF
|
.endif
|
||||||
.IF MAX_SEQUENCE_LENGTH_256 = 0
|
|
||||||
lda #0
|
|
||||||
.ENDIF
|
|
||||||
.IF DONT_REUSE_OFFSET = 0
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; here we decide to reuse latest offset or not (13(15) bytes)
|
|
||||||
;
|
|
||||||
bit <zp_ro_state
|
|
||||||
bmi test_reuse
|
|
||||||
no_reuse:
|
|
||||||
.ENDIF
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; here we decide what offset table to use (17(15) bytes)
|
|
||||||
;
|
|
||||||
.IF MAX_SEQUENCE_LENGTH_256 = 0
|
|
||||||
sta <zp_bits_hi
|
|
||||||
.ENDIF
|
|
||||||
lda #$e1
|
lda #$e1
|
||||||
.IF EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE <> 0
|
.ifdef EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE
|
||||||
cpx #$04
|
cpx #$04
|
||||||
.ELSE
|
.else
|
||||||
cpx #$03
|
cpx #$03
|
||||||
.ENDIF
|
.endif
|
||||||
bcs gbnc2_next
|
bcs gbnc2_next
|
||||||
lda tabl_bit - 1,x
|
lda tabl_bit - 1,x
|
||||||
gbnc2_next:
|
gbnc2_next:
|
||||||
|
@ -413,139 +360,144 @@ gbnc2_ok:
|
||||||
bcs gbnc2_next
|
bcs gbnc2_next
|
||||||
tax
|
tax
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; calulate absolute offset (zp_src) (17 bytes) + get_bits macro
|
; calulate absolute offset (zp_src) (21(23) bytes) + get_bits macro
|
||||||
;
|
;
|
||||||
|
.ifndef MAX_SEQUENCE_LENGTH_256
|
||||||
|
lda #0
|
||||||
|
sta zp_bits_hi
|
||||||
|
.endif
|
||||||
lda tabl_bi,x
|
lda tabl_bi,x
|
||||||
mac_get_bits
|
mac_get_bits
|
||||||
.IF DECRUNCH_FORWARDS = 0
|
.if FORWARD_DECRUNCHING = 0
|
||||||
adc tabl_lo,x
|
adc tabl_lo,x
|
||||||
sta zp_src_lo
|
sta zp_src_lo
|
||||||
lda zp_bits_hi
|
lda zp_bits_hi
|
||||||
adc tabl_hi,x
|
adc tabl_hi,x
|
||||||
adc zp_dest_hi
|
adc zp_dest_hi
|
||||||
sta zp_src_hi
|
.else
|
||||||
.ELSE
|
|
||||||
clc
|
clc
|
||||||
adc tabl_lo,x
|
adc tabl_lo,x
|
||||||
eor #$ff
|
eor #$ff
|
||||||
sta zp_src_lo
|
sta zp_src_lo
|
||||||
lda zp_bits_hi
|
lda zp_dest_hi
|
||||||
adc tabl_hi,x
|
bcc skip_dest_hi
|
||||||
eor #$ff
|
sbc #1
|
||||||
adc zp_dest_hi
|
|
||||||
sta zp_src_hi
|
|
||||||
clc
|
clc
|
||||||
.ENDIF
|
skip_dest_hi:
|
||||||
|
sbc zp_bits_hi
|
||||||
|
sbc tabl_hi,x
|
||||||
|
clc
|
||||||
|
.endif
|
||||||
|
sta zp_src_hi
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; prepare for copy loop (2 bytes)
|
; prepare for copy loop (2 bytes)
|
||||||
;
|
;
|
||||||
|
pre_copy:
|
||||||
ldx zp_len_lo
|
ldx zp_len_lo
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; main copy loop (30 bytes)
|
; main copy loop (30 bytes)
|
||||||
;
|
;
|
||||||
copy_next:
|
copy_next:
|
||||||
.IF DECRUNCH_FORWARDS = 0
|
.if FORWARD_DECRUNCHING = 0
|
||||||
tya
|
tya
|
||||||
bne copy_skip_hi
|
bne copy_skip_hi
|
||||||
dec zp_dest_hi
|
dec zp_dest_hi
|
||||||
dec zp_src_hi
|
dec zp_src_hi
|
||||||
copy_skip_hi:
|
copy_skip_hi:
|
||||||
dey
|
dey
|
||||||
.ENDIF
|
.endif
|
||||||
.IF LITERAL_SEQUENCES_NOT_USED = 0
|
.ifndef LITERAL_SEQUENCES_NOT_USED
|
||||||
bcs get_literal_byte
|
bcs get_literal_byte
|
||||||
.ENDIF
|
.endif
|
||||||
lda (zp_src_lo),y
|
lda (zp_src_lo),y
|
||||||
literal_byte_gotten:
|
literal_byte_gotten:
|
||||||
sta (zp_dest_lo),y
|
sta (zp_dest_lo),y
|
||||||
.IF DECRUNCH_FORWARDS <> 0
|
.if (FORWARD_DECRUNCHING = 1)
|
||||||
iny
|
iny
|
||||||
bne copy_skip_hi
|
bne copy_skip_hi
|
||||||
inc zp_dest_hi
|
inc zp_dest_hi
|
||||||
inc zp_src_hi
|
inc zp_src_hi
|
||||||
copy_skip_hi:
|
copy_skip_hi:
|
||||||
.ENDIF
|
.endif
|
||||||
dex
|
dex
|
||||||
bne copy_next
|
bne copy_next
|
||||||
.IF MAX_SEQUENCE_LENGTH_256 = 0
|
.ifndef MAX_SEQUENCE_LENGTH_256
|
||||||
lda zp_len_hi
|
lda zp_len_hi
|
||||||
.IF INLINE_GET_BITS <> 0
|
.ifdef INLINE_GET_BITS
|
||||||
bne copy_next_hi
|
bne copy_next_hi
|
||||||
.ENDIF
|
.endif
|
||||||
.ENDIF
|
.endif
|
||||||
|
begin_stx:
|
||||||
stx zp_bits_hi
|
stx zp_bits_hi
|
||||||
.IF INLINE_GET_BITS = 0
|
.ifndef INLINE_GET_BITS
|
||||||
beq next_round
|
beq next_round
|
||||||
.ELSE
|
.else
|
||||||
jmp next_round
|
jmp next_round
|
||||||
.ENDIF
|
.endif
|
||||||
.IF MAX_SEQUENCE_LENGTH_256 = 0
|
.ifndef MAX_SEQUENCE_LENGTH_256
|
||||||
copy_next_hi:
|
copy_next_hi:
|
||||||
dec zp_len_hi
|
dec zp_len_hi
|
||||||
jmp copy_next
|
jmp copy_next
|
||||||
.ENDIF
|
.endif
|
||||||
.IF DONT_REUSE_OFFSET = 0
|
.ifndef LITERAL_SEQUENCES_NOT_USED
|
||||||
; -------------------------------------------------------------------
|
get_literal_byte:
|
||||||
; test for offset reuse (11 bytes)
|
|
||||||
;
|
|
||||||
test_reuse:
|
|
||||||
bvs no_reuse
|
|
||||||
.IF MAX_SEQUENCE_LENGTH_256 <> 0
|
|
||||||
lda #$00 ; fetch one bit
|
|
||||||
.ENDIF
|
|
||||||
asl zp_bitbuf
|
|
||||||
bne gbnc1_ok
|
|
||||||
pha
|
|
||||||
jsr get_crunched_byte
|
jsr get_crunched_byte
|
||||||
rol
|
bcs literal_byte_gotten
|
||||||
sta zp_bitbuf
|
.endif
|
||||||
pla
|
|
||||||
gbnc1_ok:
|
|
||||||
rol
|
|
||||||
beq no_reuse ; bit == 0 => C=0, no reuse
|
|
||||||
bne copy_next ; bit != 0 => C=0, reuse previous offset
|
|
||||||
.ENDIF
|
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; exit or literal sequence handling (16(12) bytes)
|
; exit or literal sequence handling (16(12) bytes)
|
||||||
;
|
;
|
||||||
exit_or_lit_seq:
|
exit_or_lit_seq:
|
||||||
.IF LITERAL_SEQUENCES_NOT_USED = 0
|
.ifndef LITERAL_SEQUENCES_NOT_USED
|
||||||
beq decr_exit
|
beq decr_exit
|
||||||
jsr get_crunched_byte
|
jsr get_crunched_byte
|
||||||
.IF MAX_SEQUENCE_LENGTH_256 = 0
|
.ifndef MAX_SEQUENCE_LENGTH_256
|
||||||
sta zp_len_hi
|
sta zp_len_hi
|
||||||
.ENDIF
|
.endif
|
||||||
jsr get_crunched_byte
|
jsr get_crunched_byte
|
||||||
tax
|
tax
|
||||||
bcs copy_next
|
bcs copy_next
|
||||||
decr_exit:
|
decr_exit:
|
||||||
.ENDIF
|
.endif
|
||||||
rts
|
rts
|
||||||
.IF LITERAL_SEQUENCES_NOT_USED = 0
|
.ifdef EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE
|
||||||
get_literal_byte:
|
|
||||||
jsr get_crunched_byte
|
|
||||||
bcs literal_byte_gotten
|
|
||||||
.ENDIF
|
|
||||||
.IF EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE <> 0
|
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; the static stable used for bits+offset for lengths 1, 2 and 3 (3 bytes)
|
; the static stable used for bits+offset for lengths 1, 2 and 3 (3 bytes)
|
||||||
; bits 2, 4, 4 and offsets 64, 48, 32 corresponding to
|
; bits 2, 4, 4 and offsets 64, 48, 32 corresponding to
|
||||||
; %10010000, %11100011, %11100010
|
; %10010000, %11100011, %11100010
|
||||||
tabl_bit:
|
tabl_bit:
|
||||||
.BYTE $90, $e3, $e2
|
.byte $90, $e3, $e2
|
||||||
.ELSE
|
.else
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; the static stable used for bits+offset for lengths 1 and 2 (2 bytes)
|
; the static stable used for bits+offset for lengths 1 and 2 (2 bytes)
|
||||||
; bits 2, 4 and offsets 48, 32 corresponding to %10001100, %11100010
|
; bits 2, 4 and offsets 48, 32 corresponding to %10001100, %11100010
|
||||||
tabl_bit:
|
tabl_bit:
|
||||||
.BYTE $8c, $e2
|
.byte $8c, $e2
|
||||||
.ENDIF
|
.endif
|
||||||
|
.if SHOW_PROGRESS_DURING_DECRUNCH = 1
|
||||||
.IF ENABLE_SPLIT_ENCODING <> 0
|
progress_index:
|
||||||
split_init_zp:
|
.byte $00
|
||||||
mac_init_zp
|
progress_counter:
|
||||||
|
.byte $00
|
||||||
|
progress_char:
|
||||||
|
.byte $DC, $FC, $AF, $AD, $DC, $FC, $AF, $AD
|
||||||
|
progress_address_lo:
|
||||||
|
.byte $BB, $BC, $BD, $3D, $BD, $BC, $BB, $3B
|
||||||
|
progress_address_hi:
|
||||||
|
.byte $05, $05, $05, $06, $06, $06, $06, $06
|
||||||
|
show_one_progress_char:
|
||||||
|
; in: A=ASCII char to show
|
||||||
|
; y=0..7 index into progress_address_lo/hi array
|
||||||
|
pha
|
||||||
|
lda progress_address_lo,y
|
||||||
|
sta progress_STA+1
|
||||||
|
lda progress_address_hi,y
|
||||||
|
sta progress_STA+2
|
||||||
|
pla
|
||||||
|
progress_STA:
|
||||||
|
sta $FFFF
|
||||||
rts
|
rts
|
||||||
.ENDIF
|
.endif
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; end of decruncher
|
; end of decruncher
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
|
@ -554,22 +506,22 @@ split_init_zp:
|
||||||
; this 156 (204) byte table area may be relocated. It may also be
|
; this 156 (204) byte table area may be relocated. It may also be
|
||||||
; clobbered by other data between decrunches.
|
; clobbered by other data between decrunches.
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
decrunch_table:
|
decrunch_table=$200;;:
|
||||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
;; .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
;; .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
;; .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
.IF EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE <> 0
|
;;.IFDEF EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE
|
||||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
;; .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
;; .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
;; .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
.ENDIF
|
;;.ENDIF
|
||||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
;; .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
;; .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
;; .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
;; .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
;; .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
;; .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
.byte 0,0,0,0,0,0,0,0,0,0,0,0
|
;; .byte 0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
; end of decruncher
|
; end of decruncher
|
||||||
; -------------------------------------------------------------------
|
; -------------------------------------------------------------------
|
||||||
|
|
575
compression/comparison/exodecrunch.s.old
Normal file
575
compression/comparison/exodecrunch.s.old
Normal file
|
@ -0,0 +1,575 @@
|
||||||
|
;
|
||||||
|
; Copyright (c) 2002 - 2020 Magnus Lind.
|
||||||
|
;
|
||||||
|
; This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
; In no event will the authors be held liable for any damages arising from
|
||||||
|
; the use of this software.
|
||||||
|
;
|
||||||
|
; Permission is granted to anyone to use this software for any purpose,
|
||||||
|
; including commercial applications, and to alter it and redistribute it
|
||||||
|
; freely, subject to the following restrictions:
|
||||||
|
;
|
||||||
|
; 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
; claim that you wrote the original software. If you use this software in a
|
||||||
|
; product, an acknowledgment in the product documentation would be
|
||||||
|
; appreciated but is not required.
|
||||||
|
;
|
||||||
|
; 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
; be misrepresented as being the original software.
|
||||||
|
;
|
||||||
|
; 3. This notice may not be removed or altered from any distribution.
|
||||||
|
;
|
||||||
|
; 4. The names of this software and/or it's copyright holders may not be
|
||||||
|
; used to endorse or promote products derived from this software without
|
||||||
|
; specific prior written permission.
|
||||||
|
;
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; Known quirks:
|
||||||
|
; Can't handle a sequence reference that ends at $ffff. It is left in
|
||||||
|
; since it is a corner case and fixing it impacts negatively on
|
||||||
|
; performance or backwards compatibility.
|
||||||
|
; A simple way to work around this is to not decrunch to address $ffff.
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; Controls if the shared get_bits routines should be inlined or not.
|
||||||
|
;INLINE_GET_BITS=1
|
||||||
|
.IFNDEF INLINE_GET_BITS
|
||||||
|
INLINE_GET_BITS = 0
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; if literal sequences is not used (the data was crunched with the -c
|
||||||
|
; flag) then the following line can be uncommented for shorter and.
|
||||||
|
; slightly faster code.
|
||||||
|
;LITERAL_SEQUENCES_NOT_USED = 1
|
||||||
|
.IFNDEF LITERAL_SEQUENCES_NOT_USED
|
||||||
|
LITERAL_SEQUENCES_NOT_USED = 0
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; if the sequence length is limited to 256 (the data was crunched with
|
||||||
|
; the -M256 flag) then the following line can be uncommented for
|
||||||
|
; shorter and slightly faster code.
|
||||||
|
;MAX_SEQUENCE_LENGTH_256 = 1
|
||||||
|
.IFNDEF MAX_SEQUENCE_LENGTH_256
|
||||||
|
MAX_SEQUENCE_LENGTH_256 = 0
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; if the sequence length 3 has its own offset table (the data was
|
||||||
|
; crunched with the -P+16 flag) then the following
|
||||||
|
; line must be uncommented.
|
||||||
|
;EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE = 1
|
||||||
|
.IFNDEF EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE
|
||||||
|
EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE = 0
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; if sequence offsets are not reused (the data was crunched with the
|
||||||
|
; -P-32 flag) then the following line must be uncommented. Uncommenting the
|
||||||
|
; line will also result in shorter and slightly faster code.
|
||||||
|
;DONT_REUSE_OFFSET = 1
|
||||||
|
.IFNDEF DONT_REUSE_OFFSET
|
||||||
|
DONT_REUSE_OFFSET = 0
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; if decrunching forwards then the following line must be uncommented.
|
||||||
|
;DECRUNCH_FORWARDS = 1
|
||||||
|
.IFNDEF DECRUNCH_FORWARDS
|
||||||
|
DECRUNCH_FORWARDS = 0
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; if split encoding is used (the data is crunched with the -E flag)
|
||||||
|
; then the following line must be uncommented.
|
||||||
|
;ENABLE_SPLIT_ENCODING = 1
|
||||||
|
.IFNDEF ENABLE_SPLIT_ENCODING
|
||||||
|
ENABLE_SPLIT_ENCODING = 0
|
||||||
|
.ENDIF
|
||||||
|
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; The decruncher jsr:s to the get_crunched_byte address when it wants to
|
||||||
|
; read a crunched byte into A. This subroutine has to preserve X and Y
|
||||||
|
; register and must not modify the state of the carry nor the overflow flag.
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
;.import get_crunched_byte
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; This function is the heart of the decruncher. (for non split crunched files)
|
||||||
|
; It initializes the decruncher zeropage locations and precalculates the
|
||||||
|
; decrunch tables and decrunches the data
|
||||||
|
; This function will not change the interrupt status bit and it will not
|
||||||
|
; modify the memory configuration.
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
.export decrunch
|
||||||
|
.IF ENABLE_SPLIT_ENCODING <> 0
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; To decrunch files crunched with the split feature (-E) you can't use the
|
||||||
|
; decrunch function. Instead you call the split_decrunch function. But you
|
||||||
|
; can only do this if the decrunch table contains the encoding used by the
|
||||||
|
; file you are decrunching. To generate the correct content for the decrunch
|
||||||
|
; table call set the get_crunched_byte function to point to the encoding data
|
||||||
|
; and then call the split_gentable function.
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
.export split_gentable
|
||||||
|
.export split_decrunch
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; zero page addresses used
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
zp_len_lo = $9e
|
||||||
|
zp_len_hi = $9f
|
||||||
|
|
||||||
|
zp_src_lo = $ae
|
||||||
|
zp_src_hi = zp_src_lo + 1
|
||||||
|
|
||||||
|
zp_bits_hi = $a7
|
||||||
|
.IF DONT_REUSE_OFFSET = 0
|
||||||
|
zp_ro_state = $a8
|
||||||
|
.ENDIF
|
||||||
|
|
||||||
|
zp_bitbuf = $fd
|
||||||
|
zp_dest_lo = zp_bitbuf + 1 ; dest addr lo
|
||||||
|
zp_dest_hi = zp_bitbuf + 2 ; dest addr hi
|
||||||
|
|
||||||
|
.IF EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE <> 0
|
||||||
|
encoded_entries = 68
|
||||||
|
.ELSE
|
||||||
|
encoded_entries = 52
|
||||||
|
.ENDIF
|
||||||
|
|
||||||
|
tabl_bi = decrunch_table
|
||||||
|
tabl_lo = decrunch_table + encoded_entries
|
||||||
|
tabl_hi = decrunch_table + encoded_entries * 2
|
||||||
|
|
||||||
|
;; refill bits is always inlined
|
||||||
|
.MACRO mac_refill_bits
|
||||||
|
pha
|
||||||
|
jsr get_crunched_byte
|
||||||
|
rol
|
||||||
|
sta zp_bitbuf
|
||||||
|
pla
|
||||||
|
.ENDMACRO
|
||||||
|
|
||||||
|
.MACRO mac_get_bits
|
||||||
|
.IF INLINE_GET_BITS <> 0
|
||||||
|
.SCOPE
|
||||||
|
adc #$80 ; needs c=0, affects v
|
||||||
|
asl
|
||||||
|
bpl gb_skip
|
||||||
|
gb_next:
|
||||||
|
asl zp_bitbuf
|
||||||
|
bne gb_ok
|
||||||
|
mac_refill_bits
|
||||||
|
gb_ok:
|
||||||
|
rol
|
||||||
|
bmi gb_next
|
||||||
|
gb_skip:
|
||||||
|
bvc skip
|
||||||
|
gb_get_hi:
|
||||||
|
sec
|
||||||
|
sta zp_bits_hi
|
||||||
|
jsr get_crunched_byte
|
||||||
|
skip:
|
||||||
|
.ENDSCOPE
|
||||||
|
.ELSE
|
||||||
|
jsr get_bits
|
||||||
|
.ENDIF
|
||||||
|
.ENDMACRO
|
||||||
|
|
||||||
|
.MACRO mac_init_zp
|
||||||
|
.SCOPE
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; init zeropage and x reg. (8 bytes)
|
||||||
|
;
|
||||||
|
init_zp:
|
||||||
|
jsr get_crunched_byte
|
||||||
|
sta zp_bitbuf - 1,x
|
||||||
|
dex
|
||||||
|
bne init_zp
|
||||||
|
.ENDSCOPE
|
||||||
|
.ENDMACRO
|
||||||
|
|
||||||
|
.IF INLINE_GET_BITS = 0
|
||||||
|
get_bits:
|
||||||
|
adc #$80 ; needs c=0, affects v
|
||||||
|
asl
|
||||||
|
bpl gb_skip
|
||||||
|
gb_next:
|
||||||
|
asl zp_bitbuf
|
||||||
|
bne gb_ok
|
||||||
|
mac_refill_bits
|
||||||
|
gb_ok:
|
||||||
|
rol
|
||||||
|
bmi gb_next
|
||||||
|
gb_skip:
|
||||||
|
bvs gb_get_hi
|
||||||
|
rts
|
||||||
|
gb_get_hi:
|
||||||
|
sec
|
||||||
|
sta zp_bits_hi
|
||||||
|
jmp get_crunched_byte
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; no code below this comment has to be modified in order to generate
|
||||||
|
; a working decruncher of this source file.
|
||||||
|
; However, you may want to relocate the tables last in the file to a
|
||||||
|
; more suitable address.
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; jsr this label to decrunch, it will in turn init the tables and
|
||||||
|
; call the decruncher
|
||||||
|
; no constraints on register content, however the
|
||||||
|
; decimal flag has to be cleared (it almost always is, otherwise do a cld)
|
||||||
|
decrunch:
|
||||||
|
.IF ENABLE_SPLIT_ENCODING <> 0
|
||||||
|
ldx #3
|
||||||
|
jsr internal_gentable
|
||||||
|
jmp normal_decrunch
|
||||||
|
split_gentable:
|
||||||
|
ldx #1
|
||||||
|
internal_gentable:
|
||||||
|
jsr split_init_zp
|
||||||
|
.ELSE
|
||||||
|
ldx #3
|
||||||
|
mac_init_zp
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; calculate tables (64 bytes) + get_bits macro
|
||||||
|
; x must be #0 when entering
|
||||||
|
;
|
||||||
|
ldy #0
|
||||||
|
clc
|
||||||
|
table_gen:
|
||||||
|
tax
|
||||||
|
tya
|
||||||
|
and #$0f
|
||||||
|
sta tabl_lo,y
|
||||||
|
beq shortcut ; start a new sequence
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
txa
|
||||||
|
adc tabl_lo - 1,y
|
||||||
|
sta tabl_lo,y
|
||||||
|
lda zp_len_hi
|
||||||
|
adc tabl_hi - 1,y
|
||||||
|
shortcut:
|
||||||
|
sta tabl_hi,y
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
lda #$01
|
||||||
|
sta <zp_len_hi
|
||||||
|
lda #$78 ; %01111000
|
||||||
|
mac_get_bits
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
lsr
|
||||||
|
tax
|
||||||
|
beq rolled
|
||||||
|
php
|
||||||
|
rolle:
|
||||||
|
asl zp_len_hi
|
||||||
|
sec
|
||||||
|
ror
|
||||||
|
dex
|
||||||
|
bne rolle
|
||||||
|
plp
|
||||||
|
rolled:
|
||||||
|
ror
|
||||||
|
sta tabl_bi,y
|
||||||
|
bmi no_fixup_lohi
|
||||||
|
lda zp_len_hi
|
||||||
|
stx zp_len_hi
|
||||||
|
.BYTE $24
|
||||||
|
no_fixup_lohi:
|
||||||
|
txa
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
iny
|
||||||
|
cpy #encoded_entries
|
||||||
|
bne table_gen
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
.IF ENABLE_SPLIT_ENCODING <> 0
|
||||||
|
rts
|
||||||
|
split_decrunch:
|
||||||
|
ldx #3
|
||||||
|
jsr split_init_zp
|
||||||
|
; X reg must be 0 here
|
||||||
|
sec
|
||||||
|
normal_decrunch:
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; prepare for main decruncher
|
||||||
|
.IF DONT_REUSE_OFFSET = 0
|
||||||
|
ror zp_ro_state
|
||||||
|
sec
|
||||||
|
.ENDIF
|
||||||
|
ldy zp_dest_lo
|
||||||
|
stx zp_dest_lo
|
||||||
|
stx zp_bits_hi
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; copy one literal byte to destination (11 bytes)
|
||||||
|
;
|
||||||
|
literal_start1:
|
||||||
|
.IF DECRUNCH_FORWARDS = 0
|
||||||
|
tya
|
||||||
|
bne no_hi_decr
|
||||||
|
dec zp_dest_hi
|
||||||
|
.IF DONT_REUSE_OFFSET = 0
|
||||||
|
dec zp_src_hi
|
||||||
|
.ENDIF
|
||||||
|
no_hi_decr:
|
||||||
|
dey
|
||||||
|
.ENDIF
|
||||||
|
jsr get_crunched_byte
|
||||||
|
sta (zp_dest_lo),y
|
||||||
|
.IF DECRUNCH_FORWARDS <> 0
|
||||||
|
iny
|
||||||
|
bne skip_hi_incr
|
||||||
|
inc zp_dest_hi
|
||||||
|
.IF DONT_REUSE_OFFSET = 0
|
||||||
|
inc zp_src_hi
|
||||||
|
.ENDIF
|
||||||
|
skip_hi_incr:
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; fetch sequence length index (15 bytes)
|
||||||
|
; x must be #0 when entering and contains the length index + 1
|
||||||
|
; when exiting or 0 for literal byte
|
||||||
|
next_round:
|
||||||
|
.IF DONT_REUSE_OFFSET = 0
|
||||||
|
ror zp_ro_state
|
||||||
|
.ENDIF
|
||||||
|
dex
|
||||||
|
lda zp_bitbuf
|
||||||
|
no_literal1:
|
||||||
|
asl
|
||||||
|
bne nofetch8
|
||||||
|
jsr get_crunched_byte
|
||||||
|
rol
|
||||||
|
nofetch8:
|
||||||
|
inx
|
||||||
|
bcc no_literal1
|
||||||
|
sta zp_bitbuf
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; check for literal byte (2 bytes)
|
||||||
|
;
|
||||||
|
beq literal_start1
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; check for decrunch done and literal sequences (4 bytes)
|
||||||
|
;
|
||||||
|
cpx #$11
|
||||||
|
.IF INLINE_GET_BITS <> 0
|
||||||
|
bcc skip_jmp
|
||||||
|
jmp exit_or_lit_seq
|
||||||
|
skip_jmp:
|
||||||
|
.ELSE
|
||||||
|
bcs exit_or_lit_seq
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; calulate length of sequence (zp_len) (18(11) bytes) + get_bits macro
|
||||||
|
;
|
||||||
|
lda tabl_bi - 1,x
|
||||||
|
mac_get_bits
|
||||||
|
adc tabl_lo - 1,x ; we have now calculated zp_len_lo
|
||||||
|
sta zp_len_lo
|
||||||
|
.IF MAX_SEQUENCE_LENGTH_256 = 0
|
||||||
|
lda zp_bits_hi
|
||||||
|
adc tabl_hi - 1,x ; c = 0 after this.
|
||||||
|
sta zp_len_hi
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; here we decide what offset table to use (27(26) bytes) + get_bits_nc macro
|
||||||
|
; z-flag reflects zp_len_hi here
|
||||||
|
;
|
||||||
|
ldx zp_len_lo
|
||||||
|
.ELSE
|
||||||
|
tax
|
||||||
|
.ENDIF
|
||||||
|
.IF MAX_SEQUENCE_LENGTH_256 = 0
|
||||||
|
lda #0
|
||||||
|
.ENDIF
|
||||||
|
.IF DONT_REUSE_OFFSET = 0
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; here we decide to reuse latest offset or not (13(15) bytes)
|
||||||
|
;
|
||||||
|
bit <zp_ro_state
|
||||||
|
bmi test_reuse
|
||||||
|
no_reuse:
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; here we decide what offset table to use (17(15) bytes)
|
||||||
|
;
|
||||||
|
.IF MAX_SEQUENCE_LENGTH_256 = 0
|
||||||
|
sta <zp_bits_hi
|
||||||
|
.ENDIF
|
||||||
|
lda #$e1
|
||||||
|
.IF EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE <> 0
|
||||||
|
cpx #$04
|
||||||
|
.ELSE
|
||||||
|
cpx #$03
|
||||||
|
.ENDIF
|
||||||
|
bcs gbnc2_next
|
||||||
|
lda tabl_bit - 1,x
|
||||||
|
gbnc2_next:
|
||||||
|
asl zp_bitbuf
|
||||||
|
bne gbnc2_ok
|
||||||
|
tax
|
||||||
|
jsr get_crunched_byte
|
||||||
|
rol
|
||||||
|
sta zp_bitbuf
|
||||||
|
txa
|
||||||
|
gbnc2_ok:
|
||||||
|
rol
|
||||||
|
bcs gbnc2_next
|
||||||
|
tax
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; calulate absolute offset (zp_src) (17 bytes) + get_bits macro
|
||||||
|
;
|
||||||
|
lda tabl_bi,x
|
||||||
|
mac_get_bits
|
||||||
|
.IF DECRUNCH_FORWARDS = 0
|
||||||
|
adc tabl_lo,x
|
||||||
|
sta zp_src_lo
|
||||||
|
lda zp_bits_hi
|
||||||
|
adc tabl_hi,x
|
||||||
|
adc zp_dest_hi
|
||||||
|
sta zp_src_hi
|
||||||
|
.ELSE
|
||||||
|
clc
|
||||||
|
adc tabl_lo,x
|
||||||
|
eor #$ff
|
||||||
|
sta zp_src_lo
|
||||||
|
lda zp_bits_hi
|
||||||
|
adc tabl_hi,x
|
||||||
|
eor #$ff
|
||||||
|
adc zp_dest_hi
|
||||||
|
sta zp_src_hi
|
||||||
|
clc
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; prepare for copy loop (2 bytes)
|
||||||
|
;
|
||||||
|
ldx zp_len_lo
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; main copy loop (30 bytes)
|
||||||
|
;
|
||||||
|
copy_next:
|
||||||
|
.IF DECRUNCH_FORWARDS = 0
|
||||||
|
tya
|
||||||
|
bne copy_skip_hi
|
||||||
|
dec zp_dest_hi
|
||||||
|
dec zp_src_hi
|
||||||
|
copy_skip_hi:
|
||||||
|
dey
|
||||||
|
.ENDIF
|
||||||
|
.IF LITERAL_SEQUENCES_NOT_USED = 0
|
||||||
|
bcs get_literal_byte
|
||||||
|
.ENDIF
|
||||||
|
lda (zp_src_lo),y
|
||||||
|
literal_byte_gotten:
|
||||||
|
sta (zp_dest_lo),y
|
||||||
|
.IF DECRUNCH_FORWARDS <> 0
|
||||||
|
iny
|
||||||
|
bne copy_skip_hi
|
||||||
|
inc zp_dest_hi
|
||||||
|
inc zp_src_hi
|
||||||
|
copy_skip_hi:
|
||||||
|
.ENDIF
|
||||||
|
dex
|
||||||
|
bne copy_next
|
||||||
|
.IF MAX_SEQUENCE_LENGTH_256 = 0
|
||||||
|
lda zp_len_hi
|
||||||
|
.IF INLINE_GET_BITS <> 0
|
||||||
|
bne copy_next_hi
|
||||||
|
.ENDIF
|
||||||
|
.ENDIF
|
||||||
|
stx zp_bits_hi
|
||||||
|
.IF INLINE_GET_BITS = 0
|
||||||
|
beq next_round
|
||||||
|
.ELSE
|
||||||
|
jmp next_round
|
||||||
|
.ENDIF
|
||||||
|
.IF MAX_SEQUENCE_LENGTH_256 = 0
|
||||||
|
copy_next_hi:
|
||||||
|
dec zp_len_hi
|
||||||
|
jmp copy_next
|
||||||
|
.ENDIF
|
||||||
|
.IF DONT_REUSE_OFFSET = 0
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; test for offset reuse (11 bytes)
|
||||||
|
;
|
||||||
|
test_reuse:
|
||||||
|
bvs no_reuse
|
||||||
|
.IF MAX_SEQUENCE_LENGTH_256 <> 0
|
||||||
|
lda #$00 ; fetch one bit
|
||||||
|
.ENDIF
|
||||||
|
asl zp_bitbuf
|
||||||
|
bne gbnc1_ok
|
||||||
|
pha
|
||||||
|
jsr get_crunched_byte
|
||||||
|
rol
|
||||||
|
sta zp_bitbuf
|
||||||
|
pla
|
||||||
|
gbnc1_ok:
|
||||||
|
rol
|
||||||
|
beq no_reuse ; bit == 0 => C=0, no reuse
|
||||||
|
bne copy_next ; bit != 0 => C=0, reuse previous offset
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; exit or literal sequence handling (16(12) bytes)
|
||||||
|
;
|
||||||
|
exit_or_lit_seq:
|
||||||
|
.IF LITERAL_SEQUENCES_NOT_USED = 0
|
||||||
|
beq decr_exit
|
||||||
|
jsr get_crunched_byte
|
||||||
|
.IF MAX_SEQUENCE_LENGTH_256 = 0
|
||||||
|
sta zp_len_hi
|
||||||
|
.ENDIF
|
||||||
|
jsr get_crunched_byte
|
||||||
|
tax
|
||||||
|
bcs copy_next
|
||||||
|
decr_exit:
|
||||||
|
.ENDIF
|
||||||
|
rts
|
||||||
|
.IF LITERAL_SEQUENCES_NOT_USED = 0
|
||||||
|
get_literal_byte:
|
||||||
|
jsr get_crunched_byte
|
||||||
|
bcs literal_byte_gotten
|
||||||
|
.ENDIF
|
||||||
|
.IF EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE <> 0
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; the static stable used for bits+offset for lengths 1, 2 and 3 (3 bytes)
|
||||||
|
; bits 2, 4, 4 and offsets 64, 48, 32 corresponding to
|
||||||
|
; %10010000, %11100011, %11100010
|
||||||
|
tabl_bit:
|
||||||
|
.BYTE $90, $e3, $e2
|
||||||
|
.ELSE
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; the static stable used for bits+offset for lengths 1 and 2 (2 bytes)
|
||||||
|
; bits 2, 4 and offsets 48, 32 corresponding to %10001100, %11100010
|
||||||
|
tabl_bit:
|
||||||
|
.BYTE $8c, $e2
|
||||||
|
.ENDIF
|
||||||
|
|
||||||
|
.IF ENABLE_SPLIT_ENCODING <> 0
|
||||||
|
split_init_zp:
|
||||||
|
mac_init_zp
|
||||||
|
rts
|
||||||
|
.ENDIF
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; end of decruncher
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; this 156 (204) byte table area may be relocated. It may also be
|
||||||
|
; clobbered by other data between decrunches.
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
decrunch_table:
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
.IF EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE <> 0
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
.ENDIF
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
; -------------------------------------------------------------------
|
||||||
|
; end of decruncher
|
||||||
|
; -------------------------------------------------------------------
|
|
@ -1,79 +1,98 @@
|
||||||
; -------------------------------------------------------------------
|
.include "zp.inc"
|
||||||
; this file is intended to be assembled and linked with the cc65 toolchain.
|
.include "hardware.inc"
|
||||||
; It has not been tested with any other assemblers or linkers.
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; example usage of the standard decruncher
|
|
||||||
; this program decrunches data to memory
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; if decrunching forwards then the following line must be uncommented.
|
|
||||||
;DECRUNCH_FORWARDS = 1
|
|
||||||
.IFNDEF DECRUNCH_FORWARDS
|
|
||||||
DECRUNCH_FORWARDS = 0
|
|
||||||
.ENDIF
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
;.import decrunch
|
|
||||||
;.export get_crunched_byte
|
|
||||||
;.import end_of_data
|
|
||||||
|
|
||||||
; .byte $01,$08,$0b,$08,<2003,>2003,$9e,'2','0','6','1',0,0,0
|
exomizer_test:
|
||||||
; -------------------------------------------------------------------
|
|
||||||
; we begin here
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
|
|
||||||
lda #$20
|
bit SET_GR
|
||||||
sta zp_dest_hi
|
bit PAGE1
|
||||||
lda #$00
|
bit HIRES
|
||||||
sta zp_dest_lo
|
bit FULLGR
|
||||||
|
|
||||||
|
lda #<data_begin
|
||||||
.IF DECRUNCH_FORWARDS = 0
|
|
||||||
lda $04
|
|
||||||
sta _byte_lo
|
|
||||||
lda $05
|
|
||||||
sta _byte_hi
|
|
||||||
.ELSE
|
|
||||||
lda #<end_of_data
|
|
||||||
sta _byte_lo
|
sta _byte_lo
|
||||||
lda #>end_of_data
|
lda #>data_begin
|
||||||
sta _byte_hi
|
sta _byte_hi
|
||||||
|
|
||||||
; lda $02
|
jsr decrunch
|
||||||
; sta _byte_lo
|
|
||||||
; lda $03
|
.if 0
|
||||||
; sta _byte_hi
|
|
||||||
.ENDIF
|
; lda #<data_begin
|
||||||
jsr decrunch
|
; sta zp_src_lo
|
||||||
|
; lda #>data_begin
|
||||||
|
; sta zp_src_hi
|
||||||
|
|
||||||
|
|
||||||
|
lda #$1F
|
||||||
|
pha
|
||||||
|
lda #>(data_end) ; sizehi2
|
||||||
|
pha
|
||||||
|
lda #<(data_end) ; sizelo2
|
||||||
|
pha
|
||||||
|
lda #>(start_d-1) ; #>(@loaddecrunch - 1)
|
||||||
|
pha
|
||||||
|
lda #<(start_d-1) ; #<(@loaddecrunch - 1)
|
||||||
|
pha
|
||||||
|
|
||||||
|
jmp decrunch_table
|
||||||
|
|
||||||
|
|
||||||
|
;decrunch_table:
|
||||||
|
;!warn "entry=",*
|
||||||
|
; pla ; <loaddecrunch
|
||||||
|
; tay
|
||||||
|
|
||||||
|
; pla ; >loaddecrunch
|
||||||
|
; tax
|
||||||
|
; clc
|
||||||
|
|
||||||
|
; pla ; sizelo2
|
||||||
|
; adc #$F8
|
||||||
|
; sta _byte_lo
|
||||||
|
|
||||||
|
; pla ;sizehi2
|
||||||
|
; sta zp_bitbuf
|
||||||
|
|
||||||
|
; pla ;#$1F
|
||||||
|
; adc zp_bitbuf
|
||||||
|
; sta _byte_hi
|
||||||
|
|
||||||
|
; txa
|
||||||
|
; pha
|
||||||
|
|
||||||
|
; tya
|
||||||
|
; pha
|
||||||
|
|
||||||
|
; jmp decrunch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; jsr decrunch
|
||||||
|
|
||||||
|
.endif
|
||||||
|
|
||||||
end:
|
end:
|
||||||
jmp end
|
jmp end
|
||||||
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
get_crunched_byte:
|
get_crunched_byte:
|
||||||
.IF DECRUNCH_FORWARDS = 0
|
|
||||||
lda _byte_lo
|
|
||||||
bne _byte_skip_hi
|
|
||||||
dec _byte_hi
|
|
||||||
_byte_skip_hi:
|
|
||||||
dec _byte_lo
|
|
||||||
.ENDIF
|
|
||||||
_byte_lo = * + 1
|
_byte_lo = * + 1
|
||||||
_byte_hi = * + 2
|
_byte_hi = * + 2
|
||||||
lda $ffff ; needs to be set correctly before
|
lda $1234 ; needs to be set correctly before
|
||||||
|
; decrunch_file is called.
|
||||||
.IF DECRUNCH_FORWARDS <> 0
|
inc _byte_lo
|
||||||
inc _byte_lo
|
bne _byte_skip_hi
|
||||||
bne _byte_skip_hi
|
inc _byte_hi
|
||||||
inc _byte_hi
|
|
||||||
_byte_skip_hi:
|
_byte_skip_hi:
|
||||||
.ENDIF
|
rts
|
||||||
rts ; decrunch_file is called.
|
|
||||||
; end_of_data needs to point to the address just after the address
|
start_d:
|
||||||
; of the last byte of crunched data.
|
|
||||||
; -------------------------------------------------------------------
|
|
||||||
|
|
||||||
.include "exodecrunch.s"
|
.include "exodecrunch.s"
|
||||||
|
|
||||||
.incbin "level5.exo"
|
|
||||||
|
|
||||||
end_of_data:
|
data_begin:
|
||||||
|
.byte $20,$00
|
||||||
|
.incbin "level5.exo"
|
||||||
|
data_end:
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
lzsa_test:
|
lzsa_test:
|
||||||
|
|
||||||
bit SET_GR
|
bit SET_GR
|
||||||
bit PAGE0
|
bit PAGE1
|
||||||
bit HIRES
|
bit HIRES
|
||||||
bit FULLGR
|
bit FULLGR
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
lzsa_test:
|
lzsa_test:
|
||||||
|
|
||||||
bit SET_GR
|
bit SET_GR
|
||||||
bit PAGE0
|
bit PAGE1
|
||||||
bit HIRES
|
bit HIRES
|
||||||
bit FULLGR
|
bit FULLGR
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
lzsa_test:
|
lzsa_test:
|
||||||
|
|
||||||
bit SET_GR
|
bit SET_GR
|
||||||
bit PAGE0
|
bit PAGE1
|
||||||
bit HIRES
|
bit HIRES
|
||||||
bit FULLGR
|
bit FULLGR
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
lzsa_test:
|
lzsa_test:
|
||||||
|
|
||||||
bit SET_GR
|
bit SET_GR
|
||||||
bit PAGE0
|
bit PAGE1
|
||||||
bit HIRES
|
bit HIRES
|
||||||
bit FULLGR
|
bit FULLGR
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,31 @@
|
||||||
all:
|
include ../../Makefile.inc
|
||||||
|
|
||||||
clean:
|
DOS33 = ../../utils/dos33fs-utils/dos33
|
||||||
rm -f *~
|
TOKENIZE = ../../utils/asoft_basic-utils/tokenize_asoft
|
||||||
|
LINKERSCRIPTS = ../../linker_scripts
|
||||||
|
EMPTYDISK = ../../empty_disk/empty.dsk
|
||||||
|
|
||||||
|
all: cd.dsk
|
||||||
|
|
||||||
|
cd.dsk: HELLO HORIZ
|
||||||
|
cp $(EMPTYDISK) cd.dsk
|
||||||
|
$(DOS33) -y cd.dsk SAVE A HELLO
|
||||||
|
$(DOS33) -y cd.dsk BSAVE -a 0xC00 HORIZ
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
HELLO: hello.bas
|
||||||
|
$(TOKENIZE) < hello.bas > HELLO
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
HORIZ: horiz.o
|
||||||
|
ld65 -o HORIZ horiz.o -C $(LINKERSCRIPTS)/apple2_c00.inc
|
||||||
|
|
||||||
|
horiz.o: horiz.s
|
||||||
|
ca65 -o horiz.o horiz.s -l horiz.lst
|
||||||
|
|
||||||
|
####
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *~ *.o *.lst HORIZ
|
||||||
|
|
204
music/cd/horiz.s
Normal file
204
music/cd/horiz.s
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
; horizontal star wipe
|
||||||
|
|
||||||
|
; initial code = 164 bytes
|
||||||
|
|
||||||
|
GBASL = $26
|
||||||
|
GBASH = $27
|
||||||
|
BASL = $28
|
||||||
|
BASH = $29
|
||||||
|
|
||||||
|
OFFSET_POINTER = $FE
|
||||||
|
LINE = $FF
|
||||||
|
|
||||||
|
|
||||||
|
SET_GR = $C050
|
||||||
|
SET_TEXT = $C051
|
||||||
|
FULLGR = $C052
|
||||||
|
TEXTGR = $C053
|
||||||
|
PAGE0 = $C054
|
||||||
|
PAGE1 = $C055
|
||||||
|
LORES = $C056 ; Enable LORES graphics
|
||||||
|
HIRES = $C057 ; Enable HIRES graphics
|
||||||
|
|
||||||
|
PLOT = $F800 ;; PLOT AT Y,A
|
||||||
|
PLOT1 = $F80E ;; PLOT at (GBASL),Y (need MASK to be $0f or $f0)
|
||||||
|
HLINE = $F819 ;; HLINE Y,$2C at A
|
||||||
|
VLINE = $F828 ;; VLINE A,$2D at Y
|
||||||
|
CLRSCR = $F832 ;; Clear low-res screen
|
||||||
|
CLRTOP = $F836 ;; clear only top of low-res screen
|
||||||
|
GBASCALC= $F847 ;; take Y-coord/2 in A, put address in GBASL/H ( a trashed, C clear)
|
||||||
|
SETCOL = $F864 ;; COLOR=A
|
||||||
|
|
||||||
|
SETTXT = $FB36
|
||||||
|
SETGR = $FB40
|
||||||
|
|
||||||
|
BASCALC = $FBC1 ; Y-Coord in A, address in BASL/H, X,Y preserved
|
||||||
|
WAIT = $FCA8 ;; delay 1/2(26+27A+5A^2) us
|
||||||
|
|
||||||
|
|
||||||
|
;================================
|
||||||
|
; Clear screen and setup graphics
|
||||||
|
;================================
|
||||||
|
horiz:
|
||||||
|
|
||||||
|
jsr SETGR ; set lo-res 40x40 mode
|
||||||
|
bit SET_GR
|
||||||
|
bit FULLGR ; make it 40x48
|
||||||
|
|
||||||
|
lda #3
|
||||||
|
sta LINE
|
||||||
|
lda #0
|
||||||
|
sta OFFSET_POINTER
|
||||||
|
|
||||||
|
forever_loop:
|
||||||
|
|
||||||
|
lda #$0
|
||||||
|
sta OFFSET_POINTER
|
||||||
|
|
||||||
|
ldx #0
|
||||||
|
big_loop:
|
||||||
|
|
||||||
|
txa
|
||||||
|
pha
|
||||||
|
jsr BASCALC
|
||||||
|
|
||||||
|
ldy #39
|
||||||
|
ldx OFFSET_POINTER
|
||||||
|
hlin:
|
||||||
|
tya
|
||||||
|
|
||||||
|
; if signed (y>offset) && (y<endoffset) draw
|
||||||
|
; if signed (y<=offset) || (y>endoffset) don't draw
|
||||||
|
|
||||||
|
clc
|
||||||
|
sbc offsets,X
|
||||||
|
bvs gurg
|
||||||
|
eor #$80
|
||||||
|
gurg:
|
||||||
|
bpl skip_pixel ; neg if A<=offset
|
||||||
|
|
||||||
|
tya
|
||||||
|
clc
|
||||||
|
sbc endoffsets,X
|
||||||
|
bvs gurg2
|
||||||
|
eor #$80
|
||||||
|
gurg2:
|
||||||
|
bmi skip_pixel ; neg if A<=endoffset
|
||||||
|
|
||||||
|
color_smc:
|
||||||
|
lda #$3b
|
||||||
|
jmp blah ; TODO: USE BIT TRICK
|
||||||
|
skip_pixel:
|
||||||
|
lda #$0 ;
|
||||||
|
blah:
|
||||||
|
sta (BASL),Y
|
||||||
|
dey
|
||||||
|
bpl hlin
|
||||||
|
|
||||||
|
lda #$bb
|
||||||
|
sta color_smc+1
|
||||||
|
|
||||||
|
|
||||||
|
;==========================================
|
||||||
|
; draw star at beginning of line
|
||||||
|
|
||||||
|
lda offsets,X
|
||||||
|
bmi skip_star
|
||||||
|
|
||||||
|
clc
|
||||||
|
lda BASL
|
||||||
|
adc offsets,X
|
||||||
|
sta BASL
|
||||||
|
|
||||||
|
ldx LINE
|
||||||
|
|
||||||
|
ldy #7 ; 8-bits wide
|
||||||
|
lda star_bitmap-1,X ; get low bit of bitmap into carry
|
||||||
|
draw_line_loop:
|
||||||
|
lsr
|
||||||
|
|
||||||
|
pha
|
||||||
|
|
||||||
|
bcc its_transparent
|
||||||
|
|
||||||
|
lda #$ff ; white
|
||||||
|
sta (BASL),Y ; draw on screen
|
||||||
|
its_transparent:
|
||||||
|
|
||||||
|
pla
|
||||||
|
|
||||||
|
dey
|
||||||
|
bpl draw_line_loop
|
||||||
|
|
||||||
|
skip_star:
|
||||||
|
|
||||||
|
; see if new line
|
||||||
|
|
||||||
|
ldx OFFSET_POINTER
|
||||||
|
|
||||||
|
dec LINE
|
||||||
|
bne not3
|
||||||
|
|
||||||
|
lda #$b3
|
||||||
|
sta color_smc+1
|
||||||
|
|
||||||
|
dec offsets,X
|
||||||
|
dec endoffsets,X
|
||||||
|
|
||||||
|
inc OFFSET_POINTER
|
||||||
|
lda #3
|
||||||
|
sta LINE
|
||||||
|
|
||||||
|
not3:
|
||||||
|
|
||||||
|
;==========================
|
||||||
|
|
||||||
|
pla
|
||||||
|
tax
|
||||||
|
|
||||||
|
inx
|
||||||
|
cpx #24
|
||||||
|
bne big_loop
|
||||||
|
|
||||||
|
|
||||||
|
; set/flip pages
|
||||||
|
; we want to flip pages and then draw to the offscreen one
|
||||||
|
|
||||||
|
;flip_pages:
|
||||||
|
; ldx #0 ; x already 0
|
||||||
|
; lda draw_page_smc+1 ; DRAW_PAGE
|
||||||
|
;; beq done_page
|
||||||
|
; inx
|
||||||
|
;done_page:
|
||||||
|
; ldy PAGE0,X ; set display page to PAGE1 or PAGE2
|
||||||
|
; eor #$4 ; flip draw page between $400/$800
|
||||||
|
; sta draw_page_smc+1 ; DRAW_PAGE
|
||||||
|
|
||||||
|
|
||||||
|
lda #80
|
||||||
|
jsr WAIT
|
||||||
|
|
||||||
|
jmp forever_loop
|
||||||
|
|
||||||
|
|
||||||
|
offsets:
|
||||||
|
.byte 5,4,3,2,1,2,3,4,5
|
||||||
|
|
||||||
|
endoffsets:
|
||||||
|
.byte 30,20,10,20,30,40,50,12
|
||||||
|
|
||||||
|
; 76543210
|
||||||
|
; @
|
||||||
|
; @@@@@
|
||||||
|
; @ @
|
||||||
|
|
||||||
|
star_bitmap:
|
||||||
|
.byte $50
|
||||||
|
.byte $f8
|
||||||
|
.byte $20
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; for bot
|
||||||
|
|
||||||
|
jmp horiz
|
199
music/cd/horiz_bot.s
Normal file
199
music/cd/horiz_bot.s
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
; horizontal star wipe
|
||||||
|
|
||||||
|
; initial code = 164 bytes
|
||||||
|
; 163 bytes = jmp to bra
|
||||||
|
; 158 bytes = cleanup initialization
|
||||||
|
; 156 bytes = BIT trick
|
||||||
|
; 154 bytes = set offsets properly
|
||||||
|
; 151 bytes = redo init
|
||||||
|
|
||||||
|
GBASL = $26
|
||||||
|
GBASH = $27
|
||||||
|
BASL = $28
|
||||||
|
BASH = $29
|
||||||
|
|
||||||
|
OFFSET_POINTER = $FE
|
||||||
|
LINE = $FF
|
||||||
|
|
||||||
|
SET_GR = $C050
|
||||||
|
SET_TEXT = $C051
|
||||||
|
FULLGR = $C052
|
||||||
|
TEXTGR = $C053
|
||||||
|
PAGE1 = $C054
|
||||||
|
PAGE2 = $C055
|
||||||
|
LORES = $C056 ; Enable LORES graphics
|
||||||
|
HIRES = $C057 ; Enable HIRES graphics
|
||||||
|
|
||||||
|
HGR2 = $F3D8
|
||||||
|
SETTXT = $FB36
|
||||||
|
SETGR = $FB40
|
||||||
|
|
||||||
|
BASCALC = $FBC1 ; Y-Coord in A, address in BASL/H, X,Y preserved
|
||||||
|
WAIT = $FCA8 ;; delay 1/2(26+27A+5A^2) us
|
||||||
|
|
||||||
|
|
||||||
|
;================================
|
||||||
|
; Clear screen and setup graphics
|
||||||
|
;================================
|
||||||
|
horiz:
|
||||||
|
|
||||||
|
jsr SETGR ; set lo-res 40x40 mode, PAGE1
|
||||||
|
bit FULLGR ; show full screen
|
||||||
|
|
||||||
|
lda #3 ; count down from 3 to 0 each subline
|
||||||
|
sta LINE
|
||||||
|
|
||||||
|
forever_loop:
|
||||||
|
|
||||||
|
lda #$0 ; offset into the length pointers
|
||||||
|
sta OFFSET_POINTER
|
||||||
|
; A = screen line, 0..24
|
||||||
|
big_loop:
|
||||||
|
|
||||||
|
pha ; save screen line on stack
|
||||||
|
|
||||||
|
jsr BASCALC ; calculate address of line in BASL/BASH
|
||||||
|
|
||||||
|
ldy #39 ; draw 40 pixels on screen
|
||||||
|
ldx OFFSET_POINTER ; get pointer to the offsets
|
||||||
|
hlin:
|
||||||
|
tya
|
||||||
|
|
||||||
|
; if signed (y>offset) && (y<endoffset) draw
|
||||||
|
; if signed (y<=offset) || (y>endoffset) don't draw
|
||||||
|
|
||||||
|
clc
|
||||||
|
sbc offsets,X
|
||||||
|
bvs gurg
|
||||||
|
eor #$80
|
||||||
|
gurg:
|
||||||
|
bpl skip_pixel ; neg if A<=offset
|
||||||
|
|
||||||
|
tya
|
||||||
|
clc
|
||||||
|
sbc endoffsets,X
|
||||||
|
bvs gurg2
|
||||||
|
eor #$80
|
||||||
|
gurg2:
|
||||||
|
bmi skip_pixel ; neg if A<=endoffset
|
||||||
|
|
||||||
|
color_smc:
|
||||||
|
lda #$3b
|
||||||
|
.byte $2c ; bit trick, skips next two bytes
|
||||||
|
skip_pixel:
|
||||||
|
lda #$0 ; color black otherwise
|
||||||
|
blah:
|
||||||
|
sta (BASL),Y ; write out pixel
|
||||||
|
|
||||||
|
dey ; decrement Xcoord
|
||||||
|
bpl hlin ; loop until done all 40 pixels
|
||||||
|
|
||||||
|
lda #$bb ; force color to all-pink
|
||||||
|
sta color_smc+1
|
||||||
|
|
||||||
|
|
||||||
|
;==========================================
|
||||||
|
; draw star at beginning of line
|
||||||
|
|
||||||
|
lda offsets,X ; only draw if on-screen
|
||||||
|
bmi skip_star
|
||||||
|
|
||||||
|
clc ; modify x-coord
|
||||||
|
lda BASL
|
||||||
|
adc offsets,X
|
||||||
|
sta BASL
|
||||||
|
|
||||||
|
ldx LINE ; which line of bitmap to use
|
||||||
|
|
||||||
|
ldy #7 ; 8-bits wide
|
||||||
|
lda star_bitmap-1,X ; get low bit of bitmap into carry
|
||||||
|
draw_line_loop:
|
||||||
|
lsr
|
||||||
|
|
||||||
|
pha
|
||||||
|
|
||||||
|
bcc its_transparent
|
||||||
|
|
||||||
|
lda #$ff ; white
|
||||||
|
sta (BASL),Y ; draw on screen
|
||||||
|
its_transparent:
|
||||||
|
|
||||||
|
pla
|
||||||
|
|
||||||
|
dey
|
||||||
|
bpl draw_line_loop
|
||||||
|
|
||||||
|
skip_star:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ldx OFFSET_POINTER
|
||||||
|
|
||||||
|
; see if new offset (meaning, we've gone three lines)
|
||||||
|
|
||||||
|
dec LINE
|
||||||
|
bne not3
|
||||||
|
|
||||||
|
;======================
|
||||||
|
; new line
|
||||||
|
;======================
|
||||||
|
|
||||||
|
|
||||||
|
lda #$b3
|
||||||
|
sta color_smc+1 ; add shadow to (top?) of line
|
||||||
|
|
||||||
|
dec offsets,X ; scroll the line length
|
||||||
|
dec endoffsets,X
|
||||||
|
|
||||||
|
inc OFFSET_POINTER ; point to next set of offsets
|
||||||
|
|
||||||
|
lda #3 ; reset line vlue
|
||||||
|
sta LINE
|
||||||
|
|
||||||
|
not3:
|
||||||
|
|
||||||
|
;==========================
|
||||||
|
|
||||||
|
pla ; restore line count
|
||||||
|
clc
|
||||||
|
adc #1
|
||||||
|
cmp #24
|
||||||
|
; tax
|
||||||
|
|
||||||
|
; inx
|
||||||
|
; cpx #24 ; see if reached bottom
|
||||||
|
bne big_loop
|
||||||
|
|
||||||
|
|
||||||
|
; ideally we'd page flip, no room though
|
||||||
|
|
||||||
|
|
||||||
|
lda #80 ; delay a bit
|
||||||
|
jsr WAIT
|
||||||
|
|
||||||
|
beq forever_loop
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
offsets:
|
||||||
|
.byte 30,29,31,38,31,34,32,35
|
||||||
|
|
||||||
|
endoffsets:
|
||||||
|
.byte 60,50,61,68,61,64,62,65
|
||||||
|
|
||||||
|
|
||||||
|
; 76543210
|
||||||
|
; @
|
||||||
|
; @@@@@
|
||||||
|
; @ @
|
||||||
|
|
||||||
|
star_bitmap:
|
||||||
|
.byte $50
|
||||||
|
.byte $f8
|
||||||
|
.byte $20
|
||||||
|
|
||||||
|
|
||||||
|
; for bot
|
||||||
|
|
||||||
|
jmp horiz
|
Loading…
Reference in New Issue
Block a user