From bff16e6de7057aecec8dd07dd5429a8889dc1032 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 17 Jun 2022 01:24:21 -0400 Subject: [PATCH] compression_test: finally got exomizer working --- compression/comparison/exodecrunch.s | 466 ++++++++---------- compression/comparison/exodecrunch.s.old | 575 +++++++++++++++++++++++ compression/comparison/exomizer_test.s | 141 +++--- compression/comparison/lzsa_test.s | 2 +- compression/comparison/zx02_fast_test.s | 2 +- compression/comparison/zx02_opt_test.s | 2 +- compression/comparison/zx02_small_test.s | 2 +- music/cd/Makefile | 32 +- music/cd/horiz.s | 204 ++++++++ music/cd/horiz_bot.s | 199 ++++++++ 10 files changed, 1300 insertions(+), 325 deletions(-) create mode 100644 compression/comparison/exodecrunch.s.old create mode 100644 music/cd/horiz.s create mode 100644 music/cd/horiz_bot.s diff --git a/compression/comparison/exodecrunch.s b/compression/comparison/exodecrunch.s index bc1c9644..afa4dd88 100644 --- a/compression/comparison/exodecrunch.s +++ b/compression/comparison/exodecrunch.s @@ -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. ; 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 ; 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 @@ -88,65 +39,73 @@ ENABLE_SPLIT_ENCODING = 0 ; ------------------------------------------------------------------- ;.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 ; 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 +;.export decrunch + ; ------------------------------------------------------------------- -; 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. +; Controls if the shared get_bits routines should be inlined or not. +;INLINE_GET_BITS=1 ; ------------------------------------------------------------------- -.export split_gentable -.export split_decrunch -.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 +; ------------------------------------------------------------------- +; 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 ; ------------------------------------------------------------------- -zp_len_lo = $9e -zp_len_hi = $9f +zp_len_lo = $a7 +zp_len_hi = $a8 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_bits_hi = $fc 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 +.ifdef EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE encoded_entries = 68 -.ELSE +.else encoded_entries = 52 -.ENDIF +.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 +.macro mac_refill_bits pha jsr get_crunched_byte rol sta zp_bitbuf pla -.ENDMACRO +.endmacro -.MACRO mac_get_bits -.IF INLINE_GET_BITS <> 0 -.SCOPE +.ifdef INLINE_GET_BITS +.macro mac_get_bits adc #$80 ; needs c=0, affects v asl bpl gb_skip @@ -164,26 +123,11 @@ gb_get_hi: sta zp_bits_hi jsr get_crunched_byte skip: -.ENDSCOPE -.ELSE +.endmacro +.else +.macro mac_get_bits 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 +.endmacro get_bits: adc #$80 ; needs c=0, affects v asl @@ -202,7 +146,7 @@ gb_get_hi: sec sta zp_bits_hi jmp get_crunched_byte -.ENDIF +.endif ; ------------------------------------------------------------------- ; no code below this comment has to be modified in order to generate ; 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 ; call the decruncher ; 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: -.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 + +.if SHOW_PROGRESS_DURING_DECRUNCH = 1 + lda $FBB3 + cmp #$EA + bne + + lda #$A1 ; use ! instead of | for initial spinner animation + sta progress_char+1 + sta progress_char+5 ++ ; ------------------------------------------------------------------- -; calculate tables (64 bytes) + get_bits macro -; x must be #0 when entering +; show initial on-screen progress UI +; + 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 + 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 table_gen: tax @@ -271,7 +232,7 @@ rolled: bmi no_fixup_lohi lda zp_len_hi stx zp_len_hi - .BYTE $24 + .byte $24 no_fixup_lohi: txa ; ------------------------------------------------------------------- @@ -279,57 +240,60 @@ no_fixup_lohi: 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) +; copy one literal byte to destination (11(10) bytes) ; +.ifndef FORWARD_DECRUNCHING + FORWARD_DECRUNCHING = 1 +.endif +.if FORWARD_DECRUNCHING = 0 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 + +.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 - bne skip_hi_incr + bne no_hi_incr inc zp_dest_hi -.IF DONT_REUSE_OFFSET = 0 - inc zp_src_hi -.ENDIF -skip_hi_incr: -.ENDIF +no_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: @@ -349,13 +313,13 @@ nofetch8: ; check for decrunch done and literal sequences (4 bytes) ; cpx #$11 -.IF INLINE_GET_BITS <> 0 +.ifdef INLINE_GET_BITS bcc skip_jmp jmp exit_or_lit_seq skip_jmp: -.ELSE +.else bcs exit_or_lit_seq -.ENDIF +.endif ; ------------------------------------------------------------------- ; calulate length of sequence (zp_len) (18(11) bytes) + get_bits macro ; @@ -363,7 +327,7 @@ skip_jmp: 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 +.ifndef MAX_SEQUENCE_LENGTH_256 lda zp_bits_hi adc tabl_hi - 1,x ; c = 0 after this. sta zp_len_hi @@ -372,32 +336,15 @@ skip_jmp: ; z-flag reflects zp_len_hi here ; ldx zp_len_lo -.ELSE +.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 0 +.ifdef EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE cpx #$04 -.ELSE +.else cpx #$03 -.ENDIF +.endif bcs gbnc2_next lda tabl_bit - 1,x gbnc2_next: @@ -413,139 +360,144 @@ gbnc2_ok: bcs gbnc2_next 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 mac_get_bits -.IF DECRUNCH_FORWARDS = 0 +.if FORWARD_DECRUNCHING = 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 +.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 + lda zp_dest_hi + bcc skip_dest_hi + sbc #1 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) ; +pre_copy: ldx zp_len_lo ; ------------------------------------------------------------------- ; main copy loop (30 bytes) ; copy_next: -.IF DECRUNCH_FORWARDS = 0 +.if FORWARD_DECRUNCHING = 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 +.endif +.ifndef LITERAL_SEQUENCES_NOT_USED bcs get_literal_byte -.ENDIF +.endif lda (zp_src_lo),y literal_byte_gotten: sta (zp_dest_lo),y -.IF DECRUNCH_FORWARDS <> 0 +.if (FORWARD_DECRUNCHING = 1) iny bne copy_skip_hi inc zp_dest_hi inc zp_src_hi copy_skip_hi: -.ENDIF +.endif dex bne copy_next -.IF MAX_SEQUENCE_LENGTH_256 = 0 +.ifndef MAX_SEQUENCE_LENGTH_256 lda zp_len_hi -.IF INLINE_GET_BITS <> 0 +.ifdef INLINE_GET_BITS bne copy_next_hi -.ENDIF -.ENDIF +.endif +.endif +begin_stx: stx zp_bits_hi -.IF INLINE_GET_BITS = 0 +.ifndef INLINE_GET_BITS beq next_round -.ELSE +.else jmp next_round -.ENDIF -.IF MAX_SEQUENCE_LENGTH_256 = 0 +.endif +.ifndef MAX_SEQUENCE_LENGTH_256 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 +.endif +.ifndef LITERAL_SEQUENCES_NOT_USED +get_literal_byte: 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 + bcs literal_byte_gotten +.endif ; ------------------------------------------------------------------- ; exit or literal sequence handling (16(12) bytes) ; exit_or_lit_seq: -.IF LITERAL_SEQUENCES_NOT_USED = 0 +.ifndef LITERAL_SEQUENCES_NOT_USED beq decr_exit jsr get_crunched_byte -.IF MAX_SEQUENCE_LENGTH_256 = 0 +.ifndef MAX_SEQUENCE_LENGTH_256 sta zp_len_hi -.ENDIF +.endif jsr get_crunched_byte tax bcs copy_next decr_exit: -.ENDIF +.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 +.ifdef EXTRA_TABLE_ENTRY_FOR_LENGTH_THREE ; ------------------------------------------------------------------- ; 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 + .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 + .byte $8c, $e2 +.endif +.if SHOW_PROGRESS_DURING_DECRUNCH = 1 +progress_index: + .byte $00 +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 -.ENDIF +.endif ; ------------------------------------------------------------------- ; end of decruncher ; ------------------------------------------------------------------- @@ -554,22 +506,22 @@ split_init_zp: ; 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 +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 +;;.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 +;;.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 ; ------------------------------------------------------------------- diff --git a/compression/comparison/exodecrunch.s.old b/compression/comparison/exodecrunch.s.old new file mode 100644 index 00000000..bc1c9644 --- /dev/null +++ b/compression/comparison/exodecrunch.s.old @@ -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 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 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 +; ------------------------------------------------------------------- diff --git a/compression/comparison/exomizer_test.s b/compression/comparison/exomizer_test.s index dde21784..19f0f7fd 100644 --- a/compression/comparison/exomizer_test.s +++ b/compression/comparison/exomizer_test.s @@ -1,79 +1,98 @@ -; ------------------------------------------------------------------- -; this file is intended to be assembled and linked with the cc65 toolchain. -; 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 +.include "zp.inc" +.include "hardware.inc" -; .byte $01,$08,$0b,$08,<2003,>2003,$9e,'2','0','6','1',0,0,0 -; ------------------------------------------------------------------- -; we begin here -; ------------------------------------------------------------------- +exomizer_test: - lda #$20 - sta zp_dest_hi - lda #$00 - sta zp_dest_lo + bit SET_GR + bit PAGE1 + bit HIRES + bit FULLGR - -.IF DECRUNCH_FORWARDS = 0 - lda $04 - sta _byte_lo - lda $05 - sta _byte_hi -.ELSE - lda #end_of_data + lda #>data_begin sta _byte_hi -; lda $02 - ; sta _byte_lo - ; lda $03 - ; sta _byte_hi -.ENDIF - jsr decrunch + jsr decrunch + +.if 0 + +; 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 +; 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: jmp end -; ------------------------------------------------------------------- + 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_hi = * + 2 - lda $ffff ; needs to be set correctly before - -.IF DECRUNCH_FORWARDS <> 0 - inc _byte_lo - bne _byte_skip_hi - inc _byte_hi + lda $1234 ; needs to be set correctly before + ; decrunch_file is called. + inc _byte_lo + bne _byte_skip_hi + inc _byte_hi _byte_skip_hi: -.ENDIF - rts ; decrunch_file is called. -; end_of_data needs to point to the address just after the address -; of the last byte of crunched data. -; ------------------------------------------------------------------- + rts + +start_d: .include "exodecrunch.s" -.incbin "level5.exo" -end_of_data: +data_begin: +.byte $20,$00 +.incbin "level5.exo" +data_end: diff --git a/compression/comparison/lzsa_test.s b/compression/comparison/lzsa_test.s index f28c0433..708d6ff8 100644 --- a/compression/comparison/lzsa_test.s +++ b/compression/comparison/lzsa_test.s @@ -4,7 +4,7 @@ lzsa_test: bit SET_GR - bit PAGE0 + bit PAGE1 bit HIRES bit FULLGR diff --git a/compression/comparison/zx02_fast_test.s b/compression/comparison/zx02_fast_test.s index 9a69cf0e..f26f8f64 100644 --- a/compression/comparison/zx02_fast_test.s +++ b/compression/comparison/zx02_fast_test.s @@ -4,7 +4,7 @@ lzsa_test: bit SET_GR - bit PAGE0 + bit PAGE1 bit HIRES bit FULLGR diff --git a/compression/comparison/zx02_opt_test.s b/compression/comparison/zx02_opt_test.s index 38b0f0c4..f37efb68 100644 --- a/compression/comparison/zx02_opt_test.s +++ b/compression/comparison/zx02_opt_test.s @@ -4,7 +4,7 @@ lzsa_test: bit SET_GR - bit PAGE0 + bit PAGE1 bit HIRES bit FULLGR diff --git a/compression/comparison/zx02_small_test.s b/compression/comparison/zx02_small_test.s index 4f23fcfd..67550c30 100644 --- a/compression/comparison/zx02_small_test.s +++ b/compression/comparison/zx02_small_test.s @@ -4,7 +4,7 @@ lzsa_test: bit SET_GR - bit PAGE0 + bit PAGE1 bit HIRES bit FULLGR diff --git a/music/cd/Makefile b/music/cd/Makefile index 9ea2e2ed..9234dbce 100644 --- a/music/cd/Makefile +++ b/music/cd/Makefile @@ -1,5 +1,31 @@ -all: +include ../../Makefile.inc -clean: - rm -f *~ +DOS33 = ../../utils/dos33fs-utils/dos33 +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 diff --git a/music/cd/horiz.s b/music/cd/horiz.s new file mode 100644 index 00000000..5004102b --- /dev/null +++ b/music/cd/horiz.s @@ -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) && (yendoffset) 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 diff --git a/music/cd/horiz_bot.s b/music/cd/horiz_bot.s new file mode 100644 index 00000000..982ed55b --- /dev/null +++ b/music/cd/horiz_bot.s @@ -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) && (yendoffset) 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