diff --git a/games/mist_hgr/Makefile b/games/mist_hgr/Makefile new file mode 100644 index 00000000..2c7802e2 --- /dev/null +++ b/games/mist_hgr/Makefile @@ -0,0 +1,523 @@ +include ../../Makefile.inc + +DOS33 = ../../utils/dos33fs-utils/dos33 +DOS33_RAW = ../../utils/dos33fs-utils/dos33_raw +PNG_TO_40x96 = ../../utils/gr-utils/png_to_40x96 +PNG_TO_40x48D = ../../utils/gr-utils/png_to_40x48d +PNG2RLE = ../../utils/gr-utils/png2rle +B2D = ../../utils/bmp2dhr/b2d + +TOKENIZE = ../../utils/asoft_basic-utils/tokenize_asoft + + +all: mist_hgr.dsk +# mist_side2.dsk mist_side3.dsk + +#zip: mist_hgr.dsk mist_side2.dsk mist_side3.dsk +# zip mist.zip mist_hgr.dsk mist_side2.dsk mist_side3.dsk + +mist_hgr.dsk: QBOOT TEXT_TITLE QLOAD \ + MIST_TITLE MIST OCTAGON VIEWER \ + DENTIST D\'NI SHIP GENERATOR \ + SAVE1 SAVE2 SAVE3 SAVE4 SAVE5 + cp extra_empty.dsk mist_hgr.dsk + $(DOS33_RAW) mist_hgr.dsk 0 0 QBOOT 0 1 + $(DOS33_RAW) mist_hgr.dsk 0 2 QBOOT 1 1 + $(DOS33_RAW) mist_hgr.dsk 0 4 QBOOT 2 1 + $(DOS33_RAW) mist_hgr.dsk 0 6 TEXT_TITLE 0 3 + $(DOS33_RAW) mist_hgr.dsk 0 11 SAVE1 0 1 + $(DOS33_RAW) mist_hgr.dsk 0 12 SAVE2 0 1 + $(DOS33_RAW) mist_hgr.dsk 0 13 SAVE3 0 1 + $(DOS33_RAW) mist_hgr.dsk 0 14 SAVE4 0 1 + $(DOS33_RAW) mist_hgr.dsk 0 15 SAVE5 0 1 + $(DOS33_RAW) mist_hgr.dsk 1 0 QLOAD 0 14 + $(DOS33_RAW) mist_hgr.dsk 2 0 MIST_TITLE 0 84 +# $(DOS33_RAW) mist_hgr.dsk 8 0 MIST 0 159 +# $(DOS33_RAW) mist_hgr.dsk 18 0 OCTAGON 0 128 +# $(DOS33_RAW) mist_hgr.dsk 26 0 DENTIST 0 31 +# $(DOS33_RAW) mist_hgr.dsk 28 0 D\'NI 0 27 +# $(DOS33_RAW) mist_hgr.dsk 30 0 SHIP 0 20 +# $(DOS33_RAW) mist_hgr.dsk 31 8 VIEWER 0 20 +# $(DOS33_RAW) mist_hgr.dsk 32 13 GENERATOR 0 33 + + +#mist_side2.dsk: WBOOT2 CHANNEL ARBOR NIBEL CABIN +# cp extra_empty.dsk mist_side2.dsk +# $(DOS33_RAW) mist_side2.dsk 0 0 WBOOT2 0 1 +# $(DOS33_RAW) mist_side2.dsk 1 0 CHANNEL 0 135 +# $(DOS33_RAW) mist_side2.dsk 10 0 ARBOR 0 159 +# $(DOS33_RAW) mist_side2.dsk 20 0 NIBEL 0 109 +# $(DOS33_RAW) mist_side2.dsk 27 0 CABIN 0 61 + +#mist_side3.dsk: WBOOT3 MECHE SELENA STONEY SUB +# cp extra_empty.dsk mist_side3.dsk +# $(DOS33_RAW) mist_side3.dsk 0 0 WBOOT3 0 1 +# $(DOS33_RAW) mist_side3.dsk 1 0 MECHE 0 157 +# $(DOS33_RAW) mist_side3.dsk 11 0 STONEY 0 158 +# $(DOS33_RAW) mist_side3.dsk 21 0 SELENA 0 145 +# $(DOS33_RAW) mist_side3.dsk 30 1 SUB 0 78 + +### + +#WBOOT2: wrong_boot2.o +# ld65 -o WBOOT2 wrong_boot2.o -C ../../linker_scripts/apple2_800.inc + +#wrong_boot2.o: wrong_boot2.s +# ca65 -o wrong_boot2.o wrong_boot2.s -l wrong_boot2.lst + +### + +#WBOOT3: wrong_boot3.o +# ld65 -o WBOOT3 wrong_boot3.o -C ../../linker_scripts/apple2_800.inc + +#wrong_boot3.o: wrong_boot3.s +# ca65 -o wrong_boot3.o wrong_boot3.s -l wrong_boot3.lst + + +### + +QBOOT: qboot_sector.o + ld65 -o QBOOT qboot_sector.o -C ../../linker_scripts/apple2_800.inc + +qboot_sector.o: qboot_sector.s qboot_stage2.s + ca65 -o qboot_sector.o qboot_sector.s -l qboot_sector.lst + +### + +TEXT_TITLE: text_title.o + ld65 -o TEXT_TITLE text_title.o -C ../../linker_scripts/apple2_800.inc + +text_title.o: text_title.s text_print.s wait_a_bit.s + ca65 -o text_title.o text_title.s -l text_title.lst + + +### + +QLOAD: qload.o + ld65 -o QLOAD qload.o -C ../../linker_scripts/apple2_1200.inc + +qload.o: qload.s qboot.inc \ + gr_copy.s gr_offsets.s gr_pageflip.s gr_putsprite_crop.s \ + text_print.s gr_fast_clear.s decompress_fast_v2.s \ + keyboard.s draw_pointer.s end_level.s audio.s loadstore.s \ + qkumba_popwr.s + ca65 -o qload.o qload.s -l qload.lst + + +### + +LOADER: loader.o + ld65 -o LOADER loader.o -C ../../linker_scripts/apple2_1000.inc + +loader.o: loader.s \ + gr_copy.s gr_offsets.s gr_pageflip.s gr_putsprite_crop.s \ + text_print.s gr_fast_clear.s decompress_fast_v2.s \ + keyboard.s draw_pointer.s end_level.s audio.s loadstore.s \ + qkumba_popwr.s + ca65 -o loader.o loader.s -l loader.lst + +### + +SAVE1: save1.o + ld65 -o SAVE1 save1.o -C ../../linker_scripts/apple2_e00.inc + +save1.o: save1.s + ca65 -o save1.o save1.s -l save1.lst + +### + +SAVE2: save2.o + ld65 -o SAVE2 save2.o -C ../../linker_scripts/apple2_e00.inc + +save2.o: save2.s + ca65 -o save2.o save2.s -l save2.lst + +### + +SAVE3: save3.o + ld65 -o SAVE3 save3.o -C ../../linker_scripts/apple2_e00.inc + +save3.o: save3.s + ca65 -o save3.o save3.s -l save3.lst + +### + +SAVE4: save4.o + ld65 -o SAVE4 save4.o -C ../../linker_scripts/apple2_e00.inc + +save4.o: save4.s + ca65 -o save4.o save4.s -l save4.lst + +### + +SAVE5: save5.o + ld65 -o SAVE5 save5.o -C ../../linker_scripts/apple2_e00.inc + +save5.o: save5.s + ca65 -o save5.o save5.s -l save5.lst + +#### + +generate_common: generate_common.o + $(CC) $(LFLAGS) -o generate_common generate_common.o + +generate_common.o: generate_common.c + $(CC) $(CFLAGS) -c generate_common.c + +#### + +common_routines.inc: qload.lst generate_common + ./generate_common > common_routines.inc + +#### + +MIST_TITLE: mist_title.o + ld65 -o MIST_TITLE mist_title.o -C ../../linker_scripts/apple2_4000.inc + +mist_title.o: mist_title.s zp.inc hardware.inc common_defines.inc \ + common_routines.inc \ + graphics_title_hgr/mist_title.lzsa graphics_title/title_graphics.inc \ + gr_copy.s gr_offsets.s gr_pageflip.s gr_putsprite_crop.s \ + text_print.s gr_fast_clear.s decompress_fast_v2.s \ + keyboard.s draw_pointer.s end_level.s audio.s \ + init_state.s wait_a_bit.s \ + link_book_mist_dock.s common_sprites.inc leveldata_title.inc \ + pt3_lib_core.s pt3_lib_init.s pt3_lib_mockingboard_detect.s \ + pt3_lib_mockingboard_setup.s pt3_lib_irq_handler.s interrupt_handler.s + ca65 -o mist_title.o mist_title.s -l mist_title.lst + +#### + +MIST: mist.o + ld65 -o MIST mist.o -C ./apple2_2000.inc + +mist.o: mist.s zp.inc hardware.inc common_defines.inc common_routines.inc \ + graphics_mist/mist_graphics.inc \ + common_sprites.inc \ + leveldata_mist.inc \ + clock_bridge_puzzle.s clock_sprites.inc \ + marker_switch.s \ + keyboard.s \ + draw_pointer.s \ + end_level.s \ + mist_puzzles.s \ + handle_pages.s + ca65 -o mist.o mist.s -l mist.lst + +#### + +GENERATOR: generator.o + ld65 -o GENERATOR generator.o -C ./apple2_2000.inc + +generator.o: generator.s zp.inc hardware.inc \ + common_defines.inc common_routines.inc \ + graphics_generator/generator_graphics.inc \ + leveldata_generator.inc \ + generator_puzzle.s + ca65 -o generator.o generator.s -l generator.lst + + +#### + +OCTAGON: octagon.o + ld65 -o OCTAGON octagon.o -C ./apple2_2000.inc + +octagon.o: octagon.s zp.inc hardware.inc common_defines.inc \ + common_routines.inc \ + graphics_octagon/octagon_graphics.inc \ + books/octagon_books.inc \ + common_sprites.inc page_sprites.inc \ + leveldata_octagon.inc \ + brother_books.s \ + handle_pages.s \ + octagon_bookshelf.s \ + octagon_rotation.s \ + octagon_fireplace.s + ca65 -o octagon.o octagon.s -l octagon.lst + +#### + +D\'NI: dni.o + ld65 -o D\'NI dni.o -C ./apple2_2000.inc + +dni.o: dni.s zp.inc hardware.inc common_defines.inc \ + common_routines.inc \ + graphics_dni/dni_graphics.inc \ + leveldata_dni.inc \ + dni_ending.s + ca65 -o dni.o dni.s -l dni.lst + + + +#### + +MECHE: meche.o + ld65 -o MECHE meche.o -C ./apple2_2000.inc + +meche.o: meche.s zp.inc hardware.inc common_defines.inc \ + common_routines.inc \ + graphics_meche/meche_graphics.inc \ + common_sprites.inc \ + page_sprites.inc \ + leveldata_meche.inc \ + link_book_meche.s \ + link_book_mist.s \ + meche_rotation.s \ + handle_pages.s \ + keyboard.s \ + draw_pointer.s \ + gr_copy.s audio.s text_print.s decompress_fast_v2.s + ca65 -o meche.o meche.s -l meche.lst + +#### + +SELENA: selena.o + ld65 -o SELENA selena.o -C ./apple2_2000.inc + +selena.o: selena.s zp.inc hardware.inc common_defines.inc \ + common_routines.inc \ + graphics_selena/selena_graphics.inc \ + common_sprites.inc \ + leveldata_selena.inc \ + link_book_mist.s \ + end_level.s \ + keyboard.s \ + draw_pointer.s \ + speaker_beeps.s \ + selena_organ_puzzle.s selena_sound_puzzle.s \ + gr_copy.s audio.s text_print.s decompress_fast_v2.s + ca65 -o selena.o selena.s -l selena.lst + +#### + +SUB: sub.o + ld65 -o SUB sub.o -C ./apple2_2000.inc + +sub.o: sub.s zp.inc hardware.inc common_defines.inc \ + common_routines.inc \ + graphics_sub/sub_graphics.inc \ + common_sprites.inc \ + leveldata_sub.inc \ + link_book_mist.s \ + end_level.s \ + keyboard.s \ + draw_pointer.s \ + sub_puzzle.s \ + gr_copy.s audio.s text_print.s decompress_fast_v2.s + ca65 -o sub.o sub.s -l sub.lst + +#### + +VIEWER: viewer.o + ld65 -o VIEWER viewer.o -C ./apple2_2000.inc + +viewer.o: viewer.s zp.inc hardware.inc common_defines.inc \ + graphics_viewer/viewer_graphics.inc \ + common_routines.inc \ + common_sprites.inc \ + page_sprites.inc \ + number_sprites.inc \ + leveldata_viewer.inc \ + viewer_controls.s \ + keyboard.s \ + draw_pointer.s \ + gr_copy.s audio.s text_print.s decompress_fast_v2.s + ca65 -o viewer.o viewer.s -l viewer.lst + +#### + +STONEY: stoney.o + ld65 -o STONEY stoney.o -C ./apple2_2000.inc + +stoney.o: stoney.s zp.inc hardware.inc common_defines.inc \ + graphics_stoney/stoney_graphics.inc \ + common_routines.inc \ + common_sprites.inc \ + page_sprites.inc \ + leveldata_stoney.inc \ + keyboard.s \ + draw_pointer.s \ + link_book_stoney.s \ + link_book_mist.s \ + handle_pages.s \ + hlin_list.s \ + lights_off.s stoney_puzzles.s + ca65 -o stoney.o stoney.s -l stoney.lst + +#### + +SHIP: ship.o + ld65 -o SHIP ship.o -C ./apple2_2000.inc + +ship.o: ship.s zp.inc hardware.inc common_defines.inc \ + graphics_ship/ship_graphics.inc \ + common_routines.inc \ + common_sprites.inc \ + page_sprites.inc \ + leveldata_ship.inc \ + keyboard.s \ + draw_pointer.s \ + link_book_stoney.s \ + link_book_mist.s \ + handle_pages.s \ + gr_copy.s audio.s text_print.s decompress_fast_v2.s + ca65 -o ship.o ship.s -l ship.lst + +#### + +CABIN: cabin.o + ld65 -o CABIN cabin.o -C ./apple2_2000.inc + +cabin.o: cabin.s zp.inc hardware.inc common_defines.inc \ + common_routines.inc \ + graphics_cabin/cabin_graphics.inc \ + common_sprites.inc \ + page_sprites.inc \ + leveldata_cabin.inc \ + keyboard.s \ + draw_pointer.s \ + link_book_channel.s \ + marker_switch.s \ + cabin_boiler_puzzle.s \ + number_sprites.inc + ca65 -o cabin.o cabin.s -l cabin.lst + + +#### + +CHANNEL: channel.o + ld65 -o CHANNEL channel.o -C ./apple2_2000.inc + +channel.o: channel.s zp.inc hardware.inc common_defines.inc \ + common_routines.inc \ + graphics_channel/channel_graphics.inc \ + common_sprites.inc \ + page_sprites.inc \ + leveldata_channel.inc \ + channel_switches.s \ + keyboard.s \ + draw_pointer.s \ + link_book_channel.s \ + link_book_mist.s \ + gr_copy.s audio.s text_print.s decompress_fast_v2.s + ca65 -o channel.o channel.s -l channel.lst + +#### + +ARBOR: arbor.o + ld65 -o ARBOR arbor.o -C ./apple2_2000.inc + +arbor.o: arbor.s zp.inc hardware.inc common_defines.inc \ + common_routines.inc \ + graphics_arbor/arbor_graphics.inc \ + leveldata_arbor.inc \ + arbor_switches.s + ca65 -o arbor.o arbor.s -l arbor.lst + +#### + +NIBEL: nibel.o + ld65 -o NIBEL nibel.o -C ./apple2_2000.inc + +nibel.o: nibel.s zp.inc hardware.inc common_defines.inc \ + common_routines.inc \ + graphics_nibel/nibel_graphics.inc \ + leveldata_nibel.inc \ + handle_pages.s nibel_switches.s + ca65 -o nibel.o nibel.s -l nibel.lst + +#### + +DENTIST: dentist.o + ld65 -o DENTIST dentist.o -C ./apple2_2000.inc + +dentist.o: dentist.s zp.inc hardware.inc common_defines.inc \ + common_routines.inc \ + graphics_dentist/dentist_graphics.inc \ + leveldata_dentist.inc \ + dentist_panel.s \ + marker_switch.s + ca65 -o dentist.o dentist.s -l dentist.lst + + +#### + +graphics_title/title_graphics.inc: + cd graphics_title && make + +graphics_mist/mist_graphics.inc: + cd graphics_mist && make + +graphics_octagon/octagon_graphics.inc: + cd graphics_octagon && make + +books/octagon_books.inc: + cd books && make + +graphics_viewer/viewer_graphics.inc: + cd graphics_viewer && make + +graphics_meche/meche_graphics.inc: + cd graphics_meche && make + +graphics_selena/selena_graphics.inc: + cd graphics_selena && make + +graphics_cabin/cabin_graphics.inc: + cd graphics_cabin && make + +graphics_channel/channel_graphics.inc: + cd graphics_channel && make + +graphics_stoney/stoney_graphics.inc: + cd graphics_stoney && make + +graphics_dentist/dentist_graphics.inc: + cd graphics_dentist && make + +graphics_generator/generator_graphics.inc: + cd graphics_generator && make + +graphics_arbor/arbor_graphics.inc: + cd graphics_arbor && make + +graphics_nibel/nibel_graphics.inc: + cd graphics_nibel && make + +graphics_dni/dni_graphics.inc: + cd graphics_dni && make + +graphics_ship/ship_graphics.inc: + cd graphics_ship && make + +graphics_sub/sub_graphics.inc: + cd graphics_sub && make + + +#### + +clean: + rm -f *~ *.o *.lst HELLO HELLO_DISK2 \ + LOADER MIST_TITLE \ + MIST OCTAGON VIEWER DENTIST \ + MECHE SELENA SHIP STONEY CHANNEL ARBOR NIBEL \ + GENERATOR \ + generate_common + cd graphics_title && make clean + cd graphics_mist && make clean + cd graphics_octagon && make clean + cd books && make clean + cd graphics_viewer && make clean + cd graphics_meche && make clean + cd graphics_selena && make clean + cd graphics_cabin && make clean + cd graphics_channel && make clean + cd graphics_stoney && make clean + cd graphics_dentist && make clean + cd graphics_generator && make clean + cd graphics_arbor && make clean + cd graphics_nibel && make clean + cd graphics_dni && make clean + cd graphics_ship && make clean + cd graphics_sub && make clean + diff --git a/games/mist_hgr/audio.s b/games/mist_hgr/audio.s new file mode 100644 index 00000000..e6193a09 --- /dev/null +++ b/games/mist_hgr/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/mist_hgr/decompress_fast_v2.s b/games/mist_hgr/decompress_fast_v2.s new file mode 100644 index 00000000..fb2f24ad --- /dev/null +++ b/games/mist_hgr/decompress_fast_v2.s @@ -0,0 +1,370 @@ +; note -- modified by Vince Weaver to assemble with ca65 +; in this case, A = page to decompress to +; getsrc_smc+1, getsrc_smc+2 is src location + +; ----------------------------------------------------------------------------- +; Decompress raw LZSA2 block. +; Create one with lzsa -r -f2 +; +; in: +; * LZSA_SRC_LO and LZSA_SRC_HI contain the compressed raw block address +; * LZSA_DST_LO and LZSA_DST_HI contain the destination buffer address +; +; out: +; * LZSA_DST_LO and LZSA_DST_HI contain the last decompressed byte address, +1 +; +; ----------------------------------------------------------------------------- +; Backward decompression is also supported, use lzsa -r -b -f2 +; To use it, also define BACKWARD_DECOMPRESS=1 before including this code! +; +; in: +; * LZSA_SRC_LO/LZSA_SRC_HI must contain the address of the last byte of compressed data +; * LZSA_DST_LO/LZSA_DST_HI must contain the address of the last byte of the destination buffer +; +; out: +; * LZSA_DST_LO/LZSA_DST_HI contain the last decompressed byte address, -1 +; +; ----------------------------------------------------------------------------- +; +; Copyright (C) 2019 Emmanuel Marty, Peter Ferrie +; +; 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 source distribution. +; ----------------------------------------------------------------------------- + +;NIBCOUNT = $FC ; zero-page location for temp offset + +decompress_lzsa2_fast: + + sta LZSA_DST_HI + + ldy #$00 + sty LZSA_DST_LO + sty NIBCOUNT + +decode_token: + jsr getsrc ; read token byte: XYZ|LL|MMM + pha ; preserve token on stack + + and #$18 ; isolate literals count (LL) + beq no_literals ; skip if no literals to copy + cmp #$18 ; LITERALS_RUN_LEN_V2? + bcc prepare_copy_literals ; if less, count is directly embedded in token + + jsr getnibble ; get extra literals length nibble + ; add nibble to len from token + adc #$02 ; (LITERALS_RUN_LEN_V2) minus carry + cmp #$12 ; LITERALS_RUN_LEN_V2 + 15 ? + bcc prepare_copy_literals_direct ; if less, literals count is complete + + jsr getsrc ; get extra byte of variable literals count + ; the carry is always set by the CMP above + ; GETSRC doesn't change it + sbc #$EE ; overflow? + jmp prepare_copy_literals_direct + +prepare_copy_literals_large: + ; handle 16 bits literals count + ; literals count = directly these 16 bits + jsr getlargesrc ; grab low 8 bits in X, high 8 bits in A + tay ; put high 8 bits in Y + bcs prepare_copy_literals_high ; (*same as JMP PREPARE_COPY_LITERALS_HIGH but shorter) + +prepare_copy_literals: + lsr ; shift literals count into place + lsr + lsr + +prepare_copy_literals_direct: + tax + bcs prepare_copy_literals_large ; if so, literals count is large + +prepare_copy_literals_high: + txa + beq copy_literals + iny + +copy_literals: + jsr getput ; copy one byte of literals + dex + bne copy_literals + dey + bne copy_literals + +no_literals: + pla ; retrieve token from stack + pha ; preserve token again + asl + bcs repmatch_or_large_offset ; 1YZ: rep-match or 13/16 bit offset + + asl ; 0YZ: 5 or 9 bit offset + bcs offset_9_bit + + ; 00Z: 5 bit offset + + ldx #$FF ; set offset bits 15-8 to 1 + + jsr getcombinedbits ; rotate Z bit into bit 0, read nibble for bits 4-1 + ora #$E0 ; set bits 7-5 to 1 + bne got_offset_lo ; go store low byte of match offset and prepare match + +offset_9_bit: ; 01Z: 9 bit offset + ;;asl ; shift Z (offset bit 8) in place + rol + rol + and #$01 + eor #$FF ; set offset bits 15-9 to 1 + bne got_offset_hi ; go store high byte, read low byte of match offset and prepare match + ; (*same as JMP GOT_OFFSET_HI but shorter) + +repmatch_or_large_offset: + asl ; 13 bit offset? + bcs repmatch_or_16bit ; handle rep-match or 16-bit offset if not + + ; 10Z: 13 bit offset + + jsr getcombinedbits ; rotate Z bit into bit 8, read nibble for bits 12-9 + adc #$DE ; set bits 15-13 to 1 and substract 2 (to substract 512) + bne got_offset_hi ; go store high byte, read low byte of match offset and prepare match + ; (*same as JMP GOT_OFFSET_HI but shorter) + +repmatch_or_16bit: ; rep-match or 16 bit offset + ;;ASL ; XYZ=111? + bmi rep_match ; reuse previous offset if so (rep-match) + + ; 110: handle 16 bit offset + jsr getsrc ; grab high 8 bits +got_offset_hi: + tax + jsr getsrc ; grab low 8 bits +got_offset_lo: + sta OFFSLO ; store low byte of match offset + stx OFFSHI ; store high byte of match offset + +rep_match: +.ifdef BACKWARD_DECOMPRESS + + ; Backward decompression - substract match offset + + sec ; add dest + match offset + lda putdst+1 ; low 8 bits +OFFSLO = *+1 + sbc #$AA + sta copy_match_loop+1 ; store back reference address + lda putdst+2 +OFFSHI = *+1 + sbc #$AA ; high 8 bits + sta copy_match_loop+2 ; store high 8 bits of address + sec + +.else + + ; Forward decompression - add match offset + + clc ; add dest + match offset + lda putdst+1 ; low 8 bits +OFFSLO = *+1 + adc #$AA + sta copy_match_loop+1 ; store back reference address +OFFSHI = *+1 + lda #$AA ; high 8 bits + adc putdst+2 + sta copy_match_loop+2 ; store high 8 bits of address +.endif + + pla ; retrieve token from stack again + and #$07 ; isolate match len (MMM) + adc #$01 ; add MIN_MATCH_SIZE_V2 and carry + cmp #$09 ; MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2? + bcc prepare_copy_match ; if less, length is directly embedded in token + + jsr getnibble ; get extra match length nibble + ; add nibble to len from token + adc #$08 ; (MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2) minus carry + cmp #$18 ; MIN_MATCH_SIZE_V2 + MATCH_RUN_LEN_V2 + 15? + bcc prepare_copy_match ; if less, match length is complete + + jsr getsrc ; get extra byte of variable match length + ; the carry is always set by the CMP above + ; GETSRC doesn't change it + sbc #$E8 ; overflow? + +prepare_copy_match: + tax + bcc prepare_copy_match_y ; if not, the match length is complete + beq decompression_done ; if EOD code, bail + + ; Handle 16 bits match length + jsr getlargesrc ; grab low 8 bits in X, high 8 bits in A + tay ; put high 8 bits in Y + +prepare_copy_match_y: + txa + beq copy_match_loop + iny + +copy_match_loop: + lda $AAAA ; get one byte of backreference + jsr putdst ; copy to destination + +.ifdef BACKWARD_DECOMPRESS + + ; Backward decompression -- put backreference bytes backward + + lda copy_match_loop+1 + beq getmatch_adj_hi +getmatch_done: + dec copy_match_loop+1 + +.else + + ; Forward decompression -- put backreference bytes forward + + inc copy_match_loop+1 + beq getmatch_adj_hi +getmatch_done: + +.endif + + dex + bne copy_match_loop + dey + bne copy_match_loop + jmp decode_token + +.ifdef BACKWARD_DECOMPRESS + +getmatch_adj_hi: + dec copy_match_loop+2 + jmp getmatch_done + +.else + +getmatch_adj_hi: + inc copy_match_loop+2 + jmp getmatch_done +.endif + +getcombinedbits: + eor #$80 + asl + php + + jsr getnibble ; get nibble into bits 0-3 (for offset bits 1-4) + plp ; merge Z bit as the carry bit (for offset bit 0) +combinedbitz: + rol ; nibble -> bits 1-4; carry(!Z bit) -> bit 0 ; carry cleared +decompression_done: + rts + +getnibble: +NIBBLES = *+1 + lda #$AA + lsr NIBCOUNT + bcc need_nibbles + and #$0F ; isolate low 4 bits of nibble + rts + +need_nibbles: + inc NIBCOUNT + jsr getsrc ; get 2 nibbles + sta NIBBLES + lsr + lsr + lsr + lsr + sec + rts + +.ifdef BACKWARD_DECOMPRESS + + ; Backward decompression -- get and put bytes backward + +getput: + jsr getsrc +putdst: +LZSA_DST_LO = *+1 +LZSA_DST_HI = *+2 + sta $AAAA + lda putdst+1 + beq putdst_adj_hi + dec putdst+1 + rts + +putdst_adj_hi: + dec putdst+2 + dec putdst+1 + rts + +getlargesrc: + jsr getsrc ; grab low 8 bits + tax ; move to X + ; fall through grab high 8 bits + +getsrc: +LZSA_SRC_LO = *+1 +LZSA_SRC_HI = *+2 + lda $AAAA + pha + lda getsrc+1 + beq getsrc_adj_hi + dec getsrc+1 + pla + rts + +getsrc_adj_hi: + dec getsrc+2 + dec getsrc+1 + pla + rts + +.else + + ; Forward decompression -- get and put bytes forward + +getput: + jsr getsrc +putdst: +LZSA_DST_LO = *+1 +LZSA_DST_HI = *+2 + sta $AAAA + inc putdst+1 + beq putdst_adj_hi + rts + +putdst_adj_hi: + inc putdst+2 + rts + +getlargesrc: + jsr getsrc ; grab low 8 bits + tax ; move to X + ; fall through grab high 8 bits + +getsrc: +getsrc_smc: +LZSA_SRC_LO = *+1 +LZSA_SRC_HI = *+2 + lda $AAAA + inc getsrc+1 + beq getsrc_adj_hi + rts + +getsrc_adj_hi: + inc getsrc+2 + rts +.endif + diff --git a/games/mist_hgr/gr_fast_clear.s b/games/mist_hgr/gr_fast_clear.s new file mode 100644 index 00000000..76035a21 --- /dev/null +++ b/games/mist_hgr/gr_fast_clear.s @@ -0,0 +1,201 @@ +;clear_screens: +; ;=================================== +; ; Clear top/bottom of page 0 +; ;=================================== +; +; lda #$0 +; sta DRAW_PAGE +; jsr clear_top +; jsr clear_bottom + +; ;=================================== +; ; Clear top/bottom of page 1 +; ;=================================== +; +; lda #$4 +; sta DRAW_PAGE +; jsr clear_top +; jsr clear_bottom +; +; rts + + + + + ;========================================================= + ; clear_top + ;========================================================= + ; clear DRAW_PAGE + ; original = 14,558 cycles(?) 15ms, 70Hz + ; OPTIMIZED MAX (page0,48rows): 45*120+4+6 = 5410 = 5.4ms 185Hz + ; (pageX,40rows): 50*120+4+6 = 6010 = 6.0ms 166Hz + ; 50*120+4+6+37 = 6055 = 6.0ms 166Hz +clear_top: + lda #0 ; 2 +clear_top_a: + sta COLOR ; 3 + clc ; 2 + lda DRAW_PAGE ; 3 + + adc #4 ; 2 + sta __ctf+2 ; 3 + sta __ctf+5 ; 3 + adc #1 ; 2 + sta __ctf+8 ; 3 + sta __ctf+11 ; 3 + adc #1 ; 2 + sta __ctf2+2 ; 3 + sta __ctf2+5 ; 3 + adc #1 ; 2 + sta __ctf2+8 ; 3 + sta __ctf2+11 ; 3 + + + ldy #120 ; 2 + lda COLOR ; 3 +clear_top_fast_loop: +__ctf: + sta $400,Y ; 5 + sta $480,Y ; 5 + sta $500,Y ; 5 + sta $580,Y ; 5 + + cpy #80 ; 2 + bpl no_draw_bottom ; 2nt/3 +__ctf2: + sta $600,Y ; 5 + sta $680,Y ; 5 + sta $700,Y ; 5 + sta $780,Y ; 5 +no_draw_bottom: + + dey ; 2 + bpl clear_top_fast_loop ; 2nt/3 + + rts ; 6 + + + + + ;========================================================= + ; clear_bottom + ;========================================================= + ; clear bottom of draw page + +clear_bottom: + clc ; 2 + lda DRAW_PAGE ; 3 + + adc #6 ; 2 + sta __cbf2+2 ; 3 + sta __cbf2+5 ; 3 + adc #1 ; 2 + sta __cbf2+8 ; 3 + sta __cbf2+11 ; 3 + + + ldy #120 ; 2 + lda #$a0 ; Normal Space ; 2 +clear_bottom_fast_loop: +__cbf2: + sta $600,Y ; 5 + sta $680,Y ; 5 + sta $700,Y ; 5 + sta $780,Y ; 5 + + dey ; 2 + cpy #80 ; 2 + bpl clear_bottom_fast_loop ; 2nt/3 + + rts ; 6 + + +;clear_screens_notext: + ;=================================== + ; Clear top/bottom of page 0 + ;=================================== + +; lda #$0 +; sta DRAW_PAGE +; jsr clear_all + + ;=================================== + ; Clear top/bottom of page 1 + ;=================================== + +; lda #$4 +; sta DRAW_PAGE +; jsr clear_all + +; rts + + +clear_bottoms: + + lda DRAW_PAGE + pha + + ;=================================== + ; Clear bottom of page 0 + ;=================================== + + lda #$0 + sta DRAW_PAGE + jsr clear_bottom + + ;=================================== + ; Clear bottom of page 1 + ;=================================== + + lda #$4 + sta DRAW_PAGE + jsr clear_bottom + + pla + sta DRAW_PAGE + + rts + + + ;========================================================= + ; clear_all + ;========================================================= + ; clear 48 rows + +clear_all: + clc ; 2 + lda DRAW_PAGE ; 3 + + adc #4 ; 2 + sta __caf+2 ; 3 + sta __caf+5 ; 3 + adc #1 ; 2 + sta __caf+8 ; 3 + sta __caf+11 ; 3 + adc #1 ; 2 + sta __caf2+2 ; 3 + sta __caf2+5 ; 3 + adc #1 ; 2 + sta __caf2+8 ; 3 + sta __caf2+11 ; 3 + + + ldy #120 ; 2 +clear_all_color: + lda #' '|$80 ; 2 +clear_all_fast_loop: +__caf: + sta $400,Y ; 5 + sta $480,Y ; 5 + sta $500,Y ; 5 + sta $580,Y ; 5 +__caf2: + sta $600,Y ; 5 + sta $680,Y ; 5 + sta $700,Y ; 5 + sta $780,Y ; 5 + + dey ; 2 + bpl clear_all_fast_loop ; 2nt/3 + + rts ; 6 diff --git a/games/mist_hgr/gr_offsets.s b/games/mist_hgr/gr_offsets.s new file mode 100644 index 00000000..d3af91f7 --- /dev/null +++ b/games/mist_hgr/gr_offsets.s @@ -0,0 +1,5 @@ +gr_offsets: + .word $400,$480,$500,$580,$600,$680,$700,$780 + .word $428,$4a8,$528,$5a8,$628,$6a8,$728,$7a8 + .word $450,$4d0,$550,$5d0,$650,$6d0,$750,$7d0 + diff --git a/games/mist_hgr/hardware.inc b/games/mist_hgr/hardware.inc new file mode 100644 index 00000000..905b8dd8 --- /dev/null +++ b/games/mist_hgr/hardware.inc @@ -0,0 +1,98 @@ +;; HARDWARE LOCATIONS + +KEYPRESS = $C000 +KEYRESET = $C010 + +;; SOFT SWITCHES +CLR80COL = $C000 ; PAGE0/PAGE1 normal +SET80COL = $C001 ; PAGE0/PAGE1 switches PAGE0 in Aux instead +EIGHTYCOLOFF = $C00C +EIGHTYCOLON = $C00D +TBCOLOR = $C022 ; IIgs text foreground / background colors +NEWVIDEO = $C029 ; IIgs graphics modes +SPEAKER = $C030 +CLOCKCTL = $C034 ; bits 0-3 are IIgs border color +SET_GR = $C050 +SET_TEXT = $C051 +FULLGR = $C052 +TEXTGR = $C053 +PAGE0 = $C054 +PAGE1 = $C055 +LORES = $C056 ; Enable LORES graphics +HIRES = $C057 ; Enable HIRES graphics +AN3 = $C05E ; Annunciator 3 + + + + + + + +PADDLE_BUTTON0 = $C061 +PADDL0 = $C064 +PTRIG = $C070 + +;; BASIC ROUTINES + +NORMAL = $F273 + +;; MONITOR ROUTINES + +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 +SETCOL = $F864 ;; COLOR=A +ROM_TEXT2COPY = $F962 ;; iigs +TEXT = $FB36 +TABV = $FB5B ;; VTAB to A +ROM_MACHINEID = $FBB3 ;; iigs +BELL = $FBDD ;; ring the bell +BASCALC = $FBC1 ;; +VTAB = $FC22 ;; VTAB to CV +HOME = $FC58 ;; Clear the text screen +WAIT = $FCA8 ;; delay 1/2(26+27A+5A^2) us +CROUT1 = $FD8B +SETINV = $FE80 ;; INVERSE +SETNORM = $FE84 ;; NORMAL +COUT = $FDED ;; output A to screen +COUT1 = $FDF0 ;; output A to screen + + + + + + + +COLOR_BLACK = 0 +COLOR_RED = 1 +COLOR_DARKBLUE = 2 +COLOR_PURPLE = 3 +COLOR_DARKGREEN = 4 +COLOR_GREY = 5 +COLOR_MEDIUMBLUE = 6 +COLOR_LIGHTBLUE = 7 +COLOR_BROWN = 8 +COLOR_ORANGE = 9 +COLOR_GREY2 = 10 +COLOR_PINK = 11 +COLOR_LIGHTGREEN = 12 +COLOR_YELLOW = 13 +COLOR_AQUA = 14 +COLOR_WHITE = 15 + +COLOR_BOTH_BLACK = $00 +COLOR_BOTH_RED = $11 +COLOR_BOTH_DARKBLUE = $22 +COLOR_BOTH_DARKGREEN = $44 +COLOR_BOTH_GREY = $55 +COLOR_BOTH_MEDIUMBLUE = $66 +COLOR_BOTH_LIGHTBLUE = $77 +COLOR_BOTH_BROWN = $88 +COLOR_BOTH_ORANGE = $99 +COLOR_BOTH_PINK = $BB +COLOR_BOTH_LIGHTGREEN = $CC +COLOR_BOTH_YELLOW = $DD +COLOR_BOTH_AQUA = $EE +COLOR_BOTH_WHITE = $FF + diff --git a/games/mist_hgr/joystick.s b/games/mist_hgr/joystick.s new file mode 100644 index 00000000..751fd039 --- /dev/null +++ b/games/mist_hgr/joystick.s @@ -0,0 +1,46 @@ +; Oliver Schmidt +; comp.sys.apple2.programmer + +; Call with joystick number (0 or 1) in A. +; Results are stored in value0 and value1. +; UPPER_THRESHOLD is the paddle value you want to consider as "right enough" / +; "down enough". + +UPPER_THRESHOLD = 128 + +;PTRIG = $c070 +PADDL1 = $C065 + +handle_joystick: + lda #0 + + ; Read both paddles simultaneously + asl ; Joystick number -> paddle number + tax + ldy #$00 + sty value0 + sty value1 + lda PTRIG ; Trigger paddles +loop: lda PADDL0,x ; Read paddle (0 or 2) + bmi set0 ; Cycles: 2 3 + nop ; Cycles: 2 + bpl nop0 ; Cycles: 3 +set0: sty value0 ; Cycles: 4 +nop0: ; - - + ; Cycles: 7 7 + lda PADDL1,x ; Read paddle (1 or 3) + bmi set1 ; Cycles: 2 3 + nop ; Cycles: 2 + bpl nop1 ; Cycles: 3 +set1: sty value1 ; Cycles: 4 +nop1: ; - - + ; Cycles: 7 7 + iny + cpy #UPPER_THRESHOLD+1 + bne loop + + rts + +value0: .byte $00 +value1: .byte $00 + diff --git a/games/mist_hgr/keyboard.s b/games/mist_hgr/keyboard.s new file mode 100644 index 00000000..a796f1f5 --- /dev/null +++ b/games/mist_hgr/keyboard.s @@ -0,0 +1,435 @@ + + ;============================== + ; Handle Keypress + ;============================== +handle_keypress: + + ; first handle joystick + lda JOYSTICK_ENABLED + beq actually_handle_keypress + + ; only check joystick every-other frame + lda FRAMEL + and #$1 + beq actually_handle_keypress + +check_button: + lda PADDLE_BUTTON0 + bpl button_clear + + lda JS_BUTTON_STATE + bne js_check + + lda #1 + sta JS_BUTTON_STATE + lda #' ' + jmp check_sound + +button_clear: + lda #0 + sta JS_BUTTON_STATE + +js_check: + jsr handle_joystick + +js_check_left: + lda value0 + cmp #$20 + bcs js_check_right ; if less than 32, left + lda #'A' + bne check_sound + +js_check_right: + cmp #$40 + bcc js_check_up + lda #'D' + bne check_sound + +js_check_up: + lda value1 + cmp #$20 + bcs js_check_down + lda #'W' + + bne check_sound + +js_check_down: + cmp #$40 + bcc done_joystick + lda #'S' + bne check_sound + + +done_joystick: + + + +actually_handle_keypress: + lda KEYPRESS + bmi keypress + + jmp no_keypress + +keypress: + and #$7f ; clear high bit + cmp #' ' + beq check_sound ; make sure not to lose space + and #$df ; convert uppercase to lower case + +check_sound: + cmp #$14 ; control-T + bne check_joystick + + lda SOUND_STATUS + eor #SOUND_DISABLED + sta SOUND_STATUS + jmp done_keypress + + ; can't be ^J as that's the same as down +check_joystick: +; cmp #$10 ; control-P + cmp #'J' + bne check_load + + lda JOYSTICK_ENABLED + eor #1 + sta JOYSTICK_ENABLED + jmp done_keypress + +check_load: + cmp #$C ; control-L + bne check_save + + jsr load_game + jmp done_keypress + +check_save: + cmp #$13 ; control-S + bne check_left + + jsr save_game + jmp done_keypress + +check_left: + cmp #'A' + beq left_pressed + cmp #8 ; left key + bne check_right +left_pressed: + lda CURSOR_X ; if 41linking_noise + sta BTC_H + ldx #LINKING_NOISE_LENGTH ; 45 pages long??? + jsr play_audio + + ; restore rom, no write, $d000 bank 1 + + bit $c08A + +done_link_noise: + rts diff --git a/games/mist_hgr/loadstore.s b/games/mist_hgr/loadstore.s new file mode 100644 index 00000000..bdbf6a9c --- /dev/null +++ b/games/mist_hgr/loadstore.s @@ -0,0 +1,203 @@ + + ;=================================== + ;=================================== + ; load the game + ;=================================== + ;=================================== +load_game: + + lda #load_message + sta OUTH + + jsr confirm_slot + + bcs done_load + + ; actually load it + clc + adc #LOAD_SAVE1 + sta WHICH_LOAD + + jsr load_file + + ; copy to zero page + + ldx #0 +load_loop: + lda $e00,X + sta WHICH_LOAD,X + inx + cpx #(END_OF_SAVE-WHICH_LOAD+1) + bne load_loop + + lda #$ff + sta LEVEL_OVER + +done_load: + + bit SET_GR ; turn graphics back on + + rts + + ;=================================== + ;=================================== + ; save the game + ;=================================== + ;=================================== + +save_game: + + lda #save_message + sta OUTH + + jsr confirm_slot + + bcs done_save + + pha + + + ;======================== + ; actually save +actually_save: + + ;=============================== + ; first load something from + ; disk1/track0 to seek the head there + + lda WHICH_LOAD + pha + + lda #LOAD_SAVE1 + sta WHICH_LOAD + jsr load_file + + pla + sta WHICH_LOAD + + ; copy save data to $d00 + + ldx #0 +copy_loop: + lda WHICH_LOAD,X + sta $d00,X + inx + cpx #(END_OF_SAVE-WHICH_LOAD+1) + bne copy_loop + + ; spin up disk + jsr driveon + + ; actually save it + pla + clc + adc #11 + sta requested_sector+1 + + jsr sector_write + + jsr driveoff + +done_save: + + jsr change_location ; restore graphics + + rts + + + + + + + ;================================ + ; confirm and get slot number + ;================================ + ; call with first message in OUTL/OUTH + ; return: carry set if skipping + +confirm_slot: + + bit KEYRESET ; clear keyboard buffer + + ;=============================== + ; print "are you sure" message + + bit SET_TEXT ; set text mode + + lda #' '|$80 + sta clear_all_color+1 + jsr clear_all ; clear screen + + jsr move_and_print + + lda #are_you_sure + sta OUTH + jsr move_and_print + +; jsr page_flip + +wait_confirmation: + lda KEYPRESS + bpl wait_confirmation + + bit KEYRESET ; clear keypress + + and #$7f + cmp #'Y' + bne dont_do_it + + ;=============================== + ; print "Which one?" + + jsr clear_all ; clear screen + + lda #which_message + sta OUTH + jsr move_and_print + +; jsr page_flip + +which_slot: + lda KEYPRESS + bpl which_slot + + bit KEYRESET ; clear keypress + + and #$7f + sec + sbc #'1' + + bmi dont_do_it + cmp #5 + bcs dont_do_it + + clc + rts + +dont_do_it: + sec + rts + + +which_message: +.byte 9,5,"WHICH SLOT (1-5)?",0 + +load_message: +.byte 10,5,"LOAD GAME FROM DISK",0 + +save_message: +.byte 11,5,"SAVE GAME TO DISK",0 + +are_you_sure: +.byte 10,7,"ARE YOU SURE? (Y/N)",0 + +;save_filename: +;.byte "SAVE0",0 diff --git a/games/mist_hgr/log_table.s b/games/mist_hgr/log_table.s new file mode 100644 index 00000000..4113412e --- /dev/null +++ b/games/mist_hgr/log_table.s @@ -0,0 +1,5 @@ +log2_table: + ; 0 1 2 3 4 5 6 7 8 + .byte 0,0,1,1,2,2,2,2,3 + + diff --git a/games/mist_hgr/mist_title.s b/games/mist_hgr/mist_title.s new file mode 100644 index 00000000..71013e7a --- /dev/null +++ b/games/mist_hgr/mist_title.s @@ -0,0 +1,676 @@ +; Mist Title + +; loads a HGR version of the title +; also handles the initial link to mist + +; by deater (Vince Weaver) + +; Zero Page + .include "zp.inc" + .include "hardware.inc" + .include "common_defines.inc" + .include "common_routines.inc" + +mist_start: + + ;=================== + ; detect model + ;=================== + + jsr detect_appleii_model + + ;=================== + ; machine workarounds + ;=================== + ; mostly IIgs + ;=================== + ; thanks to 4am who provided this code from Total Replay + + lda ROM_MACHINEID + cmp #$06 + bne not_a_iigs + sec + jsr $FE1F ; check for IIgs + bcs not_a_iigs + + ; gr/text page2 handling broken on early IIgs models + ; this enables the workaround + + jsr ROM_TEXT2COPY ; set alternate display mode on IIgs + cli ; enable VBL interrupts + + ; also set background color to black instead of blue + lda NEWVIDEO + and #%00011111 ; bit 7 = 0 -> IIgs Apple II-compat video modes + ; bit 6 = 0 -> IIgs 128K memory map same as IIe + ; bit 5 = 0 -> IIgs DHGR is color, not mono + ; bits 0-4 unchanged + sta NEWVIDEO + lda #$F0 + sta TBCOLOR ; white text on black background + lda #$00 + sta CLOCKCTL ; black border + sta CLOCKCTL ; set twice for VidHD + +not_a_iigs: + + ;=================== + ; print config + ;=================== + + ; print non-inverse + jsr set_normal + + lda #config_string + sta OUTH + + jsr move_and_print + + ; print detected model + + lda APPLEII_MODEL + ora #$80 + sta $7d0+8 ; 23,8 + + ; if GS print the extra S + cmp #'G'|$80 + bne not_gs + lda #'S'|$80 + sta $7d0+9 + +not_gs: + + ;=================================== + ; detect if we have a language card + ; 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 status + lda #'6'|$80 + sta $7d0+11 ; 23,11 + lda #'4'|$80 + sta $7d0+12 ; 23,12 + + ; update sound status + lda SOUND_STATUS + ora #SOUND_IN_LC + sta SOUND_STATUS + + ; load sounds into LC + + ; read ram, write ram, use $d000 bank1 + bit $C08B + bit $C08B + + lda #linking_noise_compressed + sta getsrc_smc+2 + + lda #$D0 ; decompress to $D000 + + jsr decompress_lzsa2_fast + +blah: + + ; read rom, nowrite, use $d000 bank1 + bit $C08A + +no_language_card: + + ;=================================== + ; Setup Mockingboard + ;=================================== + +PT3_ENABLE_APPLE_IIC = 1 + + lda #0 + sta DONE_PLAYING + sta LOOP + + ; detect mockingboard + jsr mockingboard_detect + + bcc mockingboard_notfound + +mockingboard_found: + + ; print detected location + + lda MB_ADDR_H ; $C4 = 4, want $B4 1100 -> 1011 + and #$87 + ora #$30 + + sta $7d0+39 ; 23,39 + + jsr mockingboard_patch ; patch to work in slots other than 4? + + lda SOUND_STATUS + ora #SOUND_MOCKINGBOARD + sta SOUND_STATUS + + ;======================= + ; Set up 50Hz interrupt + ;======================== + + jsr mockingboard_init + jsr mockingboard_setup_interrupt + + ;============================ + ; Init the Mockingboard + ;============================ + + jsr reset_ay_both + jsr clear_ay_both + + ;================== + ; init song + ;================== + + jsr pt3_init_song + + jmp done_setup_sound + + +mockingboard_notfound: + + +done_setup_sound: + + + ;========================== + ; wait a bit at text title + ;========================== + + lda #$40 + jsr wait_a_bit + + ;=================== + ; setup HGR + ;=================== + + ; we could just call HGR2 here instead? + + bit SET_GR + bit PAGE0 + bit HIRES + bit FULLGR + + ;=================== + ; setup location + ;=================== + + lda #locations + sta LOCATIONS_H + + ;=================== + ; Load hires graphics + ;=================== +reload_everything: + + lda #file + sta getsrc_smc+2 ; LZSA_SRC_HI + + lda #$20 + + jsr decompress_lzsa2_fast + + ;=================================== + ; Do Intro Sequence + ;=================================== + + ; SKIP: broderbund logo (w music) + ; SKIP: cyan logo (with cyan theme) + + + ; wait a bit at MYST screen + + lda #50 + jsr wait_a_bit + + + + ;=================== + ; init screen + ;=================== + + jsr TEXT + jsr HOME + bit KEYRESET + + bit SET_GR + bit PAGE0 + bit LORES + bit FULLGR + + lda #0 + sta DRAW_PAGE + + ;=================================== + ; M Y S T letters + ;=================================== + ; missing the dramatic music + ; they should spin in, and letters are made of fire + + ; M + ldx #m_title_m_lzsa + lda #4 + jsr draw_and_wait + + ; Y + ldx #m_title_y_lzsa + lda #4 + jsr draw_and_wait + + ; S + ldx #m_title_s_lzsa + lda #4 + jsr draw_and_wait + + ; T + ldx #m_title_t_lzsa + lda #25 + jsr draw_and_wait + + ;=================================== + ; FISSURE: I realized the moment... + ;=================================== + ; touch linking book as fissure pulses + + bit TEXTGR ; split text/gr + + ldx #fissure_lzsa + lda #50 + jsr draw_and_wait + + + ;=================================== + ; FISSURE_BOOK_SMALL: starry expanse... + ;=================================== + + ldx #fissure_book_small_lzsa + lda #50 + jsr draw_and_wait + + ;=================================== + ; FISSURE_BOOK_BIG: I have tried to speculate... + ;=================================== + + ldx #fissure_book_big_lzsa + lda #50 + jsr draw_and_wait + + ;=================================== + ; FALLING_LEFT: Still, the question... + ;=================================== + + ldx #falling_left_lzsa + lda #50 + jsr draw_and_wait + + ;=================================== + ; FALLING_RIGHT: I know my aprehensions... + ;=================================== + + ldx #falling_right_lzsa + lda #50 + jsr draw_and_wait + + ;=================================== + ; BOOK_AIR : The ending... + ;=================================== + + ldx #book_air_lzsa + lda #15 + jsr draw_and_wait + + ;=================================== + ; BOOK_SPARKS : has not yet... + ;=================================== + + ldx #book_sparks_lzsa + lda #15 + jsr draw_and_wait + + ;=================================== + ; BOOK_GLOW : been written... + ;=================================== + + ldx #book_glow_lzsa + lda #15 + jsr draw_and_wait + + ;=================================== + ; BOOK_GROUND : + ;=================================== + + ldx #book_ground_lzsa + lda #50 + jsr draw_and_wait + + +done_intro: + + ; restore to full screen (no text) + + bit FULLGR + bit LORES + + ; init cursor + + lda #20 + sta CURSOR_X + sta CURSOR_Y + + lda #0 + sta LEVEL_OVER + + ;============================ + ; init vars + + jsr init_state + + ;============================ + ; set up initial location + + lda #TITLE_BOOK_GROUND + sta LOCATION ; start at first room + + lda #DIRECTION_N + sta DIRECTION + + jsr change_location + + lda #1 + sta CURSOR_VISIBLE ; visible at first + +game_loop: + ;================= + ; reset things + ;================= + + lda #0 + sta IN_SPECIAL + sta IN_RIGHT + sta IN_LEFT + + ;==================================== + ; copy background to current page + ;==================================== + + jsr gr_copy_to_current + + ;==================================== + ; handle special-case forground logic + ;==================================== + + ; handle animated linking book + lda LOCATION + cmp #TITLE_BOOK_OPEN + bne nothing_special + + lda ANIMATE_FRAME + cmp #32 ; if done animating, skip + bcs nothing_special + +animate_ocean: + cmp #26 + bcs animate_actual + + and #1 + beq even_ocean + +odd_ocean: + lda #dock_animate_sprite1 + jmp draw_animation +even_ocean: + lda #dock_animate_sprite2 + jmp draw_animation + +animate_actual: + sec + sbc #26 + asl + tay + + ; slow down animation + lda #$3f + sta if_smc+1 + + lda dock_animation_sprites,Y + sta INL + lda dock_animation_sprites+1,Y + +draw_animation: + + sta INH + lda #24 + sta XPOS + lda #12 + sta YPOS + jsr put_sprite_crop + +inc_frame: + lda FRAMEL +if_smc: + and #$f + bne done_inc_frame + + inc ANIMATE_FRAME + +done_inc_frame: + +nothing_special: + + ;==================================== + ; draw pointer + ;==================================== + + jsr draw_pointer + + ;==================================== + ; page flip + ;==================================== + + jsr page_flip + + ;==================================== + ; handle keypress/joystick + ;==================================== + + jsr handle_keypress + + + ;==================================== + ; inc frame count + ;==================================== + + inc FRAMEL + bne room_frame_no_oflo + inc FRAMEH +room_frame_no_oflo: + + ;==================================== + ; check level over + ;==================================== + + lda LEVEL_OVER + bne really_exit + jmp game_loop + +really_exit: + jmp end_level + + + ;========================== + ; includes + ;========================== + + + .include "init_state.s" + + .include "graphics_title/title_graphics.inc" + + .include "lc_detect.s" + + ; puzzles + + ; linking books + + .include "link_book_mist_dock.s" + + .include "common_sprites.inc" + + .include "leveldata_title.inc" + + + ; pt3 player + .include "pt3_lib_detect_model.s" + .include "pt3_lib_core.s" + .include "pt3_lib_init.s" + .include "pt3_lib_mockingboard_setup.s" + .include "interrupt_handler.s" + .include "pt3_lib_mockingboard_detect.s" + + + + .include "wait_a_bit.s" + + +file: +.incbin "graphics_title_hgr/mist_title.lzsa" + +linking_noise_compressed: +.incbin "audio/link_noise.btc.lzsa" + + + ;==================================== + ; draw a screen and wait + ;==================================== + ; X = low of lzsa + ; Y = high of lzsa + ; A = pause delay + +draw_and_wait: + pha + stx getsrc_smc+1 + sty getsrc_smc+2 + lda #$c ; load to page $c00 + jsr decompress_lzsa2_fast + + jsr gr_copy_to_current + + jsr page_flip + pla + jsr wait_a_bit + rts + + +get_mist_book: + + ; play music if mockingboard + + lda SOUND_STATUS + and #SOUND_MOCKINGBOARD + beq skip_start_music + cli +skip_start_music: + + lda #TITLE_BOOK_CLOSED + sta LOCATION + jmp change_location + + +PT3_LOC = theme_music + +.align $100 +theme_music: +.incbin "audio/theme.pt3" + + + + +.if 0 + + +; click on book, plays theme + + + + + +; FISSURE: I realized the momemnt + +; 1 2 3 +; 0123456789012345678901234567890123456789 +.byte " I REALIZED, THE MOMENT I FELL INTO THE" +.byte " FISSURE, THAT THE BOOK WOULD NOT BE" +.byte " DESTROYED AS I HAD PLANNED." + +; FISSURE_BOOK: _starry expanse (book tiny) + +; 0123456789012345678901234567890123456789 +.byte " IT CONTINUED FALLING INTO THAT STARRY" +.byte " EXPANSE OF WHICH I HAD ONLY A" +.byte " FLEETING GLIMPSE." + +; FALLING_BOOK: (book big) falling by starscape (I have tried to speculate) + +; 0123456789012345678901234567890123456789 +.byte "I HAVE TRIED TO SPECULATE WHERE IT MIGHT" +.byte " HAVE LANDED, BUT I MUST ADMIT," +.byte " HOWEVER-- SUCH CONJECTURE IS FUTILE." + +; FALLING_LEFT (still, the question) /(left) +; 0123456789012345678901234567890123456789 +.byte " STILL, THE QUESTION ABOUT WHOSE HANDS" +.byte " MIGHT SOMEDAY HOLD MY MYST BOOK ARE" +.byte " UNSETTLING TO ME." + +; FALLING_RIGHT I know my aprehensions (right) +; 0123456789012345678901234567890123456789 +.byte " I KNOW THAT MY APPREHENSIONS MIGHT" +.byte " NEVER BE ALLAYED, AND SO I CLOSE," +.byte " REALIZING THAT PERHAPS," + +; BOOK_GROUND the ending has not yet been written (falls, blue sparks) +; 0123456789012345678901234567890123456789 +.byte " THE ENDING HAS NOT YET BEEN WRITTEN" + + +.endif + +config_string: +; 0123456789012345678901234567890123456789 +.byte 0,23,"APPLE II?, 48K RAM, MOCKINGBOARD: SLOT ?",0 +; MOCKINGBOARD: NONE diff --git a/games/mist_hgr/qboot_sector.s b/games/mist_hgr/qboot_sector.s new file mode 100644 index 00000000..2b3901b1 --- /dev/null +++ b/games/mist_hgr/qboot_sector.s @@ -0,0 +1,244 @@ +; fast seek/multi-read +; copyright (c) Peter Ferrie 2015-16 + + ; Paramaters for loading QLOAD + + sectors = 14 ; user-defined + firsttrk = 1 ; user-defined, first track to read + firstsec = 0 ; user-defined, first sector to read + address = $12 ; user-defined + entry = $1200 ; user-defined + version = 1 + + ;memory usage: + ;256 bytes ($200-2ff) static table + grouped = $200 + + ; stay away from interrupt vectors at $3fe !!! + + ;106 bytes ($300-369) static table + preshift = $300 + zvalue = $fd ; only during init + znibble = $fe ; only during init + zmask = $ff ; only during init + + WHICH_SLOT = $DA + +; $26/$27 sector read location (ROM) +; $3D sector number (ROM) + + +; at entry (at least on AppleWin) A=1, X=60 (slot<<4), Y=0 +; qkumba says cffa cards leave Y at $10 +; 26/27 = 00/09 +; 3D = 1 + + ; For Disk II booting, the firmware loads track0/sector0 + ; to $800 and then jumps to $801 + +.org $800 + .byte 1 ; number of sectors for ROM to load + +boot_entry: + ; this code loads two sectors up to $10/$11 + + ; assume A=1 coming in here + + lsr ; check sector number + ; A=0, carry=1 + tay ; Y=0 + adc #$0f ; A=$10 (destintation) + + sta $27 ; set or update address as needed + cmp #$12 + ; 10 11 12 (1 1 1) + ; be, bf, c0 (1011 1011 1100) + ; so if hit $c000 we are done + + beq done_load_2 ; branch if loaded 2 + + inc $3d ; increment sector (faster to find) + + ; call to the read routine in proper slot + ; using rts to jump indirect to + ; $CX5C + + ; this routine reads sector in $3D on track in $41 + ; to address in $26/$27 + ; when it's done it jumps back to $801 + stx WHICH_SLOT ; save for later + + txa ; x is slot# << 4 + lsr + lsr + lsr + lsr + ora #$c0 ; slot to PROM base + pha + lda #$5b ;read-1 + pha + rts ; return used to call $CX5C in DISK II ROM + +done_load_2: + + ; patch self modifying code for Q6L read + + txa + ora #$8c ; slot to Q6L + ; Q6L? + ; if slot 6, after this A is $EC + ; Y should be 2 here +patch_loop: + iny + ldx patchtbl-3, Y + sta code_begin, X ; replace placeholders with Q6L + ; BE02 = EC? lda c0ec + ; so sets to c08c (Q6L) + + bne patch_loop + + ; patch self-modifying code for turning motor off + + and #$f8 ; MOTOROFF (c088) -> c0e8 + sta slotpatch7+1 + + ; patch self-modifying code for turning motor on + clc + adc #1 ; MOTORON (c089) -> c0e9 + sta slotpatch9+1 + + ; patch self-modifying code for phase off + + eor #9 ; PHASEOFF (c080) + sta slotpatch8+1 + + ldx #$3f + stx zmask + inx + ldy #$7f + + bne skip_ahead ; branch always + + ; pad with zeros until $839 + ; $839 is the entry point + ; adjusts address at $8FE to be entry point + ; jumps to boot 2 +;.res $839-* + +; lda #>(entry-1) +; pha +; lda #<(entry-1) +; pha +; jsr preread +; jmp $1000 ; stage2 entry point + +patchtbl: + .byte <(slotpatch1+1), <(slotpatch2+1), <(slotpatch3+1) + .byte <(slotpatch4+1), <(slotpatch5+1), <(slotpatch6+1) +indextbl: ;the 0 also terminates the patchtbl list! + .byte 0, 2, 1, 3 + + + ;construct denibbilisation table + ;pre-shifted for interleave read + +skip_ahead: +loopaa: + sty znibble + tya + asl + bit znibble + beq loopz + ora znibble + eor #$ff + and #$7e +loopa: + bcs loopz + lsr + bne loopa + dex + txa + asl + asl + sta preshift-$16, Y +loopz: + dey + bne loopaa + + ;construct 2-bit group table + + sty zvalue +loopbb: + lsr zmask + lsr zmask +loopb: + lda indextbl, X + sta grouped, Y + inc zvalue + lda zvalue + and zmask + bne loopy + inx + txa + and #3 + tax +loopy: + iny + iny + iny + iny + cpy #3 + bcs loopb + iny + cpy #3 + bcc loopbb + lda #>(entry-1) + pha + lda #<(entry-1) + pha + jsr preread + + ; seek backward support +; sty startsec+1 +; sta tmpadr+1 +; stx total+1 + + jmp seekread + +preread: + +;copy post-read if necessary +;push post-read address here +; pla +; tax +; pla +; tay +; lda #>(postread-1) +; pha +; lda #<(postread-1) +; pha +; tya +; pha +; txa +; pha + + lda #<(firsttrk*2) + sta phase+1 + ldx #sectors + lda #address + ldy #firstsec + rts + + + +end_code: + +.res $8fe-* + +; traditionally, entry point to jump to at end of loading +; $1000 in this case +;*=$8fe + .byte $10, $00 + + +.include "qboot_stage2.s" diff --git a/games/mist_hgr/qboot_stage2.s b/games/mist_hgr/qboot_stage2.s new file mode 100644 index 00000000..ce9ec270 --- /dev/null +++ b/games/mist_hgr/qboot_stage2.s @@ -0,0 +1,363 @@ +; the following lives on sectors $0E and $0D +; why? +; request sector 2 and 4, and the interleave is + +; beneath apple dos (3-23) +; Physical (firmware) : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +; DOS33 mapping : 0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15 + + +; Beneath Apple DOS +; p86 (dos reference) +; + +WAIT = $FCA8 ;; delay 1/2(26+27A+5A^2) us + +.org $1000 + +code_begin: + + .byte version + +readnib: +slotpatch1: ; smc + lda $c0d1 ; gets set to C08C (Q6L) read + bpl readnib + rts + + ;fill address array for one track +seekread: + sty startsec+1 + sta tmpadr+1 + stx total+1 + +inittrk: + sec + lda #$10 + sbc startsec+1 + cmp total+1 + bcs it_skip + + tax + +it_skip: + stx partial1 + stx partial2 + jsr seek + +startsec: + ldy #$d1 + +tmpadr: +tmpadr_loop: + lda #$d1 + sta addrtbl, y + inc tmpadr+1 + iny + dec partial1 + bne tmpadr_loop + + ;==================================== + ; read a sector + ;==================================== + ; first address field + ;==================================== + ; starts with $D5 $AA $96 + ; then XX YY volume + ; then XX YY track + ; then XX YY sector + ; then XX YY checksum + ; then ends with $DE $AA $EB + ;==================================== + ; data field + ;==================================== + ; starts with $D5 $AA $AD + ; 342 bytes of data + ; XX checksum + ; ends with $DE $AA $EB +read: + +outer_read: + jsr readnib +inner_read: + cmp #$d5 ; look for $D5 part of addr field + bne outer_read + + jsr readnib ; look for $D5 $AA + cmp #$aa + bne inner_read + + ; look for $D5 $AA $AD + + tay ; we need Y=#$AA later + jsr readnib + eor #$ad ; zero A if match + beq check_mode + + ; if not #$AD, then #$96 is assumed + ; so in address field + + ldy #2 ; volume, track, sector +another: + jsr readnib + rol ; set carry + sta sector+1 + jsr readnib + and sector+1 + dey + bpl another + + tay + ldx addrtbl, Y ; fetch corresponding address + beq read ; done? + + sta sector+1 ; store index for later + + stx adrpatch1+2 + stx adrpatch8+2 + stx adrpatch2+2 + stx adrpatch3+2 + stx adrpatch5+2 + stx adrpatch7+2 + + inx + stx adrpatch9+2 + dex + + dex + stx adrpatch4+2 + stx adrpatch6+2 + + ldy #$fe + +loop2: +adrpatch1: + lda $d102, Y + pha + iny + bne loop2 + +branch_read: + bcs read ; branch always + +check_mode: + cpx #0 + beq read ; loop if not expecting #$AD + +loop33: + sta tmpval+1 ; zero rolling checksum +slotpatch2: +loop4: + ldx $c0d1 + bpl loop4 + lda preshift-$96, X +adrpatch2: + sta $d102, Y ; store 2-bit array + +tmpval: + eor #$d1 + iny + bne loop33 + ldy #$aa +slotpatch3: +loop5: + ldx $c0d1 + bpl loop5 + eor preshift-$96, X +adrpatch3: + ldx $d102, Y ; bit2tbl + eor grouped+2, X ; first 86 nibbles use group bits 0-1 +adrpatch4: + sta $d156, y + iny + bne loop5 + and #$fc + ldy #$aa +slotpatch4: +loop6: + ldx $c0d1 + bpl loop6 + eor preshift-$96, X +adrpatch5: + ldx $d102, Y ; bit2tbl + eor grouped+1, X ; second 86 nibbles use group bits 2-3 +adrpatch6: + sta $d1ac, Y + iny + bne loop6 + and #$fc + ldx #$ac +slotpatch5: +loop7: + ldy $c0d1 + bpl loop7 + eor preshift-$96, Y +adrpatch7: + ldy $d100, X ; bit2tbl + eor grouped, Y ; last 84 nibbles use group bits 4-5 +adrpatch8: + sta $d100, x + inx + bne loop7 + and #$fc +slotpatch6: +loop8: + ldy $c0d1 + bpl loop8 + eor preshift-$96, Y + cmp #1 ; carry = !zero + ldy #1 +loop9: + pla +adrpatch9: + sta $d100, Y + dey + bpl loop9 +branch_read2: + bcs branch_read ; branch if checksum failure + +sector: + ldy #$d1 + txa + sta addrtbl, Y ; zero corresponding address + dec total+1 + dec partial2 ; adjust remaining count + ; (faster than looping over array) + sec + bne branch_read2 ; read all requested sectors in one track + + sta startsec+1 ; this was missing from original code + ; leading to trouble on wrap around + ; it not starting at sector0 +total: + ldx #$d1 + beq driveoff + inc phase+1 + inc phase+1 ; update current track + jmp inittrk + +driveoff: +slotpatch7: + lda $c0d1 + +seekret: + rts + +seek: + ldx #0 + stx step+1 +copy_cur: +curtrk: + lda #0 + sta tmpval+1 + sec +phase: + sbc #$d1 + beq seekret + + ; if seek backwards + bcs sback + + eor #$ff + inc curtrk+1 + + bcc ssback +sback: + adc #$fe + dec curtrk+1 +ssback: + cmp step+1 + bcc loop10 +step: + lda #$d1 +loop10: + cmp #8 + bcs loop11 + tay + sec +loop11: + lda curtrk+1 + ldx step1, Y + bne loop12 +loopmmm: + clc + lda tmpval+1 + ldx step2, Y +loop12: + stx sector+1 + and #3 + rol + tax +slotpatch8: + sta $c0d1, X +loopmm: + ldx #$13 +loopm: + dex + bne loopm + dec sector+1 + bne loopmm + lsr + bcs loopmmm + inc step+1 + bne copy_cur + +step1: .byte 1, $30, $28, $24, $20, $1e, $1d, $1c +step2: .byte $70, $2c, $26, $22, $1f, $1e, $1d, $1c +addrtbl: .res 16 + +partial1: .byte $00 +partial2: .byte $00 +code_end: + + + +;========================== +; enable drive motor +;========================== + +driveon: + +slotpatch9: + lda $c0d1 + + ; wait 1s + + ldx #6 +wait_1s: + lda #255 + jsr WAIT + dex + bne wait_1s + + rts + +load_new: + + jsr driveon + + lda load_track + asl ; track to start*2 + sta phase+1 + + lda load_sector + tay ; sector to start + + lda load_length ; length + tax + + lda load_address ; address to load + + jsr seekread + + rts + +load_address: + .byte $00 +load_track: + .byte $00 +load_sector: + .byte $00 +load_length: + .byte $00 + diff --git a/games/mist_hgr/qkumba_popwr.s b/games/mist_hgr/qkumba_popwr.s new file mode 100644 index 00000000..4c44d22b --- /dev/null +++ b/games/mist_hgr/qkumba_popwr.s @@ -0,0 +1,247 @@ +; popwr -- code provided by qkumba + + +frombuff=$d00 ; sector data to write + +; note these must be contiguous +encbuf=$e00 ; nibble buffer must be page alined +bit2tbl=$f00 + +readnib = $1001 + + +readd5aa: + +try_again: + jsr readnib +try_for_d5: + cmp #$d5 + bne try_again + jsr readnib + cmp #$aa + bne try_for_d5 + + jsr readnib + rts + + ;================================ + ; set up the self-modifying code + ; to point to the proper slot + ;================================ + ; slot number is in high nibble of A +popwr_init: + and #$70 ; the slot number is in the top here + sta slotpatchw1+1 ; self modify the code + sta slotpatchw2+1 + sta slotpatchw3+1 + sta slotpatchw4+1 + + rts + + ;================================ + ; write a sector + ;================================ + +sector_write: + + ; convert the input to nibbles + + ldy #2 ; why start at 2? +aa: + ldx #$aa +b1: + dey +frombuff_smc: + lda frombuff, y + lsr + rol bit2tbl-$aa, x + lsr + rol bit2tbl-$aa, x + sta encbuf, y + lda bit2tbl-$aa, x + and #$3f + sta bit2tbl-$aa, x + inx + bne b1 + tya + bne aa + + jmp cmpsecwr + +.align $100 + + ; look for the proper sector to write + +cmpsecwr: +b2: + jsr readd5aa ; look for dd55aa marker + cmp #$96 + bne b2 + + ldy #3 ; try getting the sector number +b3: + jsr readnib + rol + sta tmpsec + jsr readnib + and tmpsec ; and with prev nibble? + dey + bne b3 + + +requested_sector: + cmp #$d1 + + bne cmpsecwr ; retry if not what we want? + + ;skip tail #$DE #$AA #$EB some #$FFs ... + + ldy #$24 +b4: + dey + bpl b4 + + + ; c0e0 slot 6 ph0 off + ; c0e1 slot 6 ph0 on + ; c0e2 slot 6 ph1 off + ; c0e3 slot 6 ph1 on + ; c0e4 slot 6 ph2 off + ; c0e5 slot 6 ph2 on + ; c0e6 slot 6 ph3 off + ; c0e7 slot 6 ph3 on + ; c0e8 slot 6 motor off + ; c0e9 slot 6 motor on + ; c0ea slot 6 drive 1 + ; c0eb slot 6 drive 2 + ; c0ec slot 6 q6 off \ Q6 Q7 + ; c0ed slot 6 q6 on |-- state machine 0 0 READ + ; c0ee slot 6 q7 off | 0 1 WRITE + ; c0ef slot 6 q7 on / 1 0 SENSE WRITE PROTECT + ; 1 1 WRITE LOAD + + ; write sector data + +slotpatchw1: + ldx #$d1 ; cycle num smc Q6 Q7 + lda $c08d, x ; prime drive 1 X + lda $c08e, x ; required by Unidisk 1 0 ; senese wp? + tya + sta $c08f, x ; 1 1 ; write load + ora $c08c, x ; 0 1 ; write + + ; 40 cycles + + ldy #4 ; 2 cycles + cmp $ea ; nop ; 3 cycles + cmp ($ea,x) ; nop ; 6 cycles +b5: + jsr writenib1 ; (29 cycles) + + ; +6 cycles + dey ; 2 cycles + bne b5 ; 3/2nt + + ; 36 cycles + ; +10 cycles + ldy #(prolog_e-prolog) + ; 2 cycles + cmp $ea ; nop ; 3 cycles +b6: + lda prolog-1, y ; 4 cycles + jsr writenib3 ; (17 cycles) + + ; 32 cycles if branch taken + ; +6 cycles + dey ; 2 cycles + bne b6 ; 3/2nt + + ; 36 cycles on first pass + ; +10 cycles + tya ; 2 cycles + ldy #$56 ; 2 cycles +b7: + eor bit2tbl-1, y ; 5 cycles + tax ; 2 cycles + lda xlattbl, x ; 4 cycles +slotpatchw2: + ldx #$d1 ; slot number smc ; 2 cycles + sta $c08d, x ; wp sense ; 5 cycles + lda $c08c, x ; read ; 4 cycles + + ; 32 cycles if branch taken + + lda bit2tbl-1, y ; 5 cycles + dey ; 2 cycles + bne b7 ; 3/2nt + + ; 32 cycles + ; +9 cycles + clc ; 2 cycles +b88: + eor encbuf, y ; 4 cycles +b8: + tax ; 2 cycles + lda xlattbl, x ; 4 cycles +slotpatchw3: + ldx #$d1 ; slot number smc ; 2 cycles + sta $c08d, x ; wp sense ; 5 cycles + lda $c08c, x ; read ; 4 cycles + bcs f1 ; 3/2nt + + ; 32 cycles if branch taken + + lda encbuf, y ; 4 cycles + iny ; 2 cycles + bne b88 ; 3/2nt + + ; 32 cycles + ; +10 cycles + sec ; 2 cycles + bcs b8 ; 3 cycles + + ; 32 cycles + ; +3 cycles +f1: + ldy #(epilog_e-epilog) + ; 2 cycles + cmp ($ea,x) ; nop ; 6 cycles +b9: + lda epilog-1, y ; 4 cycles + jsr writenib3 ; (17 cycles) + + ; 32 cycles if branch taken + ; +6 cycles + dey ; 2 cycles + bne b9 ;3/2nt + + lda $c08e, x ; read/wp + lda $c08c, x ; read + lda $c088, x ; motor off + rts ; 6 cycles + +writenib1: + cmp ($ea,x) ; nop ; 6 cycles + cmp ($ea,x) ; nop ; 6 cycles +writenib3: +slotpatchw4: + ldx #$d1 ; slot number ; 2 cycles +writenib4: + sta $c08d, x ; wp sense? ; 5 cycles + ora $c08c, x ; read ; 4 cycles + rts ; 6 cycles + +prolog: .byte $ad, $aa, $d5 +prolog_e: +epilog: .byte $ff, $eb, $aa, $de +epilog_e: + +xlattbl: +.byte $96,$97,$9A,$9B,$9D,$9E,$9F,$A6 +.byte $A7,$AB,$AC,$AD,$AE,$AF,$B2,$B3 +.byte $B4,$B5,$B6,$B7,$B9,$BA,$BB,$BC +.byte $BD,$BE,$BF,$CB,$CD,$CE,$CF,$D3 +.byte $D6,$D7,$D9,$DA,$DB,$DC,$DD,$DE +.byte $DF,$E5,$E6,$E7,$E9,$EA,$EB,$EC +.byte $ED,$EE,$EF,$F2,$F3,$F4,$F5,$F6 +.byte $F7,$F9,$FA,$FB,$FC,$FD,$FE,$FF diff --git a/games/mist_hgr/qload.s b/games/mist_hgr/qload.s new file mode 100644 index 00000000..e77e7e75 --- /dev/null +++ b/games/mist_hgr/qload.s @@ -0,0 +1,247 @@ +; Loader for MIST + +.include "zp.inc" +.include "hardware.inc" + +.include "common_defines.inc" +.include "qboot.inc" + +qload_start: + + ; init the write code + lda WHICH_SLOT + jsr popwr_init + + ; first time entry + ; start by loading text title + + lda #LOAD_TEXT_TITLE ; load title + sta WHICH_LOAD + + lda #1 + sta CURRENT_DISK ; current disk number + + jsr load_file + + jsr $800 + + lda #LOAD_TITLE ; load title + sta WHICH_LOAD + +main_game_loop: + jsr load_file + + lda WHICH_LOAD + bne not_title + +start_title: + jsr $4000 + jmp main_game_loop + +not_title: + jsr $2000 + jmp main_game_loop + + ;==================================== + ; loads file specified by WHICH_LOAD + ;==================================== +load_file: + ldx WHICH_LOAD + + lda which_disk_array,X + cmp CURRENT_DISK + bne change_disk + +load_file_no_diskcheck: + lda load_address_array,X + sta load_address + + lda track_array,X + sta load_track + + lda sector_array,X + sta load_sector + + lda length_array,X + sta load_length + + jsr load_new + + rts + + ;=================================================== + ;=================================================== + ; change disk + ;=================================================== + ;=================================================== + +change_disk: + + ; turn off disk drive light + + jsr driveoff + + jsr TEXT + jsr HOME + + lda #error_string + sta OUTH + + ldx WHICH_LOAD + lda which_disk_array,X + clc + adc #48 + + ldy #19 + sta (OUTL),Y + + ldy #0 + +quick_print: + lda (OUTL),Y + beq quick_print_done + jsr COUT1 + iny + jmp quick_print + +quick_print_done: + +fnf_keypress: + lda KEYPRESS + bpl fnf_keypress + bit KEYRESET + + ;============================================== + ; actually verify proper disk is there + ; read T0:S0 and verify proper disk + + lda WHICH_LOAD + pha + + ldx #LOAD_FIRST_SECTOR ; load track 0 sector 0 + stx WHICH_LOAD + + jsr load_file_no_diskcheck + + pla + sta WHICH_LOAD + tax + + ; first sector now in $c00 + ; offset 59 + ; disk1 = $0a + ; disk2 = $32 ('2') + ; disk3 = $33 ('3') + + lda $c59 + cmp #$0a + beq is_disk1 + cmp #$32 + beq is_disk2 + cmp #$33 + beq is_disk3 + bne change_disk ; unknown disk + +is_disk1: + lda #1 + bne disk_compare + +is_disk2: + lda #2 + bne disk_compare + +is_disk3: + lda #3 + +disk_compare: + cmp which_disk_array,X + bne change_disk ; disk mismatch + + ;============================================== + ; all good, retry original load + + jsr HOME + + ldx WHICH_LOAD + lda which_disk_array,X + sta CURRENT_DISK + + jmp load_file + +; offset for disk number is 19 +error_string: +.byte "PLEASE INSERT DISK 1, PRESS RETURN",0 + + +which_disk_array: + .byte 1,1,3,3 ; MIST_TITLE,MIST,MECHE,SELENA + .byte 1,1,3,2 ; OCTAGON,VIEWER,STONEY,CHANNEL + .byte 2,1,2,2 ; CABIN,DENTIST,ARBOR,NIBEL + .byte 1,1,1,3 ; SHIP,GENERATOR,D'NI,SUB + .byte 1 ; TEXT_TITLE + .byte 1,1,1,1,1 ; SAVE1,SAVE2,SAVE3,SAVE4,SAVE5 + .byte $f ; FIRST_SECTOR + +load_address_array: + .byte $40,$20,$20,$20 ; MIST_TITLE,MIST,MECHE,SELENA + .byte $20,$20,$20,$20 ; OCTAGON,VIEWER,STONEY,CHANNEL + .byte $20,$20,$20,$20 ; CABIN,DENTIST,ARBOR,NIBEL + .byte $20,$20,$20,$20 ; SHIP,GENERATOR,D'NI,SUB + .byte $08 ; TEXT_TITLE + .byte $0E,$0E,$0E,$0E + .byte $0E ; SAVE1,SAVE2,SAVE3,SAVE4,SAVE5 + .byte $0C ; FIRST_SECTOR + +track_array: + .byte 2, 8, 1,21 ; MIST_TITLE,MIST,MECHE,SELENA + .byte 18,31,11, 1 ; OCTAGON,VIEWER,STONEY,CHANNEL + .byte 27,26,10,20 ; CABIN,DENTIST,ARBOR,NIBEL + .byte 30,32,28,30 ; SHIP,GENERATOR,D'NI,SUB + .byte 0 ; TEXT_TITLE + .byte 0, 0, 0, 0, 0 ; SAVE1,SAVE2,SAVE3,SAVE4,SAVE5 + .byte 0 ; FIRST_SECTOR + +sector_array: + .byte 0, 0, 0, 0 ; MIST_TITLE,MIST,MECHE,SELENA + .byte 0, 8, 0, 0 ; OCTAGON,VIEWER,STONEY,CHANNEL + .byte 0, 0, 0, 0 ; CABIN,DENTIST,ARBOR,NIBEL + .byte 0,13, 0, 1 ; SHIP,GENERATOR,D'NI,SUB + .byte 6 ; TEXT_TITLE + .byte 11,12,13,14,15 ; SAVE1,SAVE2,SAVE3,SAVE4,SAVE5 + .byte 0 ; FIRST_SECTOR + +length_array: + .byte 88,159,157,145 ; MIST_TITLE,MIST,MECHE,SELENA + .byte 128, 20,158,135 ; OCTAGON,VIEWER,STONEY,CHANNEL + .byte 61, 31,159,109 ; CABIN,DENTIST,ARBOR,NIBEL + .byte 20, 33, 27, 78 ; SHIP,GENERATOR,D'NI,SUB + .byte 3 ; TEXT_TITLE + .byte 1,1,1,1,1 ; SAVE1,SAVE2,SAVE3,SAVE4,SAVE5 + .byte 1 ; FIRST_SECTOR + + .include "audio.s" + .include "linking_noise.s" + .include "decompress_fast_v2.s" +; .include "draw_pointer.s" +; .include "end_level.s" +; .include "gr_copy.s" + .include "gr_fast_clear.s" + .include "gr_offsets.s" +; .include "gr_pageflip.s" +; .include "gr_putsprite_crop.s" + .include "keyboard.s" + .include "text_print.s" + .include "loadstore.s" + .include "joystick.s" + .include "log_table.s" + +; .include "page_sprites.inc" +; .include "common_sprites.inc" + + .include "qkumba_popwr.s" + +qload_end: + +.assert (>qload_end - >qload_start) < $e , error, "loader too big" diff --git a/games/mist_hgr/text_print.s b/games/mist_hgr/text_print.s new file mode 100644 index 00000000..199893be --- /dev/null +++ b/games/mist_hgr/text_print.s @@ -0,0 +1,82 @@ + + ;================================ + ; move_and_print + ;================================ + ; get X,Y from OUTL/OUTH + ; then print following string to that address + ; stop at NUL + ; convert to APPLE ASCII (or with 0x80) + ; leave OUTL/OUTH pointing to next string + +move_and_print: + ldy #0 + lda (OUTL),Y + sta CH + iny + lda (OUTL),Y + asl + tay + lda gr_offsets,Y ; lookup low-res memory address + clc + adc CH ; add in xpos + sta BASL ; store out low byte of addy + + lda gr_offsets+1,Y ; look up high byte + adc DRAW_PAGE ; + sta BASH ; and store it out + ; BASH:BASL now points at right place + + clc + lda OUTL + adc #2 + sta OUTL + lda OUTH + adc #0 + sta OUTH + + ;================================ + ; print_string + ;================================ + +print_string: + ldy #0 +print_string_loop: + lda (OUTL),Y + beq done_print_string +ps_smc1: + and #$3f ; make sure we are inverse + sta (BASL),Y + iny + bne print_string_loop +done_print_string: + iny + clc + tya + adc OUTL + sta OUTL + lda OUTH + adc #0 + sta OUTH + + rts + + ; set normal text +set_normal: + lda #$80 + sta ps_smc1+1 + + lda #09 ; ora + sta ps_smc1 + + rts + + ; restore inverse text +set_inverse: + lda #$29 + sta ps_smc1 + lda #$3f + sta ps_smc1+1 + + rts + + diff --git a/games/mist_hgr/text_title.s b/games/mist_hgr/text_title.s new file mode 100644 index 00000000..24bd644b --- /dev/null +++ b/games/mist_hgr/text_title.s @@ -0,0 +1,58 @@ +.include "common_defines.inc" +.include "zp.inc" +.include "hardware.inc" + +text_title: + jsr TEXT + jsr HOME + + lda #0 + sta DRAW_PAGE + + ; print non-inverse + lda #$80 + sta ps_smc1+1 + + lda #09 ; ora + sta ps_smc1 + + lda #boot_message + sta OUTH + + ldx #15 +text_loop: + + jsr move_and_print + + dex + bne text_loop + + +; lda #40 +; jsr wait_a_bit + + rts + +; 0123456789012345678901234567890123456789 +boot_message: +.byte 0,0, "LOADING HGR MIST V0.01",0 +.byte 0,3, "CONTROLS:",0 +.byte 5,4, "MOVE CURSOR : ARROWS OR WASD",0 +.byte 5,5, "FORWARD/ACTION : RETURN OR SPACE",0 +.byte 5,7, "ENABLE JOYSTICK: J",0 +.byte 5,8, "LOAD GAME : CONTROL-L",0 +.byte 5,9, "SAVE : CONTROL-S",0 +.byte 5,10,"TOGGLE SOUND : CONTROL-T",0 +.byte 0,13,"BASED ON MYST BY CYAN INC",0 +.byte 0,14,"APPLE II PORT: VINCE WEAVER",0 +.byte 0,15,"DISK CODE : QKUMBA",0 +.byte 0,16,"SOUND CODE : OLIVER SCHMIDT",0 +.byte 0,17,"LZSA CODE : EMMANUEL MARTY",0 +.byte 8,19,"______",0 +.byte 6,20,"A \/\/\/ SOFTWARE PRODUCTION",0 + +.include "text_print.s" +.include "gr_offsets.s" +;.include "wait_a_bit.s" diff --git a/games/mist_hgr/wait_a_bit.s b/games/mist_hgr/wait_a_bit.s new file mode 100644 index 00000000..f71370ad --- /dev/null +++ b/games/mist_hgr/wait_a_bit.s @@ -0,0 +1,27 @@ + ;==================================== + ; wait for keypress or a few seconds + ;==================================== + +wait_a_bit: + + bit KEYRESET + tax + +keyloop: + lda #200 ; delay a bit + jsr WAIT + + lda KEYPRESS + bmi done_keyloop + +; bmi keypress_exit + + dex + bne keyloop + +done_keyloop: + + bit KEYRESET + + rts + diff --git a/games/mist_hgr/zp.inc b/games/mist_hgr/zp.inc new file mode 100644 index 00000000..c02cf5db --- /dev/null +++ b/games/mist_hgr/zp.inc @@ -0,0 +1,360 @@ +;; Zero Page + +;; LZSA addresses +NIBCOUNT = $00 +APPLEII_MODEL = $01 + +;; Zero page monitor routines addresses + +WNDLFT = $20 +WNDWDTH = $21 +WNDTOP = $22 +WNDBTM = $23 +CH = $24 +CV = $25 +GBASL = $26 +GBASH = $27 +BASL = $28 +BASH = $29 +H2 = $2C +X_LEFT = $2C ; ??? +V2 = $2D +MASK = $2E +COLOR_MASK = $2F +COLOR = $30 + + +SEEDL = $4e +SEEDH = $4f +XMAX = $50 + +; MIST zero page addresses + +FRAMEL = $60 +FRAMEH = $61 +CURSOR_X = $62 +CURSOR_Y = $63 +XPOS = $64 +YPOS = $65 +LOCATION_STRUCT_L = $66 +LOCATION_STRUCT_H = $67 +IN_SPECIAL = $68 +CURSOR_VISIBLE = $69 +IN_LEFT = $6A +IN_RIGHT = $6B +BTC_L = $6C +BTC_H = $6D + +; pt3 player registers +AY_REGISTERS = $70 +A_FINE_TONE = $70 +A_COARSE_TONE = $71 +B_FINE_TONE = $72 +B_COARSE_TONE = $73 +C_FINE_TONE = $74 +C_COARSE_TONE = $75 +NOISE = $76 +ENABLE = $77 +PT3_MIXER_VAL = $77 +A_VOLUME = $78 +B_VOLUME = $79 +C_VOLUME = $7A +ENVELOPE_FINE = $7B +ENVELOPE_COARSE = $7C +ENVELOPE_SHAPE = $7D +PATTERN_L = $7E +PATTERN_H = $7F + +; note 70-7f also used by disk code + +; note: rest are up at $f0 + +; We have to save/restore the following values +; when loading/storing from disk + +WHICH_LOAD = $80 ; which file to load +DIRECTION = $81 ; direction we are pointing + DIRECTION_N = $1 + DIRECTION_S = $2 + DIRECTION_E = $4 + DIRECTION_W = $8 + DIRECTION_ANY=$f + DIRECTION_ONLY_POINT = $40 ; do not change pointer to grab + DIRECTION_SPLIT = $80 ; split text/graphics + +LOCATION = $82 ; location on the map + +RED_PAGES_TAKEN = $83 ; red pages that have been picked up + OCTAGON_PAGE = $01 + MECHE_PAGE = $02 + SELENA_PAGE = $04 + STONEY_PAGE = $08 + CHANNEL_PAGE = $10 + FINAL_PAGE = $20 +BLUE_PAGES_TAKEN= $84 ; blue pages that have been picked up +CLOCK_BRIDGE = $85 ; is the clock island bridge raised +GEAR_OPEN = $86 ; is the big gear open +MARKER_SWITCHES = $87 ; state of the marker switches + MARKER_DOCK = $01 + MARKER_GEARS = $02 + MARKER_SPACESHIP = $04 + MARKER_GENERATOR = $08 + MARKER_CLOCK = $10 + MARKER_TREE = $20 + MARKER_POOL = $40 + MARKER_DENTIST = $80 + +CLOCK_HOUR = $88 ; hour on the mist clock +CLOCK_MINUTE = $89 ; minute on the mist clock + +BOILER_LEVEL = $8A ; furnace in the cabin level + +FIREPLACE_GRID0 = $8B ; fireplace grid puzzle state +FIREPLACE_GRID1 = $8C +FIREPLACE_GRID2 = $8D +FIREPLACE_GRID3 = $8E +FIREPLACE_GRID4 = $8F +FIREPLACE_GRID5 = $90 + +CLOCK_COUNT = $91 ; clock puzzle (turns taken) +CLOCK_TOP = $92 ; clock puzzle (top dial) +CLOCK_MIDDLE = $93 ; clock puzzle (middle dial) +CLOCK_BOTTOM = $94 ; clock puzzle (bottom dial) +CLOCK_LAST = $95 ; clock puzzle (last dial turned) + +BREAKER_TRIPPED = $96 ; generator (circuit breakers status) +GENERATOR_VOLTS = $97 ; generator (total volts) +ROCKET_VOLTS = $98 ; generator (rocket volts) +SWITCH_TOP_ROW = $99 ; generator (switch top row) +SWITCH_BOTTOM_ROW = $9A ; generator (switch bottom row) +GENERATOR_VOLTS_DISP = $9B ; generator (total volts on display) +ROCKET_VOLTS_DISP = $9C ; generator (rocket volts on display) + +ROCKET_HANDLE_STEP = $9D ; organ (which knob is lit) [why zp?] +ROCKET_NOTE1 = $9E ; organ (note slider 1) +ROCKET_NOTE2 = $9F ; organ (note slider 2) +ROCKET_NOTE3 = $A0 ; organ (note slider 3) +ROCKET_NOTE4 = $A1 ; organ (note slider 4) + +MECHE_ELEVATOR = $A2 ; fortress elevator state +MECHE_ROTATION = $A3 ; fortress rotation state + ; 0..3 = S + ; 4..7 = E + ; 8..11 = N + ; 12..15 = W +MECHE_LEVERS = $A4 ; fortress rotation levers + LEFT_LEVER = 1 + RIGHT_LEVER = 2 +MECHE_LOCK1 = $A5 ; meche lock symbol1 +MECHE_LOCK2 = $A6 ; meche lock symbol2 +MECHE_LOCK3 = $A7 ; meche lock symbol3 +MECHE_LOCK4 = $A8 ; meche lock symbol4 + +HOLDING_PAGE = $A9 ; which page in hand + HOLDING_RED_PAGE = $80 + HOLDING_BLUE_PAGE = $40 + HOLDING_WHITE_PAGE = $C0 + ;FINAL_PAGE = $20 + ;CHANNEL_PAGE = $10 + ;STONEY_PAGE = $08 + ;SELENA_PAGE = $04 + ;MECHE_PAGE = $02 + ;OCTAGON_PAGE = $01 + +RED_PAGE_COUNT = $AA ; # of red pages in book +BLUE_PAGE_COUNT = $AB ; # of blue pages in book + +VIEWER_CHANNEL = $AC ; viewer: current channel +VIEWER_LATCHED = $AD ; viewer: latched channel + +TOWER_ROTATION = $AE ; tower rotation: which + ROTATION_GEARS = 2 + ROTATION_DOCK = 3 + ROTATION_TREE = 4 + ROTATION_SPACESHIP = 8 + +SHIP_RAISED = $AF ; ship raised or not + +PUMP_STATE = $B0 ; stoneship pump state + DRAINED_EXIT = $01 + DRAINED_TUNNELS = $02 + DRAINED_LIGHTHOUSE=$04 + +BATTERY_CHARGE = $B1 ; stoneship battery charge +COMPASS_STATE = $B2 ; stoneship compass state + COMPASS_DEFAULT = 0 ; cabin lights off + COMPASS_LIGHT_ON= 1 ; proper angle selected +CRANK_ANGLE = $B3 ; stoneship crank angle + +WHITE_PAGE_TAKEN= $B4 ; white page taken + +CHANNEL_SWITCHES= $B5 ; channelwood switches + CHANNEL_SW_FAUCET = $80 + CHANNEL_SW_WINDMILL = $40 + CHANNEL_SW_GATE_BOTTOM = $20 + CHANNEL_ELEVATOR1_UP = $10 + CHANNEL_SW_GATE_TOP = $08 + CHANNEL_BOOK_ELEVATOR_UP= $04 + CHANNEL_PIPE_EXTENDED = $02 + CHANNEL_BRIDGE_UP = $01 + +CHANNEL_VALVES = $B6 ; channelwood valves + CHANNEL_VALVE1 = $01 ; elevator2 + CHANNEL_VALVE2 = $02 ; big tree + CHANNEL_VALVE3 = $04 ; broken + CHANNEL_VALVE4 = $08 ; elevator1 + CHANNEL_VALVE5 = $10 ; entry + CHANNEL_VALVE6 = $20 ; bridge + +DENTIST_LIGHT = $B7 ; dentist lightswitch +DENTIST_MONTH = $B8 ; dentist panel: month +DENTIST_DAY = $B9 ; dentist panel: day +DENTIST_CENTURY = $BA ; dentist panel: century +DENTIST_YEAR = $BB ; dentist panel: year +DENTIST_HOURS = $BC ; dentist panel: hours +DENTIST_MINUTES = $BD ; dentist panel: minutes + +PILLAR_ON = $BE ; pillars: which on/off + PILLAR_EYE = $01 + PILLAR_SNAKE = $02 + PILLAR_BUG = $04 + PILLAR_ANCHOR = $08 + PILLAR_ARROW = $10 + PILLAR_LEAF = $20 + PILLAR_CROSS = $40 + PILLAR_EMU = $80 + +GREEN_BOOK_PROGRESS = $BF ; green book: what's ben seen + +DNI_PROGRESS = $C0 ; dni: atrus status + +COMPARTMENT_OPEN = $C1 ; dock marker switch compartment + +GAME_COMPLETE = $C2 ; game has been completed + +SAFE_HUNDREDS = $C3 ; safe combination, hundreds +SAFE_TENS = $C4 ; safe combination, tens +SAFE_ONES = $C5 ; safe combination, ones + +TREE_LEVEL = $C6 ; how high is the tree hole + +HOLDING_ITEM = $C7 + HOLDING_KEY = $04 + HOLDING_LIT_MATCH = $02 + HOLDING_MATCH = $01 + +BOILER_VALVE = $C8 ; how many turns of the boiler valve + +TRUNK_STATE = $C9 ; trunk state in stonsehip + TRUNK_VALVE_OPEN = $01 + TRUNK_WATER_DRAINED = $02 + TRUNK_KEY_TAKEN = $04 + TRUNK_LID_OPEN = $08 + TRUNK_HATCH_OPEN = $10 + TRUNK_KEY_ON_FLOOR = $20 + +SELENA_BUTTON_STATUS = $CA + SELENA_BUTTON1 = $01 ; POOL (water) + SELENA_BUTTON2 = $02 ; CHASM (fire) + SELENA_BUTTON3 = $04 ; CLOCK (ticking) + SELENA_BUTTON4 = $08 ; CRYSTALS (whistle) + SELENA_BUTTON5 = $10 ; TUNNEL (wind) + SELENA_LIGHTSWITCH= $80 ; light in the tunnel + +SELENA_ANTENNA1 = $CB ; rotation angle for antenna1 +SELENA_ANTENNA2 = $CC ; rotation angle for antenna1 +SELENA_ANTENNA3 = $CD ; rotation angle for antenna1 +SELENA_ANTENNA4 = $CE ; rotation angle for antenna1 +SELENA_ANTENNA5 = $CF ; rotation angle for antenna1 + +SELENA_LOCK1 = $D0 ; antenna lock slider1 +SELENA_LOCK2 = $D1 ; antenna lock slider2 +SELENA_LOCK3 = $D2 ; antenna lock slider3 +SELENA_LOCK4 = $D3 ; antenna lock slider4 +SELENA_LOCK5 = $D4 ; antenna lock slider5 + +SELENA_ANTENNA_ACTIVE = $D5 ; which antenna currently selected + +SUB_LOCATION = $D6 +SUB_DIRECTION = $D7 + +NIBEL_PROJECTOR = $D8 ; which button on projector in nibel + +END_OF_SAVE = $D9 + + +; done game puzzle state + + +WHICH_SLOT = $DA +JS_BUTTON_STATE = $DB +CURRENT_DISK = $DC +JOYSTICK_ENABLED= $DD +SOUND_STATUS = $DE + SOUND_DISABLED = $80 + SOUND_IN_LC = $01 ; $01 sound effects in language card + SOUND_MOCKINGBOARD = $02 ; mockingboard detected + +GRID_PAGE = $DF +ANIMATE_FRAME = $E0 +LEVEL_OVER = $E1 +LOCATIONS_L = $E2 +LOCATIONS_H = $E3 + +; temp var per-world define +LONG_FRAME = $E4 ; nibel +CURRENT_DISPLAY = $E4 ; selena +LAST_PLAYED = $E4 ; selena + +DISP_PAGE = $ED ; ALL +DRAW_PAGE = $EE ; ALL + +; rest of pt3_player +PT3_TEMP = $EF +ORNAMENT_L = $F0 +ORNAMENT_H = $F1 +SAMPLE_L = $F2 +SAMPLE_H = $F3 +LOOP = $F4 +MB_VALUE = $F5 +MB_ADDR_L = $F6 +MB_ADDR_H = $F7 +DONE_PLAYING = $F8 +DONE_SONG = $F9 + +;TINL = $F0 +;TINH = $F1 +;BINL = $F2 +;BINH = $F3 +;SCROLL_COUNT = $F9 + +TEMP = $FA +TEMPY = $FB +INL = $FC +INH = $FD +OUTL = $FE +OUTH = $FF + +; read any file slot 6 version +; based on FASTLD6 and RTS copyright (c) Peter Ferrie 2011-2013,2018 + +; modified to assembled with ca64 -- vmw +; added code to patch it to run from current disk slot -- vmw + + + adrlo = $26 ; constant from boot prom + adrhi = $27 ; constant from boot prom + tmpsec = $3c ; constant from boot prom + reqsec = $3d ; constant from boot prom + sizelo = $44 + sizehi = $45 + secsize = $46 + + ldsizel = $70 + ldsizeh = $71 + namlo = $7b + namhi = $7c + step = $7d ; state for stepper motor + tmptrk = $7e ; temporary copy of current track + phase = $7f ; current phase for /seek +