diff --git a/games/sb/Makefile b/games/sb/Makefile index dd70aa6c..65c860c0 100644 --- a/games/sb/Makefile +++ b/games/sb/Makefile @@ -78,7 +78,9 @@ TITLE: title.o title.o: title.s zx02_optim.s \ zp.inc hardware.inc \ - hgr_vscroll.s \ + hgr_vscroll.s audio.s \ + purple.s lc_detect.s \ + sound/purple.btc.zx02 \ graphics/czmg4ap_title.hgr.zx02 \ graphics/videlectrix_top.hgr.zx02 ca65 -o title.o title.s -l title.lst diff --git a/games/sb/audio.s b/games/sb/audio.s new file mode 100644 index 00000000..e6193a09 --- /dev/null +++ b/games/sb/audio.s @@ -0,0 +1,204 @@ +; Based on BTC.SYSTEM by Oliver Schmidt + +; How to generate proper audio for this: + +; -Open MP3 in Audacity +; -Change Project Rate (Hz) to 33,000 (bottom left box) +; -Tracks --> Mix... --> Mix Stereo Down to Mono +; -File --> Export --> Export as WAV +; - Select "WAV (Microsoft) signed 16-bit PCM" +; - Under "Edit Metadata Tags" hit "Clear", then "Okay" +; -Open saved WAV file in BTc Sound Encoder 3.0 +; -Change Algorithm to "1 bit" (leave fineness as BTc16) +; -File --> Export binary file .BTC format + + +spkr = $C030 + +;**************************************************************** +;* Audio playback * +;**************************************************************** +; audio file in BTC_L/BTC_H +; pages to play in X + + +play_audio: + ldy #0 + + ; loop here as long as BITs are [F]alse (aka 0) +F_NX: NOP ; 2 2 + NOP ; 2 2 + NOP ; 2 2 + BIT $00 ; 3 3 +F_RD: LDA (BTC_L),y ; 5 5 5 + ASL ; 2 2 2 + BCS T_1_SW ; 2/3 2 + NOP ; 2 2 + NOP ; 2 2 + NOP ; 2 2 + NOP ; 2 2 +F_1: JSR delay ; 6 (+13) 19 + ASL ; 2 2 = 31 + BCS T_2_SW ; 2/3 + NOP ; 2 + NOP ; 2 + NOP ; 2 + NOP ; 2 +F_2: JSR delay ; 6 (+13) + ASL ; 2 + BCS T_3_SW ; 2/3 + NOP ; 2 + NOP ; 2 + NOP ; 2 + NOP ; 2 +F_3: JSR delay ; 6 (+13) + ASL ; 2 + BCS T_4_SW ; 2/3 + NOP ; 2 + NOP ; 2 + NOP ; 2 + NOP ; 2 +F_4: JSR delay ; 6 (+13) + ASL ; 2 + BCS T_5_SW ; 2/3 + NOP ; 2 + NOP ; 2 + NOP ; 2 + NOP ; 2 +F_5: JSR delay ; 6 (+13) + ASL ; 2 + BCS T_6_SW ; 2/3 + NOP ; 2 + NOP ; 2 + NOP ; 2 + NOP ; 2 +F_6: JSR delay ; 6 (+13) + ASL ; 2 + BCS T_7_SW ; 2/3 + NOP ; 2 + NOP ; 2 + NOP ; 2 + NOP ; 2 +F_7: JSR delay ; 6 (+13) + ASL ; 2 + BCS T_8_SW ; 2/3 2 2 + NOP ; 2 2 2 + NOP ; 2 2 2 + NOP ; 2 2 2 + NOP ; 2 2 2 +F_8: INY ; 2 2 2 + BNE F_NX ; 2/3 3 = 31 2 + INC BTC_H ; 5 5 + DEX ; 2 2 + BNE F_RD ; 2/3 3 = 31 + RTS + ; click speaker on transitions +T_1_SW: STA spkr ; 4 [SW]itch to [T]rue on BIT [1] + BCS T_1 ; 3 (always) +T_2_SW: STA spkr ; 4 [SW]itch to [T]rue on BIT [2] + BCS T_2 ; 3 (always) +T_3_SW: STA spkr ; 4 [SW]itch to [T]rue on BIT [3] + BCS T_3 ; 3 (always) +T_4_SW: STA spkr ; 4 [SW]itch to [T]rue on BIT [4] + BCS T_4 ; 3 (always) +T_5_SW: STA spkr ; 4 [SW]itch to [T]rue on BIT [5] + BCS T_5 ; 3 (always) +T_6_SW: STA spkr ; 4 [SW]itch to [T]rue on BIT [6] + BCS T_6 ; 3 (always) +T_7_SW: STA spkr ; 4 [SW]itch to [T]rue on BIT [7] + BCS T_7 ; 3 (always) +T_8_SW: STA spkr ; 4 [SW]itch to [T]rue on BIT [8] + BCS T_8 ; 3 (always) + +F_1_SW: STA spkr ; 4 [SW]itch to [F]alse on BIT [1] + BCC F_1 ; 3 (always) +F_2_SW: STA spkr ; 4 [SW]itch to [F]alse on BIT [2] + BCC F_2 ; 3 (always) +F_3_SW: STA spkr ; 4 [SW]itch to [F]alse on BIT [3] + BCC F_3 ; 3 (always) +F_4_SW: STA spkr ; 4 [SW]itch to [F]alse on BIT [4] + BCC F_4 ; 3 (always) +F_5_SW: STA spkr ; 4 [SW]itch to [F]alse on BIT [5] + BCC F_5 ; 3 (always) +F_6_SW: STA spkr ; 4 [SW]itch to [F]alse on BIT [6] + BCC F_6 ; 3 (always) +F_7_SW: STA spkr ; 4 [SW]itch to [F]alse on BIT [7] + BCC F_7 ; 3 (always) +F_8_SW: STA spkr ; 4 [SW]itch to [F]alse on BIT [8] + BCC F_8 ; 3 (always) + + ; loop here as long as BITs are [T]rue (aka 1) +T_NX: NOP ; 2 + NOP ; 2 + NOP ; 2 + BIT $00 ; 3 +T_RD: LDA (BTC_L),y ; 5 + ASL ; 2 + BCC F_1_SW ; 2/3 + NOP ; 2 + NOP ; 2 + NOP ; 2 + NOP ; 2 +T_1: JSR delay ; 6 (+13) + ASL ; 2 + BCC F_2_SW ; 2/3 + NOP ; 2 + NOP ; 2 + NOP ; 2 + NOP ; 2 +T_2: JSR delay ; 6 (+13) + ASL ; 2 + BCC F_3_SW ; 2/3 + NOP ; 2 + NOP ; 2 + NOP ; 2 + NOP ; 2 +T_3: JSR delay ; 6 (+13) + ASL ; 2 + BCC F_4_SW ; 2/3 + NOP ; 2 + NOP ; 2 + NOP ; 2 + NOP ; 2 +T_4: JSR delay ; 6 (+13) + ASL ; 2 + BCC F_5_SW ; 2/3 + NOP ; 2 + NOP ; 2 + NOP ; 2 + NOP ; 2 +T_5: JSR delay ; 6 (+13) + ASL ; 2 + BCC F_6_SW ; 2/3 + NOP ; 2 + NOP ; 2 + NOP ; 2 + NOP ; 2 +T_6: JSR delay ; 6 (+13) + ASL ; 2 + BCC F_7_SW ; 2/3 + NOP ; 2 + NOP ; 2 + NOP ; 2 + NOP ; 2 +T_7: JSR delay ; 6 (+13) + ASL ; 2 + BCC F_8_SW ; 2/3 + NOP ; 2 + NOP ; 2 + NOP ; 2 + NOP ; 2 +T_8: INY ; 2 + BNE T_NX ; 2/3 + INC BTC_H ; 5 + DEX ; 2 + BNE T_RD ; 2/3 + RTS + +delay: + nop ; 2 + nop ; 2 + BIT $00 ; 3 + RTS ; 6 = 13 + + diff --git a/games/sb/lc_detect.s b/games/sb/lc_detect.s new file mode 100644 index 00000000..3123a6ae --- /dev/null +++ b/games/sb/lc_detect.s @@ -0,0 +1,40 @@ +; Code from TotalReplay by 4am and qkumba + +;------------------------------------------------------------------------------ +; Has64K +; Checks whether computer has functioning language card (64K) +; +; in: none +; out: C clear if 64K detected +; C set if 64K not detected +; all other flags and registers clobbered +; ROM in memory (not LC RAM bank) +;------------------------------------------------------------------------------ + +detect_language_card: + + ; enable language card + ; READ_RAM1_WRITE_RAM1 + + bit $C08B + bit $C08B + + lda #$AA ; test #1 for $D0 page + sta $D000 + eor $D000 + bne no_lc + lsr $D000 ; test #2 for $D0 page + lda #$55 + eor $D000 + bne no_lc + clc + bcc done_detect + +no_lc: + sec + +done_detect: + ; READ_ROM_NO_WRITE + bit $C08A + + rts diff --git a/games/sb/qload.s b/games/sb/qload.s index 29ee7daa..5587fb00 100644 --- a/games/sb/qload.s +++ b/games/sb/qload.s @@ -183,7 +183,7 @@ sector_array: .byte 0, 0, 0, 0 ; LEVEL8, LEVEL9, LEVEL10 length_array: - .byte 16, 16, 16, 32 ; TITLE, DUCK, SB, FN + .byte 32, 16, 16, 32 ; TITLE, DUCK, SB, FN .byte 46, 46, 46, 46 ; LEVEL4, LEVEL5, LEVEL6, LEVEL7 .byte 46, 46, 32, 32 ; LEVEL8, LEVEL9, LEVEL10 diff --git a/games/sb/sound/Makefile b/games/sb/sound/Makefile new file mode 100644 index 00000000..236264ca --- /dev/null +++ b/games/sb/sound/Makefile @@ -0,0 +1,6 @@ +ZX02 = ~/research/6502_compression/zx02.git/build/zx02 -f + +all: purple.btc.zx02 + +purple.btc.zx02: purple.btc + $(ZX02) purple.btc purple.btc.zx02 diff --git a/games/sb/sound/purple.btc b/games/sb/sound/purple.btc new file mode 100644 index 00000000..512271a4 Binary files /dev/null and b/games/sb/sound/purple.btc differ diff --git a/games/sb/title.s b/games/sb/title.s index 477f76c1..7ed4b06d 100644 --- a/games/sb/title.s +++ b/games/sb/title.s @@ -27,6 +27,47 @@ hires_start: sta HGR_PAGE jsr hgr_make_tables + + ;========================================= + ; detect if we have a language card (64k) + ; and load sound into it if possible + ;=================================== + + lda #0 + sta SOUND_STATUS ; clear out, sound enabled + + jsr detect_language_card + bcs no_language_card + +yes_language_card: + + ; update sound status + lda SOUND_STATUS + ora #SOUND_IN_LC + sta SOUND_STATUS + + ;================================== + ; load sound into the language card + ; into $D000 set 1 + ;================================== + + ; read/write RAM, use $d000 bank1 + bit $C083 + bit $C083 + + lda #purple_data + sta ZX0_src+1 + + lda #$D0 ; decompress to $D000 + + jsr full_decomp + + +no_language_card: + + ;=================== ;=================== ; scroll the logo @@ -80,8 +121,11 @@ load_title_image: jsr full_decomp -; rts + ;========================== + ; Play sound + ;=========================== + jsr play_purple wait_until_keypress: @@ -109,8 +153,14 @@ done: .include "zx02_optim.s" .include "hgr_tables.s" .include "hgr_vscroll.s" + .include "audio.s" + .include "purple.s" + .include "lc_detect.s" title_data: .incbin "graphics/czmg4ap_title.hgr.zx02" vid_top: .incbin "graphics/videlectrix_top.hgr.zx02" + +purple_data: + .incbin "sound/purple.btc.zx02" diff --git a/games/sb/zp.inc b/games/sb/zp.inc index 6565f3a1..387dcddb 100644 --- a/games/sb/zp.inc +++ b/games/sb/zp.inc @@ -39,6 +39,14 @@ FRAMEH = $61 SCROLL = $62 XSAVE = $63 SCROLL_OFFSET = $64 +BTC_L = $65 +BTC_H = $66 +SOUND_STATUS = $67 + SOUND_DISABLED = $80 + SOUND_IN_LC = $01 ; $01 sound effects in language card + SOUND_MOCKINGBOARD = $02 ; mockingboard detected + + ;WAITING = $62 ;LETTERL = $63