diff --git a/LICENSE b/LICENSE deleted file mode 100644 index cf1ab25..0000000 --- a/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -This is free and unencumbered software released into the public domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. - -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -For more information, please refer to diff --git a/Makefile b/Makefile deleted file mode 100644 index 08e15bc..0000000 --- a/Makefile +++ /dev/null @@ -1,354 +0,0 @@ - -############################################################################### -### Generic Makefile for cc65 projects - full version with abstract options ### -### V1.3.0(w) 2010 - 2013 Oliver Schmidt & Patryk "Silver Dream !" Ɓogiewa ### -############################################################################### - -############################################################################### -### In order to override defaults - values can be assigned to the variables ### -############################################################################### - -# Space or comma separated list of cc65 supported target platforms to build for. -# Default: c64 (lowercase!) -TARGETS := apple2 - -# Name of the final, single-file executable. -# Default: name of the current dir with target name appended -PROGRAM := - -# Path(s) to additional libraries required for linking the program -# Use only if you don't want to place copies of the libraries in SRCDIR -# Default: none -LIBS := - -# Custom linker configuration file -# Use only if you don't want to place it in SRCDIR -# Default: none -CONFIG := - -# Additional C assembler flags and options. -# Default: none -CFLAGS = - -# Additional assembler flags and options. -# Default: none -ASFLAGS = --debug-info --listing $@.lst - -# Additional linker flags and options. -# Default: none -LDFLAGS = -vm -m $@.map -Ln $@.vice - -# Path to the directory containing C and ASM sources. -# Default: src -SRCDIR := - -# Path to the directory where object files are to be stored (inside respective target subdirectories). -# Default: obj -OBJDIR := - -# Command used to run the emulator. -# Default: depending on target platform. For default (c64) target: x64 -kernal kernal -VICIIdsize -autoload -EMUCMD := - -# Optional commands used before starting the emulation process, and after finishing it. -# Default: none -#PREEMUCMD := osascript -e "tell application \"System Events\" to set isRunning to (name of processes) contains \"X11.bin\"" -e "if isRunning is true then tell application \"X11\" to activate" -#PREEMUCMD := osascript -e "tell application \"X11\" to activate" -#POSTEMUCMD := osascript -e "tell application \"System Events\" to tell process \"X11\" to set visible to false" -#POSTEMUCMD := osascript -e "tell application \"Terminal\" to activate" -PREEMUCMD := -POSTEMUCMD := - -# On Windows machines VICE emulators may not be available in the PATH by default. -# In such case, please set the variable below to point to directory containing -# VICE emulators. -ifeq ($(OS),Windows_NT) - VICE_HOME := -else - UNAME_S := $(shell uname -s) - ifeq ($(UNAME_S),Darwin) - VICE_HOME := /Applications/Vice/x64.app/Contents/MacOS/ - endif -endif - -# Options state file name. You should not need to change this, but for those -# rare cases when you feel you really need to name it differently - here you are -STATEFILE := Makefile.options - -################################################################################### -#### DO NOT EDIT BELOW THIS LINE, UNLESS YOU REALLY KNOW WHAT YOU ARE DOING! #### -################################################################################### - -################################################################################### -### Mapping abstract options to the actual assembler, assembler and linker flags ### -### Predefined assembler, assembler and linker flags, used with abstract options ### -### valid for 2.14.x. Consult the documentation of your cc65 version before use ### -################################################################################### - -# assembler flags used to tell the assembler to optimise for SPEED -define _optspeed_ - CFLAGS += -Oris -endef - -# assembler flags used to tell the assembler to optimise for SIZE -define _optsize_ - CFLAGS += -Or -endef - -# assembler and assembler flags for generating listings -define _listing_ - CFLAGS += --listing $$(@:.o=.lst) - ASFLAGS += --listing $$(@:.o=.lst) - REMOVES += $(addsuffix .lst,$(basename $(OBJECTS))) -endef - -# Linker flags for generating map file -define _mapfile_ - LDFLAGS += --mapfile $$@.map - REMOVES += $(PROGRAM).map -endef - -# Linker flags for generating VICE label file -define _labelfile_ - LDFLAGS += -Ln $$@.lbl - REMOVES += $(PROGRAM).lbl -endef - -# Linker flags for generating a debug file -define _debugfile_ - LDFLAGS += -Wl --dbgfile,$$@.dbg - REMOVES += $(PROGRAM).dbg -endef - -############################################################################### -### Defaults to be used if nothing defined in the editable sections above ### -############################################################################### - -# Presume the C64 target like the cl65 compile & link utility does. -# Set TARGETS to override. -ifeq ($(TARGETS),) - TARGETS := c64 -endif - -# Presume we're in a project directory so name the program like the current -# directory. Set PROGRAM to override. -ifeq ($(PROGRAM),) - PROGRAM := $(notdir $(CURDIR)) -endif - -# Presume the C and asm source files to be located in the subdirectory 'src'. -# Set SRCDIR to override. -ifeq ($(SRCDIR),) - SRCDIR := src -endif - -# Presume the object and dependency files to be located in the subdirectory -# 'obj' (which will be created). Set OBJDIR to override. -ifeq ($(OBJDIR),) - OBJDIR := obj -endif -TARGETOBJDIR := $(OBJDIR)/$(TARGETS) - -# On Windows it is mandatory to have CC65_HOME set. So do not unnecessarily -# rely on cl65 being added to the PATH in this scenario. -ifdef CC65_HOME - CC := $(CC65_HOME)/bin/cl65 -else - CC := cl65 -endif - -# Default emulator commands and options for particular targets. -# Set EMUCMD to override. -cx16_EMUCMD := $(VICE_HOME)x16emu -run -prg -c64_EMUCMD := $(VICE_HOME)x64 -kernal kernal -VICIIdsize -autostart -c128_EMUCMD := $(VICE_HOME)x128 -kernal kernal -VICIIdsize -autoload -vic20_EMUCMD := $(VICE_HOME)xvic -kernal kernal -VICdsize -autoload -pet_EMUCMD := $(VICE_HOME)xpet -Crtcdsize -autoload -plus4_EMUCMD := $(VICE_HOME)xplus4 -TEDdsize -autoload -apple2_EMUCMD := test.bat -# So far there is no x16 emulator in VICE (why??) so we have to use xplus4 with -memsize option -c16_EMUCMD := $(VICE_HOME)xplus4 -ramsize 16 -TEDdsize -autoload -cbm510_EMUCMD := $(VICE_HOME)xcbm2 -model 510 -VICIIdsize -autoload -cbm610_EMUCMD := $(VICE_HOME)xcbm2 -model 610 -Crtcdsize -autoload -atari_EMUCMD := atari800 -windowed -xl -pal -nopatchall -run - -ifeq ($(EMUCMD),) - EMUCMD = $($(CC65TARGET)_EMUCMD) -endif - -############################################################################### -### The magic begins ### -############################################################################### - -# The "Native Win32" GNU Make contains quite some workarounds to get along with -# cmd.exe as shell. However it does not provide means to determine that it does -# actually activate those workarounds. Especially does $(SHELL) NOT contain the -# value 'cmd.exe'. So the usual way to determine if cmd.exe is being used is to -# execute the command 'echo' without any parameters. Only cmd.exe will return a -# non-empy string - saying 'ECHO is on/off'. -# -# Many "Native Win32" programs accept '/' as directory delimiter just fine. How- -# ever the internal commands of cmd.exe generally require '\' to be used. -# -# cmd.exe has an internal command 'mkdir' that doesn't understand nor require a -# '-p' to create parent directories as needed. -# -# cmd.exe has an internal command 'del' that reports a syntax error if executed -# without any file so make sure to call it only if there's an actual argument. -ifeq ($(shell echo),) - MKDIR = mkdir -p $1 - RMDIR = rmdir $1 - RMFILES = $(RM) $1 -else - MKDIR = mkdir $(subst /,\,$1) - RMDIR = rmdir $(subst /,\,$1) - RMFILES = $(if $1,del /f $(subst /,\,$1)) -endif -COMMA := , -SPACE := $(N/A) $(N/A) -define NEWLINE - - -endef -# Note: Do not remove any of the two empty lines above ! - -TARGETLIST := $(subst $(COMMA),$(SPACE),$(TARGETS)) - -ifeq ($(words $(TARGETLIST)),1) - -# Set PROGRAM to something like 'myprog.c64'. -override PROGRAM := $(PROGRAM).$(TARGETLIST) - -# Set SOURCES to something like 'src/foo.c src/bar.s'. -# Use of assembler files with names ending differently than .s is deprecated! -SOURCES := $(wildcard $(SRCDIR)/*.c) -SOURCES += $(wildcard $(SRCDIR)/*.s) -SOURCES += $(wildcard $(SRCDIR)/*.asm) -SOURCES += $(wildcard $(SRCDIR)/*.a65) - -# Add to SOURCES something like 'src/c64/me.c src/c64/too.s'. -# Use of assembler files with names ending differently than .s is deprecated! -SOURCES += $(wildcard $(SRCDIR)/$(TARGETLIST)/*.c) -SOURCES += $(wildcard $(SRCDIR)/$(TARGETLIST)/*.s) -SOURCES += $(wildcard $(SRCDIR)/$(TARGETLIST)/*.asm) -SOURCES += $(wildcard $(SRCDIR)/$(TARGETLIST)/*.a65) - -# Set OBJECTS to something like 'obj/c64/foo.o obj/c64/bar.o'. -OBJECTS := $(addsuffix .o,$(basename $(addprefix $(TARGETOBJDIR)/,$(notdir $(SOURCES))))) - -# Set DEPENDS to something like 'obj/c64/foo.d obj/c64/bar.d'. -DEPENDS := $(OBJECTS:.o=.d) - -# Add to LIBS something like 'src/foo.lib src/c64/bar.lib'. -LIBS += $(wildcard $(SRCDIR)/*.lib) -LIBS += $(wildcard $(SRCDIR)/$(TARGETLIST)/*.lib) - -# Add to CONFIG something like 'src/c64/bar.cfg src/foo.cfg'. -CONFIG += $(wildcard $(SRCDIR)/$(TARGETLIST)/*.cfg) -CONFIG += $(wildcard $(SRCDIR)/*.cfg) - -# Select CONFIG file to use. Target specific configs have higher priority. -ifneq ($(word 2,$(CONFIG)),) - CONFIG := $(firstword $(CONFIG)) - $(info Using config file $(CONFIG) for linking) -endif - -.SUFFIXES: -.PHONY: all test clean zap love - -all: $(PROGRAM) - --include $(DEPENDS) --include $(STATEFILE) - -# If OPTIONS are given on the command line then save them to STATEFILE -# if (and only if) they have actually changed. But if OPTIONS are not -# given on the command line then load them from STATEFILE. Have object -# files depend on STATEFILE only if it actually exists. -ifeq ($(origin OPTIONS),command line) - ifneq ($(OPTIONS),$(_OPTIONS_)) - ifeq ($(OPTIONS),) - $(info Removing OPTIONS) - $(shell $(RM) $(STATEFILE)) - $(eval $(STATEFILE):) - else - $(info Saving OPTIONS=$(OPTIONS)) - $(shell echo _OPTIONS_=$(OPTIONS) > $(STATEFILE)) - endif - $(eval $(OBJECTS): $(STATEFILE)) - endif -else - ifeq ($(origin _OPTIONS_),file) - $(info Using saved OPTIONS=$(_OPTIONS_)) - OPTIONS = $(_OPTIONS_) - $(eval $(OBJECTS): $(STATEFILE)) - endif -endif - -# Transform the abstract OPTIONS to the actual cc65 options. -$(foreach o,$(subst $(COMMA),$(SPACE),$(OPTIONS)),$(eval $(_$o_))) - -# Strip potential variant suffix from the actual cc65 target. -CC65TARGET := $(firstword $(subst .,$(SPACE),$(TARGETLIST))) - -# The remaining targets. -$(TARGETOBJDIR): - $(call MKDIR,$@) - -vpath %.c $(SRCDIR)/$(TARGETLIST) $(SRCDIR) - -$(TARGETOBJDIR)/%.o: %.c | $(TARGETOBJDIR) - $(CC) -t $(CC65TARGET) -c --create-dep $(@:.o=.d) $(CFLAGS) -o $@ $< - -vpath %.s $(SRCDIR)/$(TARGETLIST) $(SRCDIR) - -$(TARGETOBJDIR)/%.o: %.s | $(TARGETOBJDIR) - $(CC) -t $(CC65TARGET) -c --create-dep $(@:.o=.d) $(ASFLAGS) -o $@ $< - -vpath %.asm $(SRCDIR)/$(TARGETLIST) $(SRCDIR) - -$(TARGETOBJDIR)/%.o: %.asm | $(TARGETOBJDIR) - $(CC) -t $(CC65TARGET) -c --create-dep $(@:.o=.d) $(ASFLAGS) -o $@ $< - -vpath %.a65 $(SRCDIR)/$(TARGETLIST) $(SRCDIR) - -$(TARGETOBJDIR)/%.o: %.a65 | $(TARGETOBJDIR) - $(CC) -t $(CC65TARGET) -c --create-dep $(@:.o=.d) $(ASFLAGS) -o $@ $< - -$(PROGRAM): $(CONFIG) $(OBJECTS) $(LIBS) - $(CC) -t $(CC65TARGET) $(LDFLAGS) -o $@ $(patsubst %.cfg,-C %.cfg,$^) - -test: $(PROGRAM) - $(PREEMUCMD) - $(EMUCMD) $(notdir $(<)) - $(POSTEMUCMD) - -clean: - $(call RMFILES,$(OBJECTS)) - $(call RMFILES,$(DEPENDS)) - $(call RMFILES,$(REMOVES)) - $(call RMFILES,$(PROGRAM)) - -else # $(words $(TARGETLIST)),1 - -all test clean: - $(foreach t,$(TARGETLIST),$(MAKE) TARGETS=$t $@$(NEWLINE)) - -endif # $(words $(TARGETLIST)),1 - -OBJDIRLIST := $(wildcard $(OBJDIR)/*) - -zap: - $(foreach o,$(OBJDIRLIST),-$(call RMFILES,$o/*.o $o/*.d $o/*.lst)$(NEWLINE)) - $(foreach o,$(OBJDIRLIST),-$(call RMDIR,$o)$(NEWLINE)) - -$(call RMDIR,$(OBJDIR)) - -$(call RMFILES,$(basename $(PROGRAM)).* $(STATEFILE)) - -love: - @echo "Not war, eh?" - -################################################################### -### Place your additional targets in the additional Makefiles ### -### in the same directory - their names have to end with ".mk"! ### -################################################################### --include *.mk diff --git a/Makefile-dsk.mk b/Makefile-dsk.mk deleted file mode 100644 index 34bf4da..0000000 --- a/Makefile-dsk.mk +++ /dev/null @@ -1,21 +0,0 @@ -DSK = Penetrator.dsk - -# For this one, see https://applecommander.github.io/ -AC ?= ac.jar - -# Unix or Windows -ifeq ($(shell echo),) - CP = cp $1 -else - CP = copy $(subst /,\,$1) -endif - -REMOVES += $(DSK) - -.PHONY: dsk -dsk: $(DSK) - -$(DSK): penetrator-apple2.apple2.loader penetrator-apple2.apple2 - $(call CP, apple2/template.dsk $@) - java -jar $(AC) -p $@ penetrat.system sys < penetrator-apple2.apple2.loader - java -jar $(AC) -as $@ penetrat bin < penetrator-apple2.apple2 diff --git a/README.md b/README.md index 7b7d00a..0b0956a 100644 --- a/README.md +++ b/README.md @@ -1,174 +1,7 @@ # penetrator - Remake of the ZX Spectrum game for the Apple II. - -1. INTRODUCTION - -This is a "port" of the Commander X16 version that's also in my repo's as just -penetrator. I had to rewrite quite a bit of the drawing code and make some -other changes to make it work on the Apple II, and to make it fast enough. - -This is also my very first program for the Apple II. It was a learning -experience :) - -2. CURRENT STATUS - -The game is a pretty good replica of the original. It is missing the demo -attract mode, and the fireworks. - -Video https://youtu.be/fVms0nNVDtY and here's Oliver Schmidt's son, Pascal, -playing the game on real hardware: https://www.youtube.com/watch?v=rXC2JKuN594 - -There's also a pre-built Apple II disk of the project, Penetrator.dsk under the -releases tab. This can be played directly in emulators. - -3. TECHNICAL DETAILS - -The game is written in 6502 assembly using the ca65 assembler. - -Below is a CPU cycle profile of 1 game frame in stage 4. It's a busy frame with -bullets, bombs and enemies. Most importantly, it has a busy terrain at the top -and bottom. - -Hex | Dec | Frame % | Item ---- | --- | --- | --- -148F3 | 84211 | 100% | Total Frame -61F | 1567 | 2.0% | inputGame -0A | 10 | 0.0% | Misc -73 | 115 | 0.1% | gameWorldMove -05 | 5 | 0.0% | Misc -19 | 25 | 0.0% | gameCheckStage -08 | 8 | 0.0% | Misc -B80 | 2944 | 3.5% | gameAI -17 | 23 | 0.0% | Misc -7267 | 29287 | 34.8% | drawClearRows -6721 | 26401 | 31.4% | terrainDraw -38A8 | 14504 | 17.2% | drawEnemies -985 | 2437 | 2.9% | drawPlayer -581 | 1409 | 1.7% | drawBullets -6E3 | 1763 | 2.1% | drawBombs -E14 | 3604 | 4.3% | drawExplosions -06 | 6 | 0.0% | Misc -1A | 26 | 0.0% | drawPresent -11 | 17 | 0.0% | Misc -3C | 60 | 0.1% | Emulator error +Remake of the ZX Spectrum game for the Apple II. -As can be seen, clearing the area where the world will be drawn takes almost 35% -of the frame and drawing the terrain takes another 31% of the frame. The -Emulator Error are unaccounted for cycles -discrepency between total cycles at -the start and end, vs. the cycles reported in each step. I modifies the -emulator myself to do step reporting and I assume I must have missed someting. - -4. KEYS and JOYSTICK - -The Apple 2 gameplay works only with a joystick since you cannot detect multiple -keys down on the Apple II. The UI works with the keyboard or joystick and the -world editor uses both. - -The joystick can also drive the menu's. Pressing right, for example, is -equivalent to pressing 1 (the UI menu options are selected through numbers). - -The menus all show the keys to advance. There's also a help screen in the -editor. - -5. THE FILES - -I tried to comment all the code very thoroughly in the CX16 version. Since this -version is derived from that version, the code is also well documented, but to -be honest, the comments may not always be accurate. I did not do a pass to see -if they are accurate. - -There are actually 2 programs in this. The 1st is the game, and it's in -src/apple2. - -* audio.inc - Routines to make the speaker beep -* defs.inc - Constants and definitions used throughout -* draw.inc - HGR buffer drawing. drawSprite, for example -* edit.inc - The built-in world editor -* file.inc - Load and Save code -* fontdata.inc - A ZX Spectrum font in reverse 8x8 - Apple II format -* game.inc - The in-game logic, AI etc. The bulk of the "game" -* input.inc - User controls for game and editor -* logo.hgr - 8Kb splash screen in HGR format -* logo.inc - File that simply does an incbin on logo.hgr -* logodata.inc - Line data for writing Penetrator and logo image data -* macros.inc - Print macros mostly -* penetrator.asm - Where the game starts, initial setup, etc. -* penetrator.cfg - ca65 configuration file -* rodata.inc - Read-only data such as lookup tables, sprites etc. -* terrain.inc - The terrain drawing routines -* text.inc - In game text and print functions -* trndata.inc - The world data (triplet - top, bottom and enemy pos) -* ui.inc - User facing screens, name input, etc. -* variables.inc - All non zero page variables (stats, scores, draw buffers) -* zpvars.inc - The zero page variables (most variables) - -The second is the ProDos loader that will auto-load the game. It's in the -src/apple2.loader folder. It has these files (all provided to me by Oliver -Schmidt) - -* loader.cfg - ca65 configuration file -* loader.s - file to load and start the game - -6. BUILDING THE GAME - -Making the game has a few steps. Use make and the Makefile on all OSs, that -would be the easiest. - -Start by making the loader - this needs to be done once only. -make TARGETS=apple2.loader - -Next, make the game with: -make - -The next step is to make a bootable disk image. For this, you will need 3rd -party software. I use AppleCommander. This software will put the loader and -game into the disk image. You will need to install Java to use AppleCommander. - -The apple2/template.dsk is a "blank ProDos floppy" that has the loader and the -game placed on it by AppleCommander. - -To make the disc image, set an environment variable to point at apple commander -(see notes) and then use the command: -make dsk - -This will make a disc named Penetrator.dsk which can be loaded up in an -emulator. - -If you want to edit the code and get into some iterative development/testing, -you can edit the Makefile and fill in the commands commands neccesary to launch -an emulator as well. Look for apple2_EMUCMD and set that as neccesary. The -simplest is to call test.sh or test.bat and fill in a complete command in the -batch file or shell script. However you choose to do this, once done, you can -do everything with the command: -make dsk test - -NOTES: -1) Find AppleCommander here (I used Version 1.5.0): -https://github.com/AppleCommander/AppleCommander/releases -2) Set the environment variable (or change the Makefile-dsk.md) to point at the -apple commander jar file. Here's how it's done for different shell's: - Powershell: - $env:AC = "path to apple commander.jar" - cmd.exe - set AC="path to apple commander.jar" - bash (Unix or MacOS terminal): - export AC="path to apple commander.jar" - -7. CREDITS - -* Phillip Mitchell and Beam Software for creating and publishing the game in - 1982. -* A special call-out to Oliver Schmidt who provided me with invaluable - assistance to get me going on the Apple II. -* Everyone involved in the Apple II projects (AppleWin | AppleCommander). -* Everyone involved in making the cc65 tools, it's very good. - -8. CONTACT - -Feel free to contact me at swessels@email.com if you have thoughts or -suggestions. - -Thank you -Stefan Wessels -16 December 2019 - Initial Revision +This project has moved to my original penetrator remake on GitHub. There are a few other versions consolidated in there now as well. + +[penetrator for apple 2's new home](https://github.com/StewBC/penetrator) diff --git a/apple2/template.dsk b/apple2/template.dsk deleted file mode 100644 index 230723a..0000000 Binary files a/apple2/template.dsk and /dev/null differ diff --git a/src/apple2.loader/loader.cfg b/src/apple2.loader/loader.cfg deleted file mode 100644 index d2087a5..0000000 --- a/src/apple2.loader/loader.cfg +++ /dev/null @@ -1,14 +0,0 @@ -################################################################################# -# # -# LOADER.SYSTEM - an Apple][ ProDOS 8 loader for cc65 programs (Oliver Schmidt) # -# # -################################################################################# - -MEMORY { - LOADER: start = $2000, size = $0200, file = %O; -} - -SEGMENTS { - CODE: load = LOADER, type = ro; - DATA: load = LOADER, type = rw; -} diff --git a/src/apple2.loader/loader.s b/src/apple2.loader/loader.s deleted file mode 100644 index 22d7946..0000000 --- a/src/apple2.loader/loader.s +++ /dev/null @@ -1,179 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; ; -; LOADER.SYSTEM - an Apple][ ProDOS 8 loader for cc65 programs (Oliver Schmidt) ; -; ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -A1L := $3C -A1H := $3D -PATHNAME := $0280 -MLI := $BF00 -TXTCLR := $C050 ; Display graphics -TXTSET := $C051 ; Display text -MIXCLR := $C052 ; Disable 4 lines of text -LOWSCR := $C054 ; Page 1 -HISCR := $C055 ; Page 2 -HIRES := $C057 ; Hires graphics -VERSION := $FBB3 -RDKEY := $FD0C -PRBYTE := $FDDA -COUT := $FDED - -QUIT_CALL = $65 -OPEN_CALL = $C8 -READ_CALL = $CA -CLOSE_CALL = $CC - -FILE_NOT_FOUND_ERR = $46 - -; ------------------------------------------------------------------------ - - .data - -OPEN_PARAM: - .byte $03 ;PARAM_COUNT - .addr PATHNAME ;PATHNAME - .addr $4000 - $0400 ;IO_BUFFER -OPEN_REF: .byte $00 ;REF_NUM - -READ_PARAM: - .byte $04 ;PARAM_COUNT -READ_REF: .byte $00 ;REF_NUM - .addr $4000 ;DATA_BUFFER - .word $FFFF ;REQUEST_COUNT - .word $0000 ;TRANS_COUNT - -CLOSE_PARAM: - .byte $01 ;PARAM_COUNT -CLOSE_REF: .byte $00 ;REF_NUM - -QUIT_PARAM: - .byte $04 ;PARAM_COUNT - .byte $00 ;QUIT_TYPE - .word $0000 ;RESERVED - .byte $00 ;RESERVED - .word $0000 ;RESERVED - -LOADING: - .byte $0D - .asciiz "Loading " - -ELLIPSES: - .byte " ...", $0D, $0D, $00 - -FILE_NOT_FOUND: - .asciiz "... File Not Found" - -ERROR_NUMBER: - .asciiz "... Error $" - -PRESS_ANY_KEY: - .asciiz " - Press Any Key " - -; ------------------------------------------------------------------------ - - .code - - ; Reset stack - ldx #$FF - txs - - ; Remove ".SYSTEM" from pathname - lda PATHNAME - sec - sbc #.strlen(".SYSTEM") - sta PATHNAME - - ; Add trailing '\0' to pathname - tax - lda #$00 - sta PATHNAME+1,x - - ; Provide some user feedback - lda #LOADING - jsr PRINT - lda #<(PATHNAME+1) - ldx #>(PATHNAME+1) - jsr PRINT - lda #ELLIPSES - jsr PRINT - - jsr MLI - .byte OPEN_CALL - .word OPEN_PARAM - bcc :+ - jmp ERROR - - ; Copy file reference number -: lda OPEN_REF - sta READ_REF - sta CLOSE_REF - - ; Turn off 80-column firmware - lda VERSION - cmp #$06 ; //e ? - bne :+ - lda #$15 - jsr $C300 - - ; Switch to hires page 2 -: bit TXTCLR - bit MIXCLR - bit HISCR - bit HIRES - - jsr MLI - .byte READ_CALL - .word READ_PARAM - bcs ERROR - - jsr MLI - .byte CLOSE_CALL - .word CLOSE_PARAM - bcs ERROR - - ; Go for it ... - jmp $6000 - -PRINT: - sta A1L - stx A1H - ldx VERSION - ldy #$00 -: lda (A1L),y - beq :++ - cpx #$06 ; //e ? - beq :+ - cmp #$60 ; lowercase ? - bcc :+ - and #$5F ; -> uppercase -: ora #$80 - jsr COUT - iny - bne :-- ; Branch always -: rts - -ERROR: - bit TXTSET - bit LOWSCR - cmp #FILE_NOT_FOUND_ERR - bne :+ - lda #FILE_NOT_FOUND - jsr PRINT - beq :++ ; Branch always -: pha - lda #ERROR_NUMBER - jsr PRINT - pla - jsr PRBYTE -: lda #PRESS_ANY_KEY - jsr PRINT - jsr RDKEY - jsr MLI - .byte QUIT_CALL - .word QUIT_PARAM diff --git a/src/apple2/audio.inc b/src/apple2/audio.inc deleted file mode 100644 index 09d12b5..0000000 --- a/src/apple2/audio.inc +++ /dev/null @@ -1,114 +0,0 @@ -;----------------------------------------------------------------------------- -; audio.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2020 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "CODE" - -;----------------------------------------------------------------------------- -.proc serviceAudio - - lda audioMask ; get the active channels - and audioFrame ; see if any channel needs to play this frame - bne makeSounds ; make a sound if a channel needs audio - rts - -makeSounds: - bit Bit7Mask ; AUDIO_EXPLOSION - bne bombDrop - - bit Bit6Mask ; AUDIO_FIRE - bne fire - - bit Bit5Mask ; AUDIO_EXPLOSION - bne explosion - - bit Bit8432Mask ; AUDIO_ENGINE - Not that bit 8 is erroneusly checked - bne engine ; only because I didn't want to make a new constant - - bit Bit1Mask ; AUDIO_UI_TICK - bne ui - - rts - -explosion: - ldy audioExplFrame ; use the frame as an index - lda explDelay, y - tax - ldy #$6 - jsr playNote - - inc audioExplFrame ; make sure off-screen ticks to end - lda audioExplFrame - cmp #%00000011 - bcc :+ - lda #AUDIO_MOTOR_PLAY - sta audioFrame ; turn off the explosion -: - rts - -bombDrop: - ldy #$30 - ldx #$10 - jmp playNote - -fire: - ldy #$20 - ldx #$10 - jmp playNote - -engine: - bit Bit4Mask ; AUDIO_MOTOR_FWD - beq :+ - ldy #$25 - ldx #$08 - jmp playNote -: - bit Bit3Mask ; AUDIO_MOTOR_REW - beq :+ - ldy #$35 - ldx #$08 - jmp playNote -: - ldy #$30 - ldx #$08 - jmp playNote - -ui: - ldy #$40 - ldx #$08 - jmp playNote - -.endproc - -;----------------------------------------------------------------------------- -.proc playNote - - delay = tempBlock + 21 - - sty delay - -loop: - lda SPEAKER - ldy delay -: - nop - nop - nop - nop - dey - bne :- ; hold for the duration in y - dex - bne loop ; retrigger - - lda #AUDIO_EXPLOSION ; reset the audio frame (serviced) - and audioFrame ; but keep explosion if it was set - ora #AUDIO_MOTOR_PLAY ; and always add the MOTOR - sta audioFrame - - rts - -.endproc diff --git a/src/apple2/defs.inc b/src/apple2/defs.inc deleted file mode 100644 index e43fa41..0000000 --- a/src/apple2/defs.inc +++ /dev/null @@ -1,124 +0,0 @@ -;----------------------------------------------------------------------------- -; defs.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -; System locations -PATHNAME = $0280 - -ram_layer0 = $2000 ; HGR Pages -ram_layer1 = $4000 - -MLI = $BF00 ; ProDOS API -SPEAKER = $C030 ; Access to toggle the speaker -PADDL0 = $C064 ; Read to get POT -PTRIG = $C070 ; Reset PADDLE values - -;----------------------------------------------------------------------------- -; MLI call type bytes -QUIT_CALL = $65 -OPEN_CALL = $C8 -READ_CALL = $CA -WRITE_CALL = $CB -CLOSE_CALL = $CC -CREATE_CALL = $C0 - -;----------------------------------------------------------------------------- -; self-modifying address marker -PLACEHOLDER = $FFFF - -;----------------------------------------------------------------------------- -; modes -GAME_MODE_PLAY = $00 -GAME_MODE_TRAIN = $01 -GAME_MODE_EDIT = $02 - -BRUSH_TERRAIN = $00 -BRUSH_ENEMIES = $01 - -;----------------------------------------------------------------------------- -; digital input constants -KEY_RIGHT = %00000001 -KEY_LEFT = %00000010 -KEY_DOWN = %00000100 -KEY_UP = %00001000 -KEY_START = %00010000 -KEY_SELECT = %00100000 -KEY_FIRE = %01000000 -KEY_BOMB = %10000000 - -;----------------------------------------------------------------------------- -; game constants -XINSET = 4 ; By how many BYTE cols the display is offset into X -XSIZE = (80 - (4 * XINSET)) ; columns on screen (1 BYTE col = 2 game cols) -YSIZE = 192 ; lines on screen - -WORLD_START = $08 ; top line where world is drawn -WORLD_END = $B3 ; last line where world is drawn -BUFLENGTH = $100 ; size for buffers that hold enemies - -NUM_LIVES = 5 ; How many lives to start with -NUM_STAGES = 5 -NUM_BOMBS = 2 ; How many bombs the player can drop -NUM_INFLIGHT = 3 ; How many missiles can be in-flight at once -NUM_SKIP_MONST = 4 ; How many rockets to skip before making one a monster - -DANGER_FONT = 4 ; Number of font characters that make one filled column -DANGER_LENGTH = ((textEnd-1)-textDangerBar) ; how many characters in the danger column (skip trailing 0) -DANGER_TICKS = ((((worldDataEnd-worldDataStart) / 3) / DANGER_LENGTH) / DANGER_FONT) - -; audio constants -AUDIO_BOMB_DROP = %01000000 ; Releasing a bomb -AUDIO_FIRE = %00100000 ; Firing the gun -AUDIO_EXPLOSION = %00010000 ; An enemy exploding -AUDIO_MOTOR_FWD = %00001000 ; Speeding up -AUDIO_MOTOR_REW = %00000100 ; slowing down -AUDIO_MOTOR_PLAY = %00000010 ; flying at a constant speed -AUDIO_UI_TICK = %00000001 ; UI selection - -; The enemyBuffer is filled with these values, which break down as: -; -; Bits 1 & 2 - Type. 0 - monster, 1 - missile, 2 - radar & 3 - nuke -; Bits 3 & 4 - Column of sprite - Missile 2 wide, radar 4 wide, etc. -; Bits 5, 6 & 7 - Animation frame number, 0 - 7 (Radar has 8 frames) -; Bit 8 - 1 - Flying, 0 - on ground -; -; For monsters, Bits 5, 6 and 7 mean the following: -; Monster Bit 5 - Direction - 0 is up and 1 is down -; Monster Bit 6 & 7 - The delay counter while it is stopped. 0 - moving, <> 0 paused -; -; All 0 means empty, no enemy at that location - -SPR_MONSTER0 = %10000000 ; enemy buffer mask MONSTER left -SPR_MONSTER1 = %10000100 ; enemy buffer mask MONSTER col 2 -SPR_MONSTER2 = %10001000 ; enemy buffer mask MONSTER right -SPR_MISSILE0 = %00000001 ; enemy buffer mask missile left -SPR_MISSILE1 = %00000101 ; enemy buffer mask missile right -SPR_RADAR0 = %00000010 ; enemy buffer mask radar left -SPR_RADAR1 = %00000110 ; enemy buffer mask radar col 2 -SPR_RADAR2 = %00001010 ; enemy buffer mask radar col 3 -SPR_RADAR3 = %00001110 ; enemy buffer mask radar right -SPR_NUKE0 = %00000011 ; enemy buffer mask nuke left -SPR_NUKE1 = %00000111 ; enemy buffer mask nuke right - -MONSTER_HEIGHT = 13 ; rows in monster sprite -MONSTER_WIDTH = 3 ; cols in monster sprite -MONSTER_SPEED = 4 ; speed at which monster moves (in rows) - -MISSILE_HEIGHT = 14 ; rows in missile sprite - -RADAR_HEIGHT = 16 ; rows in radar sprite - -NUKE_HEIGHT = 8 ; rows in nuke sprite - -EXPLOSION_HEIGHT = 16 ; rows in explosion sprite - -BOMB_HEIGHT = 6 ; rows in bomb sprite -BOMB_FRWRD_FRMS = 6 ; horz bomb travel duration - -SHIP_HEIGHT = 12 ; rows in player ship sprite -SHIP_WIDTH = 4 ; cols in player ship sprite -SHIP_START = 16 ; height above world where ship starts diff --git a/src/apple2/draw.inc b/src/apple2/draw.inc deleted file mode 100644 index 67a0a20..0000000 --- a/src/apple2/draw.inc +++ /dev/null @@ -1,1130 +0,0 @@ -;----------------------------------------------------------------------------- -; draw.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "CODE" - -;----------------------------------------------------------------------------- -; turns layers on and off so that the backLayer is hidden and the other -; layer is visible to the user -.proc drawPresent - - lda backLayer - eor #1 - sta backLayer - beq :+ - - bit LOWSCR - lda #>ram_layer1 - sta zVramH - rts - -: - bit HISCR ; Page 2 - lda #>ram_layer0 - sta zVramH - rts - -.endproc - -;----------------------------------------------------------------------------- -; Clears the world area -.proc drawClearRows - - lda #$00 - ldx #(XSIZE/2) - - ldy backLayer - beq layer0 - jmp layer1 - -layer0: - .repeat $B0, Row - sta XINSET + $100 * ($20 + (Row + 8) & $07 << 2 | (Row + 8) & $30 >> 4) | (Row + 8) & $08 << 4 | (Row + 8) & $C0 >> 1 | (Row + 8) & $C0 >> 3, x - .endrepeat - dex - bmi done0 - jmp layer0 - -done0: - rts - -layer1: - .repeat $B0, Row - sta XINSET + $100 * ($40 + (Row + 8) & $07 << 2 | (Row + 8) & $30 >> 4) | (Row + 8) & $08 << 4 | (Row + 8) & $C0 >> 1 | (Row + 8) & $C0 >> 3, x - .endrepeat - dex - bmi done1 - jmp layer1 - -done1: - rts - -.endproc - -;----------------------------------------------------------------------------- -.proc drawClearScreen - - lda #0 - tax -: - .repeat $20, B - sta ram_layer0+(B*256), x - sta ram_layer1+(B*256), x - .endrep - dex - beq done - jmp :- -done: - rts - -.endproc - -;----------------------------------------------------------------------------- -; Invert the visible screen (the user facing layer) -.proc drawInvertVisibleScreen - - scrnPtrL = tempBlock + 7 ; past uiWinScreen - scrnPtrH = tempBlock + 8 - - lda #0 - sta scrnPtrL - lda backLayer - eor #1 - tax - lda layersH, x - sta scrnPtrH - ldy #0 - ldx #$20 - -loop: - lda (scrnPtrL), y - eor #%01111111 - sta (scrnPtrL), y - dey - bne loop - inc scrnPtrH - dex - bne loop - - rts - -.endproc - -;----------------------------------------------------------------------------- -; Plot a square pixel -; Coords in x and y registers -; width and height in 1's but min "pixel" plot size is 4x4 pixels -.proc drawPlotXY - - width = tempBlock + 14 ; Param (local variables come after uiWriteName locals) - height = tempBlock + 15 ; Param - side = tempBlock + 16 ; Param - rows = tempBlock + 17 ; internal - x0 = tempBlock + 18 ; internal - iWidth = tempBlock + 19 ; internal - - txa ; x pos in a - lsr ; go from 80 to 40, odd in carry - sta x0 ; save the x - lda #0 - rol ; get carry into a - sta side ; stor this as which "side" of the byte is active - - tya ; y * 4 since min width is 4 pixels wide, height must be min 4 as well - asl - asl - tay ; put the draw height in Y - - lda height ; Adjust the height up by 4x as well - asl - asl - sta rows ; save as count for how many rows - -loop: - clc - lda rowL, y - adc x0 ; get the x y address set up - sta write + 1 - sta write + 4 - lda rowH, y - adc zVramH - sta write + 2 - sta write + 5 - - ldx width ; Write 0 to (width-1) - dex - stx iWidth ; save as the offset index -store: - txa ; take the index - clc - adc side ; add the side - and #1 ; and with 1 to see what byte to use - tax ; x now 0 ot 1 - lda plotPix, x ; and load the byte to use - pha ; save for later - lda iWidth ; index to write tp - clc - adc side ; add side to that as well - lsr ; turn into a column - tax ; and put the index offset into x - pla ; and get back the value to write to the column -write: - ora PLACEHOLDER, x ; merge with the other half of the column - sta PLACEHOLDER, x ; and write that into the column - dec iWidth ; step back 1 column - ldx iWidth ; and load that into x - bpl store ; and if x < 0 then 0 to (width-1) was written - iny ; fo to next row down - dec rows ; all rows were written - bne loop - - rts - -.endproc - -;----------------------------------------------------------------------------- -; Generic routine to draw a sprite rect to the screen. Sets zCollision <> 0 -; when the pixels from this sprite overlapped with pixels already drawn -; Parameters - see zaDraw* below -.proc drawSprite - - zaDrawWorldHeight = tempBlock + 2 ; parameter - where on screen - zaDrawSprHeight = tempBlock + 5 ; parameter - # of rows in sprite - zaDrawSprWidth = tempBlock + 3 ; parameter - # of columns in sprite - zaScreenColLocal = tempBlock + 4 ; not a parameter - internal for drawing - zaDrawByte = tempBlock + 6 ; not a parameter - internal for collisions - zaDataWidth = tempBlock + 8 ; not a parameter - internal for collisions - - lda zScreenCol ; make a copy since it needs to be modified - lsr ; 80 to 40 - sta zaScreenColLocal - - ldy zaDrawWorldHeight - cpy #WORLD_START - bcc done - -rows: - clc - ldx zaDrawSprWidth - lda rowL, y ; get the screen row start address, low byte - adc zaScreenColLocal ; add the column to the address - sta write + 1 ; set eor low address - sta write + 4 ; set sta low address - lda rowH, y ; get the high byte of the screen row start - adc zVramH ; add the VRAM high byte (for which layer) - sta write + 2 ; set the eor hi - sta write + 5 ; set the sta hi -offset: - lda PLACEHOLDER, x ; this address is modified by the caller - sta zaDrawByte ; save the byte -write: - eor PLACEHOLDER,x ; get what's on screen xor'd with what's being added - sta PLACEHOLDER,x ; save that to the screen - and zaDrawByte ; mask off any bits that the sprite isn't setting - cmp zaDrawByte ; see if the sprite overlapped something there already - clc ; cmp can set carry. keep it clear - beq :+ ; if 0 then no overlap / collision - inc zCollision ; there's a collision, count it -: - dex - bpl offset - dec zaDrawSprHeight - beq done - dey ; go up a row on screen - cpy #WORLD_START - bcc done - clc - lda zaDataWidth - adc offset + 1 - sta offset + 1 - bcc rows - inc offset + 2 - bne rows - -done: - rts - -.endproc - -;----------------------------------------------------------------------------- -; Draws the player's ship using drawSprite -; Takes no parameters -.proc drawPlayer - - - zaDrawWorldHeight = tempBlock + 2 - zaDrawSprHeight = tempBlock + 5 - zaDrawSprWidth = tempBlock + 3 - zaDataWidth = tempBlock + 8 - explFrame = tempBlock + 9 ; Persistent across a death animation - explosion explFrame - - lda playerShipY - sta zaDrawWorldHeight - - lda #SHIP_HEIGHT - sta zaDrawSprHeight - - lda playerShipX ; mark where on screen to draw - sta zScreenCol - clc - adc bufferDraw ; make enemyBuffer relative to screen col 0 - sta zEnemyCol ; mark where enemies would start that intersect with the ship - - lda playerDead ; if playerDead <> 0 then the player - bne explode ; is dead and should explode - - lda zScreenCol - and #1 - beq evenScreen - -oddScreen: - lda #3 ; set the dimensions of the ship to draw - sta zaDrawSprWidth - lda #4 - sta zaDataWidth - - - lda #shipU - sta drawSprite::offset + 2 - bne draw - -evenScreen: - lda #2 ; set the dimensions of the ship - sta zaDrawSprWidth - lda #3 - sta zaDataWidth - - lda #shipA - sta drawSprite::offset + 2 - -draw: - jsr drawSprite ; draw the sprite - lda zCollision ; if there's a collision, kill the player - beq done - - ldx zEnemyCol ; player collided - see if it was with an enemy - ldy #SHIP_WIDTH - -colLoop: - lda playerShipY ; if p ship top < enemy.bot then no collision - sec - sbc #SHIP_HEIGHT - cmp enemyHgtBuffer, x - bcs notHit - sec - lda enemyHgtBuffer, x ; if enemy top < p ship bot then no collision - sbc #RADAR_HEIGHT - cmp playerShipY - bcs notHit - - lda #1 ; they intersect so kill the enemy (assume just 1 enemy hit) - sta zaDrawSprWidth - jsr gameKillEnemy ; kill the enemy that collided with the player - jmp gamePlayerCollision ; and kill the player if it collided with an enemy - -notHit: - inc zEnemyCol ; advance the column where the enemy may be that collided with the player - inx - dey ; check all columns for the player ship - bne colLoop - jmp gamePlayerCollision ; and if no enemy collision, just kill the player - -done: - rts - -explode: - inc explFrame ; advance the local explFrame counter - lda explFrame - lsr ; Slow it down - tax ; and see if it is .ge. 4 - cpx #4 - bcc :+ - ldx #0 ; if so, wrap back to zero - stx explFrame - -: - stx audioExplFrame - lda audioFrame - ora #AUDIO_EXPLOSION - sta audioFrame - - lda #3 ; set a nonsense width to make the explosion - sta zaDataWidth ; not so recognizable - - lda #3 ; set the dimensions of the explosion - sta zaDrawSprWidth - - lda explosionAL,x ; point at the explosion sprite data - sta drawSprite::offset + 1 - lda explosionAH,x - sta drawSprite::offset + 2 - - jmp drawSprite ; draw the explosion sprite instead of the ship - -.endproc - -;----------------------------------------------------------------------------- -; Draws a single column of a radar sprite (because of clipping) -; Takes the enemy flags as a parameter -; Radar is either 2 byte AB (A being col 0 & 1 and B being 2 & 3) or -; 3 byte CDE where C is blank & 0, D is 1 & 2 and E is 3 and blank) -; On odd, the column can only be 00 because odd 1 is drawn by even A, -; odd 2 is drawn by even 1 (D) and odd 3 is drawn by even B. -; Even can be 0 (A), 1(D), 2(B) or 3(E) -.proc drawRadar - - zaFrame = tempBlock + 6 ; internal - zaDrawWorldHeight = tempBlock + 2 ; setup for drawSprite - zaDrawSprHeight = tempBlock + 5 - zaDrawSprWidth = tempBlock + 3 - zaDataWidth = tempBlock + 8 - zaSkipLength = tempBlock + 7 - - and #%01111100 ; frame and column - lsr ; column to 1s - lsr - sta zaFrame ; save - - lda enemyHgtBuffer, x ; get the height - 1 pixel above the terrain - sta zaDrawWorldHeight - - lda #RADAR_HEIGHT - sta zaDrawSprHeight - - lda zScreenCol ; see if it's an even or odd sceeen sub-column - and #$01 - beq evenScreen - -oddScreen: - lda #3 ; odd radar is 3 bytes - sta zaDataWidth ; that's how many bytes between sprite rows - - lda #(XSIZE-1) ; check the right edge - sec ; for clipping - sbc zScreenCol - lsr - cmp #3 - bcc :+ - lda #2 ; maximum 3 (0-2) bytes to write -: - sta zaDrawSprWidth - - lda zaFrame ; ignore column - will/must be 00 - lsr - lsr - tax - lda radarUL, x ; get the frame - sta drawSprite::offset + 1 - lda radarUH, x - sta drawSprite::offset + 2 - lda #4 ; snd set the step size - sta zaSkipLength - bne draw - -evenScreen: - ldx zaFrame ; frame + col is offset in table - lda radarAL, x ; point at data in table index x - sta drawSprite::offset + 1 - lda radarAH, x - sta drawSprite::offset + 2 - txa - and #%00000011 ; extract just the column - tax - lda radarAS, x ; and see how many bytes to skip based on column - sta zaSkipLength - lda radarAD, x ; see how wide this sprite is - sta zaDataWidth - lda radarAR, x ; see how many bytes to render - sta zaDrawSprWidth - - lda zScreenCol - cmp #(XSIZE - 2) ; last column only draw 1 byte - bcc draw - lda #0 - sta zaDrawSprWidth ; save as draw width - -draw: - jmp drawSprite - -.endproc - -;----------------------------------------------------------------------------- -; Draws a missile on-screen -; Takes the flags as a parameter -.proc drawMissile - - zaFrame = tempBlock + 6 ; internal - zaDrawWorldHeight = tempBlock + 2 ; setup for drawSprite - zaDrawSprHeight = tempBlock + 5 - zaDrawSprWidth = tempBlock + 3 - zaDataWidth = tempBlock + 8 - zaSkipLength = tempBlock + 7 - - tay - - lda enemyHgtBuffer, x ; get the height - 1 pixel above the terrain - sta zaDrawWorldHeight ; while x is still good - - tya - and #%11000100 ; launch mask, frame and column - lsr ; column to 2s - bit Bit76Mask ; check if in the air - beq :+ - ora #%00000001 ; yes - force frame 1 -: - and #%00000011 - tax - - lda #MISSILE_HEIGHT - sta zaDrawSprHeight - - lda zScreenCol ; see if it's an even or odd sceeen sub-column - and #$01 - beq evenScreen - -oddScreen: - lda #2 ; odd missile is 2 bytes - sta zaDataWidth ; that's how many bytes between sprite rows - - lda zScreenCol - cmp #(XSIZE-1) - bne :+ - lda #0 - beq :++ -: - lda #1 -: - sta zaDrawSprWidth - - lda missileUL, x ; point at data in table index x - sta drawSprite::offset + 1 - lda missileUH, x - sta drawSprite::offset + 2 - lda #2 - sta zaSkipLength - bne draw - -evenScreen: - lda missileAL, x ; point at data in table index x - sta drawSprite::offset + 1 - lda missileAH, x - sta drawSprite::offset + 2 - - lda #1 ; and see how many bytes to skip based on column - sta zaSkipLength - lda missileAD, x ; see how wide this sprite is - sta zaDataWidth - lda #0 - sta zaDrawSprWidth ; save as draw width - -draw: - jmp drawSprite - -.endproc - -;----------------------------------------------------------------------------- -; Draws a nuke on-screen -; Takes the flags as a parameter -.proc drawNuke - - zaFrame = tempBlock + 6 ; internal - zaDrawWorldHeight = tempBlock + 2 ; setup for drawSprite - zaDrawSprHeight = tempBlock + 5 - zaDrawSprWidth = tempBlock + 3 - zaDataWidth = tempBlock + 8 - zaSkipLength = tempBlock + 7 - - tay - - lda enemyHgtBuffer, x ; get the height - 1 pixel above the terrain - sta zaDrawWorldHeight ; while x is still good - - tya - ldx #0 - bit Bit3Mask - beq :+ - inx - -: - lda #NUKE_HEIGHT - sta zaDrawSprHeight - - lda zScreenCol ; see if it's an even or odd sceeen sub-column - and #$01 - beq evenScreen - -oddScreen: - lda #2 ; odd nuke is 2 bytes - sta zaDataWidth ; that's how many bytes between sprite rows - - lda zScreenCol ; see if clipping to right hand side is needed - cmp #(XSIZE-1) - bne :+ - lda #0 - beq :++ -: - lda #1 -: - sta zaDrawSprWidth ; save how many bytes to render - - lda nukeUL, x ; point at data in table index x - sta drawSprite::offset + 1 - lda nukeUH, x - sta drawSprite::offset + 2 - - lda #2 ; odd screen nuke is 2 bytes (col can't be 1) - sta zaSkipLength - bne draw - -evenScreen: - lda nukeAD, x ; see how wide this sprite is - sta zaDataWidth - - lda #0 - sta zaDrawSprWidth ; save as draw width - - lda nukeAL, x ; point at data in table index x - sta drawSprite::offset + 1 - lda nukeAH, x - sta drawSprite::offset + 2 - - lda #1 ; even screen nuke is 1 byte (col 0 or 1) - sta zaSkipLength - -draw: - jmp drawSprite - -.endproc - -;----------------------------------------------------------------------------- -; Takes the flags as a parameter -.proc drawMonster - - zaFrame = tempBlock + 6 ; internal - zaDrawWorldHeight = tempBlock + 2 ; setup for drawSprite - zaDrawSprHeight = tempBlock + 5 - zaDrawSprWidth = tempBlock + 3 - zaDataWidth = tempBlock + 8 - zaSkipLength = tempBlock + 7 - - tay - - lda enemyHgtBuffer, x ; get the height - 1 pixel above the terrain - sta zaDrawWorldHeight ; while x is still good - - lda #2 ; monster is always 2 bytes - sta zaDataWidth ; that's how many bytes between sprite rows - - tya - lsr - lsr - and #%00000011 - tax - - lda #MONSTER_HEIGHT - sta zaDrawSprHeight - - lda zScreenCol ; see if it's an even or odd sceeen sub-column - and #$01 - beq evenScreen - -oddScreen: - lda zScreenCol ; see if clipping to right hand side is needed - cmp #(XSIZE-1) - bne :+ - lda #0 - beq :++ -: - lda #1 -: - sta zaDrawSprWidth ; save how many bytes to render - - lda #monsterU - sta drawSprite::offset + 2 - - lda #3 ; odd screen monster is 2 bytes (col can't be 1) - sta zaSkipLength - bne draw - -evenScreen: - lda monsterAR, x - sta zaDrawSprWidth ; save as draw width - - lda monsterAL, x ; point at data in table index x - sta drawSprite::offset + 1 - lda monsterAH, x - sta drawSprite::offset + 2 - - lda monsterAS, x ; even screen monster is 1 byte (col 0 or 1) - sta zaSkipLength - -draw: - jmp drawSprite - -.endproc - -;----------------------------------------------------------------------------- -; Draws all the bombs on-screen -; Takes no parameters -.proc drawBombs - - zaBombIndex = tempBlock + 1 ; internal - which of the bombs - zaDrawWorldHeight = tempBlock + 2 ; for drawSprite - zaDrawSprHeight = tempBlock + 5 - zaDrawSprWidth = tempBlock + 3 - zaDataWidth = tempBlock + 8 - - ldx #NUM_BOMBS - 1 ; 0 based index - -loop: - lda bombY, x ; get the height of the bomb - bne doBomb ; 0 is not active, otherwise height - -nextBomb: - dex - bpl loop - clc - rts - -doBomb: - stx zaBombIndex - sta zaDrawWorldHeight ; save the height - - lda bombX, x - sta zScreenCol - and #$01 - beq evenScreen - -oddScreen: - lda #1 - sta zaDrawSprWidth ; save as draw width - lda #2 - sta zaDataWidth - - lda bombDir, x ; select the sprite based on the state - tax - beq :+ ; if .gt. 0 then it's bomb 1 - ldx #1 -: - lda bombUL, x ; forward travelling bomb - sta drawSprite::offset + 1 - lda bombUH, x - sta drawSprite::offset + 2 - lda bombH, x - sta zaDrawSprHeight - bne draw - -evenScreen: - lda #0 - sta zaDrawSprWidth ; save as draw width - lda #1 - sta zaDataWidth - - lda bombDir, x ; select the sprite based on the state - tax - beq :+ - ldx #1 -: - lda bombAL, x ; forward travelling bomb - sta drawSprite::offset + 1 - lda bombAH, x - sta drawSprite::offset + 2 - lda bombH, x - sta zaDrawSprHeight - -draw: - jsr drawSprite - - lda zCollision - beq nextBombX - - lda zScreenCol - clc - adc bufferDraw ; make enemyBuffer relative to screen col 0 - tax - ldy #2 - -tryEnemy: - stx zEnemyCol ; may be a collision with enemy - lda enemyHgtBuffer, x ; is there an enemy in this row? - beq noBombHit ; no - maybe next column? - -checkCol: - sec - sbc #RADAR_HEIGHT ; assume tallest enemy (favors the player) - cmp zaDrawWorldHeight ; compare to bombY - bcs noBombHit ; E top .le. b bot (carry clear) is maybe collision - lda zaDrawWorldHeight ; get the bombY - sec - sbc #BOMB_HEIGHT ; calc bomb top - cmp enemyHgtBuffer, x ; B top .le. E bot (carry clear) is a collision - bcc bombHit - -noBombHit: - inx ; maybe bomb spans 2 cols - check next column - dey ; see if bomb is over 2 cols - beq bombDies ; if 0 done all columns - bne tryEnemy ; JuMP - -bombHit: - lda #1 ; enemy is in this 1 column - sta zaDrawSprWidth - - jsr gameKillEnemy ; see if the bomb killed an enemy - lda enemyHitType ; figure out if there's score - bmi bombDies - jsr gameAddScore - -bombDies: - ldx zaBombIndex - lda #0 ; now kill the bomb itself - sta bombY, x ; by setting its height to 0 - sta zCollision - -nextBombX: - ldx zaBombIndex - jmp nextBomb - -.endproc - - -;----------------------------------------------------------------------------- -.proc drawBullets - - zaOffset = tempBlock + 1 - zaDrawSprWidth = tempBlock + 3 - zaBulletCol = tempBlock + 5 - zaMask = tempBlock + 6 - - lda #0 ; work by screen columns - sta zScreenCol ; starting at 0 - - ldx bulletIndex ; x is the index for the bullet - -loop: - lda bulletsBuffer, x ; get the column - bne bullet ; and if non-zero, there's a bullet in this column - -next: - inx ; next x - inc zScreenCol ; and next screen column - lda zScreenCol ; see if the screen column is - cmp #XSIZE ; past the end of the screen - bcc loop ; if not, keep going - lda #0 - sta bulletsBuffer, x ; Kill any overflow bullets - inx - sta bulletsBuffer, x ; Kill any overflow bullets - clc ; done - clear carry and end - rts - -bullet: - stx zaBulletCol ; where the bullet starts - tay ; height now in Y - lda zScreenCol ; game column in a - tax ; save in x - lsr ; divide by 2 for byte position - clc ; lsr could set carry - adc rowL, y ; get the write locations set up - sta write + 1 - sta write + 4 - lda rowH, y - adc zVramH - sta write + 2 - sta write + 5 - - txa ; restore game col - and #1 ; test for odd/even - beq evenScreen ; and go appropriate - -oddScreen: - txa ; restore game column - cmp #(XSIZE - 1) ; see if it's at the right edge - bne :+ - ldx #1 - stx zaOffset ; set how many columns to check - ldx #0 ; will only write 1 byte, the last right col - lda #%01111000 - bne :++ -: - ldx #3 - stx zaOffset - ldx #1 ; write 2 bytes - lda #%01111111 ; the right col + the whole next byte (start there) -: - sta zaMask - bne write - -evenScreen: - txa ; restore game column - cmp #(XSIZE - 2) ; see if it's at the right edge even screen - bne :+ - ldx #2 - stx zaOffset - ldx #0 ; will only write 1 byte - lda #%01111111 ; the whole byte is a bullet - bne :++ -: - ldx #3 - stx zaOffset - ldx #1 ; write 2 bytes - lda #%00001111 ; the right col + the whole next byte (start there) -: - sta zaMask - -write: ; bullet is a solid line - eor PLACEHOLDER, x - sta PLACEHOLDER, x - and zaMask - cmp zaMask - bne collision - dex - bmi step - lda zaMask - cmp #%01111111 - beq :+ - lda #%01111111 - bne :++ -: - lda #%01111000 -: - sta zaMask - bne write - -step: ; setp past the bullet - inc zScreenCol ; and next screen column - ldx zaBulletCol - inx - jmp next ; this will step past second part of the bullet - -collision: - lda zScreenCol ; index into screem - clc - adc bufferDraw ; and make relative to enemy buffer - tay -: - lda enemyHgtBuffer, y - bne hasEnemy - iny - dec zaOffset - bpl :- - bmi endBullet - -hasEnemy: - ldx zaBulletCol ; load the bullet index in x - sec - sbc bulletsBuffer, x ; see where it hit relative to enemy - bcc endBullet ; bullet hit lower - cmp #RADAR_HEIGHT ; since it hit anyway, use tallest enemy - bcs endBullet ; it hit higher - - lda #1 - sta zaDrawSprWidth ; gameKillEnemy looks at this to see how wide to look for a kill - sty zEnemyCol - jsr gameKillEnemy - lda enemyHitType ; figure out if there's score - bmi endBullet - jsr gameAddScore - -endBullet: - ldx zaBulletCol ; load the bullet index in x - lda #0 - sta bulletsBuffer, x - beq step ; JuMP - -.endproc - -;----------------------------------------------------------------------------- -.proc drawExplosions - - zaFrame = tempBlock + 6 ; internal - zaDrawWorldHeight = tempBlock + 2 ; setup for drawSprite - zaDrawSprHeight = tempBlock + 5 - zaDrawSprWidth = tempBlock + 3 - zaDataWidth = tempBlock + 8 - zaExplodeCol = tempBlock + 10 - - lda #0 ; work by screen columns - sta zScreenCol ; starting at 0 - - ldx bufferDraw ; x is the index for the bullet - -loop: - lda explosionBuffer, x ; get the column - bne explode ; and if non-zero, there's a bullet in this column - -next: - inx ; next x - inc zScreenCol ; and next screen column - lda zScreenCol ; see if the screen column is - cmp #XSIZE ; past the end of the screen - bcc loop ; if not, keep going - lda #0 - sta zCollision - clc ; done - clear carry and end - rts - -explode: - stx zaExplodeCol - - pha - and #%00000011 ; frame - sta zaFrame ; save - - pla - and #%11111000 ; height - sta zaDrawWorldHeight - - lda #EXPLOSION_HEIGHT - sta zaDrawSprHeight - - lda zScreenCol ; see if it's an even or odd sceeen sub-column - and #$01 - beq evenScreen - -oddScreen: - lda #3 ; odd explosion is 3 bytes - sta zaDataWidth ; that's how many bytes between sprite rows - - lda #(XSIZE-1) ; check the right edge - sec ; for clipping - sbc zScreenCol - lsr - cmp #3 - bcc :+ - lda #2 ; maximum 3 (0-2) bytes to write -: - sta zaDrawSprWidth - - ldx zaFrame ; frame + col is offset in table - lda explosionUL, x ; get the frame - sta drawSprite::offset + 1 - lda explosionUH, x - sta drawSprite::offset + 2 - bne draw - -evenScreen: - lda #2 ; odd explosion is 3 bytes - sta zaDataWidth ; that's how many bytes between sprite rows - - ldx zaFrame ; frame + col is offset in table - lda explosionAL, x ; point at data in table index x - sta drawSprite::offset + 1 - lda explosionAH, x - sta drawSprite::offset + 2 - - lda zScreenCol - cmp #(XSIZE - 2) ; last column only draw 1 byte - bcc :+ - lda #0 - beq :++ -: - lda #1 -: - sta zaDrawSprWidth ; save as draw width - -draw: - jsr drawSprite - ldx zaExplodeCol - jmp next - -.endproc - -;----------------------------------------------------------------------------- -; Iterate over the enemies on screen and get them drawn to the back buffer -; Parameter - zCollision must be 0 when called -.proc drawEnemies - - zaEnemyType = tempBlock + 1 ; parameter to the specific enemy draw call - zaDrawSprWidth = tempBlock + 3 - zaSkipLength = tempBlock + 7 - - lda terrainOrigin ; will always be 0 since this isn't called till screen fully scrolled in - sta zScreenCol ; start drawing here on-screen - - ldx bufferDraw ; make enemyBuffer relative to screen col 0 - stx zEnemyCol ; start here processing enemies - -loop: - lda enemyBuffer, x ; check this column for a (partial) enemy (just a strip) - beq continue ; skip non-enemy columns - - sta zaEnemyType ; save the flags - - bit Bit34Mask ; check the column - beq evalType ; col0 always evaluated - lda zScreenCol ; Get the column - bit Bit1Mask ; see if odd or even - bne continue ; if odd, ignore - lda zaEnemyType ; if even, need to draw type - -evalType: - bit Bit1Mask ; see if this is a missile (lsb set) - bne missileOrNuke ; bits match so it's a missile - - bit Bit2Mask ; see if it's a radar - bne doRadar - - jsr drawMonster ; lower 2 bits clear is a monster - bcc colchk ; drawSprite always exits with carry clear so this is a jmp - -doRadar: - jsr drawRadar - bcc colchk ; will always be clear, so in effect jmp - -missileOrNuke: - bit Bit2Mask - beq missile - jsr drawNuke - bcc colchk ; JuMP - -missile: - jsr drawMissile - -colchk: - lda gameMode ; in the edit mode, collision detection doesn't do anything - cmp #GAME_MODE_EDIT - clc - beq step - lda zCollision ; see if this enemy is in collision (for missiles with terrain) - beq step - inc zaDrawSprWidth - jsr gameKillEnemy - -step: - lda zaSkipLength - adc zScreenCol - cmp #XSIZE - bcs done - sta zScreenCol - clc - lda zaSkipLength - adc zEnemyCol - sta zEnemyCol - tax - jmp loop - -continue: - inc zScreenCol - ldx zScreenCol - cpx #XSIZE - bcs done - inc zEnemyCol - ldx zEnemyCol - jmp loop - -done: - rts - -.endproc diff --git a/src/apple2/edit.inc b/src/apple2/edit.inc deleted file mode 100644 index 17fd267..0000000 --- a/src/apple2/edit.inc +++ /dev/null @@ -1,590 +0,0 @@ -;----------------------------------------------------------------------------- -; edit.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "CODE" - -;----------------------------------------------------------------------------- -.proc editLoop - - jsr drawClearScreen ; make sure the screen is clear before adjusting the - - jsr editInit - jsr editLoadStage - lda #2 - sta updateHUD - -loop: - jsr inputEdit - beq :+ - jsr editHandleKeys - lda pause ; pause is quit flag in endit - beq :+ - rts -: - clc - jsr terrainShow ; show terrain 1st because it collides with nothing - jsr drawEnemies ; enemies collide with nothing in edit mode - jsr editDrawCursor - lda updateHUD - beq :+ - jsr uiShowEditLabels -: - jsr drawPresent ; flip layers 0/1 (bring backLayer to visible) - - jmp loop - -.endproc - -;----------------------------------------------------------------------------- -.proc editHandleKeys - - cmp #'6' ; 6 or bigger - not a stage command - bcs notnum - cmp #'1' ; less than 1 - not a stage command - bcc notnum - sbc #'1' ; stages are 0 based - sta stage - - lda #AUDIO_UI_TICK ; make a sound - sta audioFrame - jsr serviceAudio - - lda #0 ; reset where the buffers will start - sta bufferInsert - jsr drawClearScreen - jsr editLoadStage ; get the right stage at the right place - jmp uiShowEditLabels ; update the HUD - -notnum: - cmp #$1b ; ESC key - bne notQuit - - lda #AUDIO_UI_TICK ; make a sound - sta audioFrame - jsr serviceAudio - - lda #1 - sta pause ; abuse pause to signal quit - rts - -notQuit: - cmp #'c' ; c or C for help - beq help - cmp #'C' - bne notHelp - -help: - lda #AUDIO_UI_TICK ; make a sound - sta audioFrame - jsr serviceAudio - - jmp uiShowEditHelp - -notHelp: - cmp #'s' ; s or S for save - beq save - cmp #'S' - bne notSave - -save: - lda #AUDIO_UI_TICK ; make a sound - sta audioFrame - jsr serviceAudio - - lda #0 ; a 0 is save - jsr uiFileLoadSave - jmp editLoop - -notSave: - cmp #'l' ; l or L for load - beq load - cmp #'L' - bne done - -load: - lda #AUDIO_UI_TICK ; make a sound - sta audioFrame - jsr serviceAudio - - lda #1 ; a 1 is load - jsr uiFileLoadSave - jmp editLoop - -done: - clc - rts - -.endproc - -;----------------------------------------------------------------------------- -; Move the world left (feels like YOU are moving right) -; will update the stage when a stage boundary is crossed and will then -; update the HUD -.proc editGameWorldRight - - zaWorldPtr = tempBlock + 14 ; 2 bytes for a ptr - - lda stage ; only scroll right while the stage - cmp #4 ; isn't 5 (0 based so 4). Stage 5 - bcc :+ ; cannot be edited - rts -: - jsr gameWorldMove ; use the game move code - - lda zWorldPtr + 1 ; but then calculate a point where the stage marker might be - sta zaWorldPtr + 1 - lda zWorldPtr - sec - sbc #((XSIZE+3)*3) - sta zaWorldPtr - bcs :+ - dec zaWorldPtr + 1 - -: - ldy #2 ; and read the enemy byte - lda (zaWorldPtr), y - bit Bit7Mask ; and see if this is a stage change - beq :+ - inc stage ; bit was set so change stage - lda #2 ; and update the HUD - sta updateHUD -: - inc bufferDraw ; the bufferDraw (col 0) is also one more to the right - rts - -.endproc - -;----------------------------------------------------------------------------- -; Scroll to the left, updating the stage boundary and adding enemies as needed. -.proc editGameWorldLeft - - leftWorldPtr = tempBlock + 14 - - lda zWorldPtr + 1 ; get the left edge insert point by subtracting - sta leftWorldPtr + 1 ; XSIZE+3 from the right edge. XSIZE-1 is the current - lda zWorldPtr ; left screen col. +3 is 4 past, which is the width - sec ; of a radar that could now scroll on-screen - sbc #((XSIZE+3)*3) ; the buffer will have proper height data for at least - sta leftWorldPtr ; 2 of these 3 cols to the left - see editLoadStage - bcs :+ - dec leftWorldPtr + 1 - -: - lda leftWorldPtr + 1 ; see if this new dest is <= the world start. - cmp #>worldDataStart ; if it is then don't scroll any further left, just exit - beq :+ ; hi equal to worldStart hi, so test low - bcs leftOk ; hi > worldStart hi so good to go -done: - rts -: - lda leftWorldPtr - cmp #worldDataStart - sta writeAddress + 1 - - lda #<(worldDataEnd-worldDataStart) ; set the size - sta writeLength - lda #>(worldDataEnd-worldDataStart) - sta writeLength + 1 - - jmp saveFile ; save - -.endproc - -;----------------------------------------------------------------------------- -.proc loadWorld - - lda #worldDataStart - sta readAddress + 1 - - lda #<(worldDataEnd-worldDataStart) ; set the length (size) - sta readLength - lda #>(worldDataEnd-worldDataStart) - sta readLength + 1 - - jmp loadFile ; load - -.endproc - -;----------------------------------------------------------------------------- -.proc saveHighScores - - jsr setHighScoreFileNames ; set the name - - lda #scoresTable - sta writeAddress + 1 - - lda #<(scoresTableEnd-scoresTable) ; set the size - sta writeLength - lda #>(scoresTableEnd-scoresTable) - sta writeLength + 1 - - jmp saveFile ; save - -.endproc - -;----------------------------------------------------------------------------- -.proc loadHighScores - - jsr setHighScoreFileNames ; set the name - - lda #scoresTable - sta readAddress + 1 - - lda #<(scoresTableEnd-scoresTable) ; set the size - sta readLength - lda #>(scoresTableEnd-scoresTable) - sta readLength + 1 - - jmp loadFile ; load - -.endproc - -;----------------------------------------------------------------------------- -.proc setHighScoreFileNames - - ldx pathPos ; append to the end of the path - ldy #0 ; from the 1st char pf the name -: - lda hihgScoreFileName, y ; copy name to path - sta PATHNAME, x - beq :+ - iny - inx - bne :- - -: - stx PATHNAME - dec PATHNAME ; don't count the trailing null - - rts - -.endproc - -;----------------------------------------------------------------------------- -.proc setWorldFileName - - zaEntryL = zWorldPtr ; internal - ptr to a string being entered (abusing world ptr) - - tya ; add the file length to the path length - clc - adc pathPos - tax - stx PATHNAME - dec PATHNAME ; don't count the trailing null - -: - lda (zaEntryL), y ; copy the file name to the end of the path - sta PATHNAME, x - dex - dey - bpl :- - - rts - -.endproc - -;----------------------------------------------------------------------------- -.proc saveFile - - jsr MLI ; create the file, ignoring errors - .byte CREATE_CALL - .word createParam - - jsr MLI ; open the (now hopefully existing) file - .byte OPEN_CALL - .word openParam - bcc :+ - jmp error - -: - lda openRef - sta writeRef - sta closeRef - - jsr MLI - .byte WRITE_CALL - .word writeParam - bcs error - - jsr MLI - .byte CLOSE_CALL - .word closeParam - bcs error - -error: - rts - -.endproc - -;----------------------------------------------------------------------------- -.proc loadFile - - jsr MLI - .byte OPEN_CALL - .word openParam - bcc :+ - jmp error - -: - lda openRef - sta readRef - sta closeRef - - jsr MLI - .byte READ_CALL - .word readParam - bcs error - - jsr MLI - .byte CLOSE_CALL - .word closeParam - bcs error - -error: - rts - -.endproc diff --git a/src/apple2/fontdata.inc b/src/apple2/fontdata.inc deleted file mode 100644 index 6a95cae..0000000 --- a/src/apple2/fontdata.inc +++ /dev/null @@ -1,948 +0,0 @@ -;----------------------------------------------------------------------------- -; fontdata.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "RODATA" - -;----------------------------------------------------------------------------- -; The characters are listed in Apple format (backwards) and human-facing -; format (not backwards ;) -font: -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $24 ; --X--X-- --X--X-- -.byte $24 ; --X--X-- --X--X-- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $24 ; --X--X-- --X--X-- -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $24 ; --X--X-- --X--X-- -.byte $24 ; --X--X-- --X--X-- -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $24 ; --X--X-- --X--X-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $10 ; ---X---- ----X--- -.byte $78 ; -XXXX--- ---XXXX- -.byte $14 ; ---X-X-- --X-X--- -.byte $38 ; --XXX--- ---XXX-- -.byte $50 ; -X-X---- ----X-X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $10 ; ---X---- ----X--- - -.byte $00 ; -------- -------- -.byte $46 ; -X---XX- -XX---X- -.byte $26 ; --X--XX- -XX--X-- -.byte $10 ; ---X---- ----X--- -.byte $08 ; ----X--- ---X---- -.byte $64 ; -XX--X-- --X--XX- -.byte $62 ; -XX---X- -X---XX- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $08 ; ----X--- ---X---- -.byte $14 ; ---X-X-- --X-X--- -.byte $08 ; ----X--- ---X---- -.byte $54 ; -X-X-X-- --X-X-X- -.byte $22 ; --X---X- -X---X-- -.byte $5C ; -X-XXX-- --XXX-X- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $10 ; ---X---- ----X--- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $20 ; --X----- -----X-- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $20 ; --X----- -----X-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $04 ; -----X-- --X----- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $04 ; -----X-- --X----- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $28 ; --X-X--- ---X-X-- -.byte $10 ; ---X---- ----X--- -.byte $7C ; -XXXXX-- --XXXXX- -.byte $10 ; ---X---- ----X--- -.byte $28 ; --X-X--- ---X-X-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $7C ; -XXXXX-- --XXXXX- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $08 ; ----X--- ---X---- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $7C ; -XXXXX-- --XXXXX- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $18 ; ---XX--- ---XX--- -.byte $18 ; ---XX--- ---XX--- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $40 ; -X------ ------X- -.byte $20 ; --X----- -----X-- -.byte $10 ; ---X---- ----X--- -.byte $08 ; ----X--- ---X---- -.byte $04 ; -----X-- --X----- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $62 ; -XX---X- -X---XX- -.byte $52 ; -X-X--X- -X--X-X- -.byte $4A ; -X--X-X- -X-X--X- -.byte $46 ; -X---XX- -XX---X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $18 ; ---XX--- ---XX--- -.byte $14 ; ---X-X-- --X-X--- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $7C ; -XXXXX-- --XXXXX- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $42 ; -X----X- -X----X- -.byte $40 ; -X------ ------X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $02 ; ------X- -X------ -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $42 ; -X----X- -X----X- -.byte $30 ; --XX---- ----XX-- -.byte $40 ; -X------ ------X- -.byte $42 ; -X----X- -X----X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $10 ; ---X---- ----X--- -.byte $18 ; ---XX--- ---XX--- -.byte $14 ; ---X-X-- --X-X--- -.byte $12 ; ---X--X- -X--X--- -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $10 ; ---X---- ----X--- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $02 ; ------X- -X------ -.byte $3E ; --XXXXX- -XXXXX-- -.byte $40 ; -X------ ------X- -.byte $42 ; -X----X- -X----X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $02 ; ------X- -X------ -.byte $3E ; --XXXXX- -XXXXX-- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $40 ; -X------ ------X- -.byte $20 ; --X----- -----X-- -.byte $10 ; ---X---- ----X--- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $42 ; -X----X- -X----X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $7C ; -XXXXX-- --XXXXX- -.byte $40 ; -X------ ------X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $04 ; -----X-- --X----- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $20 ; --X----- -----X-- -.byte $10 ; ---X---- ----X--- -.byte $08 ; ----X--- ---X---- -.byte $10 ; ---X---- ----X--- -.byte $20 ; --X----- -----X-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $7C ; -XXXXX-- --XXXXX- -.byte $00 ; -------- -------- -.byte $7C ; -XXXXX-- --XXXXX- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $08 ; ----X--- ---X---- -.byte $10 ; ---X---- ----X--- -.byte $20 ; --X----- -----X-- -.byte $10 ; ---X---- ----X--- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $42 ; -X----X- -X----X- -.byte $20 ; --X----- -----X-- -.byte $10 ; ---X---- ----X--- -.byte $00 ; -------- -------- -.byte $10 ; ---X---- ----X--- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $52 ; -X-X--X- -X--X-X- -.byte $6A ; -XX-X-X- -X-X-XX- -.byte $7A ; -XXXX-X- -X-XXXX- -.byte $02 ; ------X- -X------ -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3E ; --XXXXX- -XXXXX-- -.byte $42 ; -X----X- -X----X- -.byte $3E ; --XXXXX- -XXXXX-- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $3E ; --XXXXX- -XXXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $42 ; -X----X- -X----X- -.byte $02 ; ------X- -X------ -.byte $02 ; ------X- -X------ -.byte $42 ; -X----X- -X----X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $1E ; ---XXXX- -XXXX--- -.byte $22 ; --X---X- -X---X-- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $22 ; --X---X- -X---X-- -.byte $1E ; ---XXXX- -XXXX--- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $02 ; ------X- -X------ -.byte $3E ; --XXXXX- -XXXXX-- -.byte $02 ; ------X- -X------ -.byte $02 ; ------X- -X------ -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $02 ; ------X- -X------ -.byte $3E ; --XXXXX- -XXXXX-- -.byte $02 ; ------X- -X------ -.byte $02 ; ------X- -X------ -.byte $02 ; ------X- -X------ -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $42 ; -X----X- -X----X- -.byte $02 ; ------X- -X------ -.byte $72 ; -XXX--X- -X--XXX- -.byte $42 ; -X----X- -X----X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $7C ; -XXXXX-- --XXXXX- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $7C ; -XXXXX-- --XXXXX- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $40 ; -X------ ------X- -.byte $40 ; -X------ ------X- -.byte $40 ; -X------ ------X- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $22 ; --X---X- -X---X-- -.byte $12 ; ---X--X- -X--X--- -.byte $0E ; ----XXX- -XXX---- -.byte $12 ; ---X--X- -X--X--- -.byte $22 ; --X---X- -X---X-- -.byte $42 ; -X----X- -X----X- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $02 ; ------X- -X------ -.byte $02 ; ------X- -X------ -.byte $02 ; ------X- -X------ -.byte $02 ; ------X- -X------ -.byte $02 ; ------X- -X------ -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $42 ; -X----X- -X----X- -.byte $66 ; -XX--XX- -XX--XX- -.byte $5A ; -X-XX-X- -X-XX-X- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $42 ; -X----X- -X----X- -.byte $46 ; -X---XX- -XX---X- -.byte $4A ; -X--X-X- -X-X--X- -.byte $52 ; -X-X--X- -X--X-X- -.byte $62 ; -XX---X- -X---XX- -.byte $42 ; -X----X- -X----X- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3E ; --XXXXX- -XXXXX-- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $3E ; --XXXXX- -XXXXX-- -.byte $02 ; ------X- -X------ -.byte $02 ; ------X- -X------ -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $4A ; -X--X-X- -X-X--X- -.byte $52 ; -X-X--X- -X--X-X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3E ; --XXXXX- -XXXXX-- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $3E ; --XXXXX- -XXXXX-- -.byte $22 ; --X---X- -X---X-- -.byte $42 ; -X----X- -X----X- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $02 ; ------X- -X------ -.byte $3C ; --XXXX-- --XXXX-- -.byte $40 ; -X------ ------X- -.byte $42 ; -X----X- -X----X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $7F ; -XXXXXXX XXXXXXX- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $24 ; --X--X-- --X--X-- -.byte $18 ; ---XX--- ---XX--- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $42 ; -X----X- -X----X- -.byte $5A ; -X-XX-X- -X-XX-X- -.byte $24 ; --X--X-- --X--X-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $42 ; -X----X- -X----X- -.byte $24 ; --X--X-- --X--X-- -.byte $18 ; ---XX--- ---XX--- -.byte $18 ; ---XX--- ---XX--- -.byte $24 ; --X--X-- --X--X-- -.byte $42 ; -X----X- -X----X- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $41 ; -X-----X X-----X- -.byte $22 ; --X---X- -X---X-- -.byte $14 ; ---X-X-- --X-X--- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $20 ; --X----- -----X-- -.byte $10 ; ---X---- ----X--- -.byte $08 ; ----X--- ---X---- -.byte $04 ; -----X-- --X----- -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $70 ; -XXX---- ----XXX- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $70 ; -XXX---- ----XXX- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $02 ; ------X- -X------ -.byte $04 ; -----X-- --X----- -.byte $08 ; ----X--- ---X---- -.byte $10 ; ---X---- ----X--- -.byte $20 ; --X----- -----X-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $0E ; ----XXX- -XXX---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $0E ; ----XXX- -XXX---- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $08 ; ----X--- ---X---- -.byte $1C ; ---XXX-- --XXX--- -.byte $2A ; --X-X-X- -X-X-X-- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $FF ; XXXXXXXX XXXXXXXX - -.byte $00 ; -------- -------- -.byte $38 ; --XXX--- ---XXX-- -.byte $44 ; -X---X-- --X---X- -.byte $1E ; ---XXXX- -XXXX--- -.byte $04 ; -----X-- --X----- -.byte $04 ; -----X-- --X----- -.byte $7E ; -XXXXXX- -XXXXXX- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $1C ; ---XXX-- --XXX--- -.byte $20 ; --X----- -----X-- -.byte $3C ; --XXXX-- --XXXX-- -.byte $22 ; --X---X- -X---X-- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $04 ; -----X-- --X----- -.byte $04 ; -----X-- --X----- -.byte $3C ; --XXXX-- --XXXX-- -.byte $44 ; -X---X-- --X---X- -.byte $44 ; -X---X-- --X---X- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $38 ; --XXX--- ---XXX-- -.byte $04 ; -----X-- --X----- -.byte $04 ; -----X-- --X----- -.byte $04 ; -----X-- --X----- -.byte $38 ; --XXX--- ---XXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $20 ; --X----- -----X-- -.byte $20 ; --X----- -----X-- -.byte $3C ; --XXXX-- --XXXX-- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $3C ; --XXXX-- --XXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $1C ; ---XXX-- --XXX--- -.byte $22 ; --X---X- -X---X-- -.byte $1E ; ---XXXX- -XXXX--- -.byte $02 ; ------X- -X------ -.byte $1C ; ---XXX-- --XXX--- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $30 ; --XX---- ----XX-- -.byte $08 ; ----X--- ---X---- -.byte $18 ; ---XX--- ---XX--- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $3C ; --XXXX-- --XXXX-- -.byte $20 ; --X----- -----X-- -.byte $1C ; ---XXX-- --XXX--- - -.byte $00 ; -------- -------- -.byte $02 ; ------X- -X------ -.byte $02 ; ------X- -X------ -.byte $1E ; ---XXXX- -XXXX--- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- -.byte $0C ; ----XX-- --XX---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $1C ; ---XXX-- --XXX--- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $20 ; --X----- -----X-- -.byte $00 ; -------- -------- -.byte $20 ; --X----- -----X-- -.byte $20 ; --X----- -----X-- -.byte $20 ; --X----- -----X-- -.byte $24 ; --X--X-- --X--X-- -.byte $18 ; ---XX--- ---XX--- - -.byte $00 ; -------- -------- -.byte $04 ; -----X-- --X----- -.byte $14 ; ---X-X-- --X-X--- -.byte $0C ; ----XX-- --XX---- -.byte $0C ; ----XX-- --XX---- -.byte $14 ; ---X-X-- --X-X--- -.byte $24 ; --X--X-- --X--X-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $30 ; --XX---- ----XX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $16 ; ---X-XX- -XX-X--- -.byte $2A ; --X-X-X- -X-X-X-- -.byte $2A ; --X-X-X- -X-X-X-- -.byte $2A ; --X-X-X- -X-X-X-- -.byte $2A ; --X-X-X- -X-X-X-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $1E ; ---XXXX- -XXXX--- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $1C ; ---XXX-- --XXX--- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $1C ; ---XXX-- --XXX--- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $1E ; ---XXXX- -XXXX--- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $1E ; ---XXXX- -XXXX--- -.byte $02 ; ------X- -X------ -.byte $02 ; ------X- -X------ - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $3C ; --XXXX-- --XXXX-- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $3C ; --XXXX-- --XXXX-- -.byte $20 ; --X----- -----X-- -.byte $40 ; -X------ ------X- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $38 ; --XXX--- ---XXX-- -.byte $04 ; -----X-- --X----- -.byte $04 ; -----X-- --X----- -.byte $04 ; -----X-- --X----- -.byte $04 ; -----X-- --X----- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $1C ; ---XXX-- --XXX--- -.byte $02 ; ------X- -X------ -.byte $1C ; ---XXX-- --XXX--- -.byte $20 ; --X----- -----X-- -.byte $1E ; ---XXXX- -XXXX--- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $08 ; ----X--- ---X---- -.byte $1C ; ---XXX-- --XXX--- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $30 ; --XX---- ----XX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $1C ; ---XXX-- --XXX--- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $14 ; ---X-X-- --X-X--- -.byte $14 ; ---X-X-- --X-X--- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $22 ; --X---X- -X---X-- -.byte $2A ; --X-X-X- -X-X-X-- -.byte $2A ; --X-X-X- -X-X-X-- -.byte $2A ; --X-X-X- -X-X-X-- -.byte $14 ; ---X-X-- --X-X--- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $22 ; --X---X- -X---X-- -.byte $14 ; ---X-X-- --X-X--- -.byte $08 ; ----X--- ---X---- -.byte $14 ; ---X-X-- --X-X--- -.byte $22 ; --X---X- -X---X-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $22 ; --X---X- -X---X-- -.byte $3C ; --XXXX-- --XXXX-- -.byte $20 ; --X----- -----X-- -.byte $1C ; ---XXX-- --XXX--- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $3E ; --XXXXX- -XXXXX-- -.byte $10 ; ---X---- ----X--- -.byte $08 ; ----X--- ---X---- -.byte $04 ; -----X-- --X----- -.byte $3E ; --XXXXX- -XXXXX-- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $60 ; -XX----- -----XX- -.byte $10 ; ---X---- ----X--- -.byte $0C ; ----XX-- --XX---- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $60 ; -XX----- -----XX- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $10 ; ---X---- ----X--- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $06 ; -----XX- -XX----- -.byte $08 ; ----X--- ---X---- -.byte $30 ; --XX---- ----XX-- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $06 ; -----XX- -XX----- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $28 ; --X-X--- ---X-X-- -.byte $14 ; ---X-X-- --X-X--- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- - -.byte $1C ; ---XXX-- --XXX--- -.byte $22 ; --X---X- -X---X-- -.byte $59 ; -X-XX--X X--XX-X- -.byte $45 ; -X---X-X X-X---X- -.byte $45 ; -X---X-X X-X---X- -.byte $59 ; -X-XX--X X--XX-X- -.byte $22 ; --X---X- -X---X-- -.byte $1C ; ---XXX-- --XXX--- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $02 ; ------X- -X------ -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $01 ; -------X X------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $05 ; -----X-X X-X----- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $15 ; ---X-X-X X-X-X--- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- - -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $55 ; -X-X-X-X X-X-X-X- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- -.byte $00 ; -------- -------- - -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $49 ; -X--X--X X--X--X- -.byte $3E ; --XXXXX- -XXXXX-- -.byte $08 ; ----X--- ---X---- - -.byte $08 ; ----X--- ---X---- -.byte $3E ; --XXXXX- -XXXXX-- -.byte $49 ; -X--X--X X--X--X- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- -.byte $08 ; ----X--- ---X---- - -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- -.byte $2A ; --X-X-X- -X-X-X-- -.byte $00 ; -------- -------- -.byte $08 ; ----X--- ---X---- -.byte $00 ; -------- -------- -endFont: diff --git a/src/apple2/game.inc b/src/apple2/game.inc deleted file mode 100644 index dc6fcbb..0000000 --- a/src/apple2/game.inc +++ /dev/null @@ -1,1212 +0,0 @@ -;----------------------------------------------------------------------------- -; game.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "CODE" - -;----------------------------------------------------------------------------- -.proc gamePlay - - jsr gameInit - -outerloop: - lda lives - bne :+ - rts ; no lives left = Game Over -: - jsr gameLevelInit ; prep whatever level the active player is at - jsr gameShowPlayer ; show the pre-play who's turn message - jsr uiShowGameLabels ; show the lines for score, danger, etc. - -preamble: ; bring terrain on-screen with no clock delay - jsr drawPresent - jsr gameWorldMove - jsr gameWorldMove - jsr terrainShow ; show terrain 1st because it collides with nothing - jsr drawEnemies ; enemy missiles collide with terrain - - dec terrainOrigin ; get the start of terrain drawing to col 0 - dec terrainOrigin ; get the start of terrain drawing to col 0 - bpl preamble ; and draw even at 0 - inc terrainOrigin ; origin is now -1 so set it back to 0 - jsr gamePlaceShip ; find a safe spot for the player to spawn - jsr drawPlayer ; now show the player ship - jsr drawPresent ; flip layers 0/1 (bring backLayer to visible) - - bit KBDSTRB - wait #$40 ; give the user a moment to get ready - -loop: - jsr inputGame ; read joystick and move player, check for pause key - cmp #$9b ; check for ESC - bne skip ; if not, check for pause - rts ; on ESC, just quit - -skip: - lda playerDead ; if the player is dead the world doesn't move - bne :+ - jsr gameWorldMove ; scroll the world - inc bufferDraw ; and move the draw start also - jsr gameCheckStage ; see if a stage is ending -: - lda flipFlop ; the flipFlop is 0->1->0->1, etc. - eor #1 - sta flipFlop - - jsr gameAI ; run the "AI" - this moves enemies and animates everything, etc. - -next: - dec bulletIndex ; Bullets move every frame (2x for 1 world move) - dec bulletIndex - -draw: - jsr terrainShow ; show terrain 1st because it collides with nothing - jsr drawEnemies ; enemy missiles collide with terrain - jsr drawPlayer ; player collides with enemies only - jsr drawBullets ; checks for enemy collision - jsr drawBombs ; checks for enemy collision (but won't destroy player) - jsr drawExplosions ; explosions draw over everything and collide with nothing - - lda updateHUD ; only update the hud when it changes - beq delay - jsr uiUpdateGameHud - -delay: - jsr drawPresent ; flip layers 0/1 (bring backLayer to visible) - - lda victory ; when set, either a nuke or back home - bne win - jsr serviceAudio ; run the audio - lda playerDead - beq loop ; playerDead = 0 means alive so keep going - -died: - dec playerDead ; the counter holds the explosion state - bne skip ; don't get user input - jsr gameNextPlayer ; switch players if a 2p game - jmp outerloop - -win: - jsr gameWinSequence ; flash screen and show the win screen (wow or home) - jmp outerloop - -.endproc - -;----------------------------------------------------------------------------- -.proc gameInit - - jsr drawClearScreen ; make sure the screen is clear before adjusting the - - lda #NUM_LIVES ; lives to start - sta lives - - lda #0 ; init some variables - stage is set before this - sta direction ; go to the right - sta activePlayer ; player 1 is always 1st to go - sta score - sta score + 1 - sta score + 2 - - ldx #NUM_STAGES-1 ; mark all stages as all rockets -: - sta makeMonster, x - dex - bpl :- - - lda #NUM_SKIP_MONST ; make this stage (NUM_SKIP_MONST) be a monster stage - sta monsterCnt - - ldx #3 ; set stage 3 (zero based) as some rockets become monsters - sta makeMonster, x - - - ldy #0 ; init player 1 - jsr gameStatsToPlayer - - ldy #1 ; init player 2 - jmp gameStatsToPlayer - -.endproc - -;----------------------------------------------------------------------------- -.proc gameLevelInit - - lda #0 ; Lots of values need a 0 init - sta victory - sta playerDead - sta zCollision - sta stopScrolling - sta bufferInsert - sta dangerTickIdx - sta moveHorz - sta moveVert - sta flipFlop - sta pause - sta fireCoolDown - - tax ; clear the buffers for tracking objects -: - sta worldBBuffer, x - sta worldTBuffer, x - sta enemyBuffer, x - sta enemyHgtBuffer, x - sta explosionBuffer, x - sta bulletsBuffer, x - dex - bne :- - - ldx #(bombDir + (NUM_BOMBS - 1) - bombX) ; clear the bomb area -: - sta bombX, x - dex - bpl :- - - lda #XSIZE-1 ; place where terrain will start drawing (right hand) - sta terrainOrigin - - lda #AUDIO_MOTOR_PLAY ; Init th eaudio-frame with the engine - sta audioFrame - - lda #$ff - sta lastInput ; set no keys down all 1's - sta nextStage - - lda #DANGER_TICKS - sta dangerTickCount - - ldx #(textEnd-textStage)-1 ; empty the text areas to spaces -store: - lda textStage, x - beq :+ ; skip the null terminators - lda #$20 ; load the space (" ") character - sta textStage, x ; write it to the text areas -: - dex - bpl store - - jsr gameFindStage ; point zWorldPtr at the stage start - jsr gameWorldMove ; prime the draw buffers - lda bufferInsert - sta bufferDraw ; point the tail at the head - inc bufferDraw ; advance the tail (this will correct itself) - - rts - -.endproc - -;----------------------------------------------------------------------------- -.proc gameShowPlayer - - jsr drawClearScreen - - print textPlayer, #(08), #(8*08) - lda activePlayer - clc - adc #$31 - sta textPlayerNum - print textPlayerNum, #(23), #(8*08) - jsr drawPresent - - wait #$40 - - jmp drawClearScreen - -.endproc - -;----------------------------------------------------------------------------- -.proc gamePlaceShip - - bottom = tempBlock - top = tempBlock + 1 - - lda #$ff ; init markers with extremes - sta bottom - lda #0 - sta top - - lda #(XSIZE/3) ; some way into the screen - sta playerShipX ; put the ship - clc - adc bufferDraw ; make worldBBuffer relative to screen col 0 - tay - ldx #SHIP_WIDTH -loop: - lda worldBBuffer, y ; get the bottom at this col under the ship - cmp bottom ; see if it's higher than the marker - bcs :+ - sta bottom ; is higher, update the marker -: - lda worldTBuffer, y ; get the top above the ship - cmp top ; see if it's lower than the marker - bcc :+ - sta top ; if lower, update the top marker -: - iny - dex - bne loop ; do for all terrain under/above the ship - lda bottom ; put the ship SHIP_START above the bottom - sec - sbc #SHIP_START - sta playerShipY - sec ; see how high the top is now - sbc #SHIP_HEIGHT - cmp top ; see if the top is now above the world top - bcs done - lda #SHIP_HEIGHT ; if it is, adjust the ship down to - adc top ; be directly under the top - this happens in narrow passages - sta playerShipY - -done: - rts - -.endproc - -;----------------------------------------------------------------------------- -; Manage the nextStage counter based on the stage variable changing -; This variable is needed because the stage changes relative to the marker -; based on direction. -.proc gameCheckStage - - ldy #2 ; check for the current stage end marker - lda (zWorldPtr), y - bit Bit7Mask ; end of/start of stage marker - beq noMarker ; not set means no marker - - lda direction ; there is a marker - see which direction - bne :+ - lda #XSIZE -: - sta nextStage - -noMarker: - lda nextStage ; now deal with the nextStage marker counter, if set - bmi done ; -1 means nothing to do - - lda stopScrolling ; if stopScrolling is set - bne done ; then the stage counter does not count down - dec nextStage ; count down to -1 eventually - bne done ; non-zero - nothing to do - - dec nextStage ; at zero - take action and set to -1 so this inly triggers once - sty updateHUD ; y = 2 so force HUD update draws for the 2 buffers - lda direction ; based on direction, adjust the stage counter - beq stageUp ; going right - -stagedown: - dec stage ; going left so dec stage - bpl done ; stage 0 and above - keep going - - lda #0 ; stage -1 means back home, - sta enemyHit ; add score for a non-flying nuke (1000 pts) - jsr gameAddScore - - lda #1 ; mark the "home run" as a victory - sta victory - rts - -stageUp: - inc stage ; going right - stage up - -done: - rts -.endproc - -;----------------------------------------------------------------------------- -; This processes the buffers for enemies, bullets, explosions and moves the bombs. -.proc gameAI - - zaBombHeight = tempBlock + 1 - zaTempFrame = tempBlock + 2 - zaTempHeight = tempBlock + 2 - zaEnd = tempBlock + 3 - - lda inFlight + 1 ; launches counted last frame - sta inFlight ; use it this frame - lda #0 ; reset the counter from last frame - sta inFlight + 1 ; to count again in this frame - - ldy bufferInsert ; this is the end of the world - iny ; but radar's can extend up to 3 beyond - iny ; and the end is 1 past the last - iny ; thing to process - iny - sty zaEnd ; so mark the end of processing - ldy bufferDraw ; make enemyBuffer relative to screen col 0 - -loop: - lda enemyBuffer, y - beq explosion ; ignore blank columns - - bit Bit12Mask ; check if it needs animating - beq :+ ; ignore monsters (%nnnnnn00) - - adc #%00010000 ; advance to next anim frame (radars & missiles) - and #%01110000 ; restrict to these 3 bits - sta zaTempFrame ; save only the frame counter - lda enemyBuffer, y ; get the original - and #%10001111 ; mask out the frame - ora zaTempFrame ; add in the new frame (and thus preserve bit 8) - sta enemyBuffer, y ; save this enemy now (post anim update) - -: - bit Bit8432Mask ; check if this is a radar, 2nd column of a missile or a launched missile - bne doHeight ; skip it if it is one of those things - - lda inFlight ; see how many rockets are in-flight - cmp #NUM_INFLIGHT * 2 ; limit to 3 (both halves count so looks like 6 launches) - bcs :+ - - lda enemyHgtBuffer, y ; this is the left hand column of a missile - see if it needs to launch - sec - sbc playerShipY ; get the distance from the player - lsr ; put it in the same units as the X - lsr - cmp #31 ; distance cut off - > delta then rockets don't launch - bcs :+ - sta tempBlock + 4 ; approx 4/3 * height - lsr tempBlock + 4 ; since the missiles move 3 rows up for every - lsr tempBlock + 4 ; 4 pixels the world moves - clc - adc tempBlock + 4 - sta zaTempHeight ; save it - tya ; get the distance of this rocket from the player in X - sec ; start by calculating the screen X position of the rocket - sbc bufferDraw ; make enemyBuffer relative to screen col 0 - sbc playerShipX ; and then subtracting the screen x position of the ship - bcc :+ ; player is to the right so ignore - cmp zaTempHeight ; is dist y to missile = dist x to missile (in column units?) - beq launch ; if equal, do a launch -: - lda enemyBuffer, y - bne doHeight ; no match, so no launch - -launch: - iny ; mark the right hand column as launched - lda enemyBuffer, y - ora #%10000000 - sta enemyBuffer, y - dey - - lda enemyBuffer, y ; mark left column as launched - ora #%10000000 - sta enemyBuffer, y - -doHeight: - bit Bit8Mask ; see if this needs height adjustment - beq explosion ; don't move non-launched stuff - - inc inFlight + 1 ; count launched rockets - bit Bit1Mask ; see if this is a missile - bne :+ ; this is a missile - bit Bit34Mask ; don't do anything unless this is - bne explosion ; the 1st column of the monster - jsr gameMonsterAI ; This is a monster - run its AI - jmp explosion - -: - lda enemyHgtBuffer, y - sec - sbc #3 - cmp #WORLD_START - bcs :+ ; out of existence at the top, kill it off - lda #0 - sta enemyBuffer, y -: - sta enemyHgtBuffer, y - -explosion: - lda explosionBuffer, y ; advance the explosion sprite frame - beq nextBufferEntry - clc - adc #1 - bit Bit3Mask ; at frame 4, stop the explosion - beq :+ - lda #0 -: - sta explosionBuffer, y - -nextBufferEntry: ; advance processing to the next enemy - iny - cpy zaEnd ; see if all enemies processed - clc - beq doBombs - jmp loop - -doBombs: - ldx #NUM_BOMBS - 1 ; move the bombs - -loopb: - lda bombY, x - beq nextb ; 0 in Y means inactive - clc - adc #3 ; move down 4 rows - sta bombY, x - - lda bombDir, x ; get the travel direction - beq :+ ; if 0, it's going straight down - dec bombDir, x ; decrease the columns it will move forward for - inc bombX, x ; <> 0, still moving forward, inc it's x position - bne skbd ; always (jmp) -: - lda stopScrolling ; see if the world is moving - bne skbd ; if not, don't adjust the bomb X - dec bombX, x ; scroll bomb with world to go straight down -skbd: - lda bombX, x ; get the screen column - bmi bol ; if < 0 then bomb out left hand side of screen - adc bufferDraw ; make enemyBuffer relative to screen col 0 - tay - lda worldBBuffer, y ; get the terrain bottom height in this col - sec - sbc bombY, x ; subtract the bomb height - bcs nextb ; if the bomb < terrain (carry set), all is well -bol: - lda #0 ; bomb too low, write 0 into the bomb height - sta bombY, x - -nextb: - dex - bpl loopb ; repeat for all bombs - - clc - rts -.endproc - - -;----------------------------------------------------------------------------- -; This moves the monster up and down between the top and bottom of the world -; where it will pause for a moment. When the monster overlaps the player, it -; will also pause for a moment before going back to the bounce -; called with y the index in enemyBuffer to the 1st strip of the monster and -; acc the value in enemyBuffer, y -.proc gameMonsterAI - - zaTempIndex = tempBlock + 2 ; y reg saved as Index to 1st strip in monster - - and #%01100000 ; check if the stop counter has a value - beq moving ; if not, monster is moving - -paused: ; the monster is at top/bottom or overlapped player - lda #%00100000 - adc enemyBuffer, y ; add to the monster value - ora #%10000000 ; make sure the flying bit stays on - sta enemyBuffer, y ; save the update - rts - -moving: ; the monster is bouncing up or down - sty zaTempIndex ; save the index - need to work on 3 strips - ldx #MONSTER_WIDTH ; load x with the width (3) - lda enemyBuffer, y ; reload the enemy (acc destroyed by and above) - bit Bit5Mask ; bit 5 is direction - 0 is up and 1 is down - bne down - -up: - lda enemyHgtBuffer, y ; monster is at same height in all its columns - sec - sbc #MONSTER_SPEED ; move up to where it would be - sbc #MONSTER_HEIGHT ; but need the top of the monster to check if it hit the ceiling - - dey ; adjust for alignment with world buffer - -chktop: - cmp worldTBuffer, y ; compare to the world ceiling height - beq changedir ; if equal, change direction don't go up - bcc changedir ; if less than, also don't go up but change dir - iny ; do for all the monster strips - dex - bne chktop - - ldx #MONSTER_WIDTH ; not in ceiling collision so adjust height - ldy zaTempIndex ; start at the 1st strip - -: - lda enemyHgtBuffer, y ; move the strips upwards - sec - sbc #MONSTER_SPEED ; speed at which monster moves - sta enemyHgtBuffer, y ; save updated position - iny ; repeat for all strips - dex - bne :- - -chkplayerhgt: ; see if the monster is now overlapping the enemy ship - clc - ldy zaTempIndex ; get the 1st strip index - ldx #MONSTER_SPEED ; check as many columns as moved (faster for than overlap calc) -: - cmp playerShipY ; is it matching the player - beq stop ; if yes, stop the monster - adc #1 ; try each position in the step - dex ; and repeat for all increments in a monster step (speed) - bne :- - rts - -changedir: - ldy zaTempIndex ; go back to the 1st strip - lda enemyBuffer, y ; get the enemy - eor #%00110000 ; turn on stop and change dir in one go - sta enemyBuffer, y ; save - rts - -stop: - lda enemyBuffer, y ; get the 1st strip - ora #%00100000 ; set stop counter to 1 - sta enemyBuffer, y ; save - rts - -down: - lda enemyHgtBuffer, y ; monster is at same height in all its columns - clc - adc #MONSTER_SPEED ; height down by speed to where it would go - - ldx #MONSTER_WIDTH ; check for a bottom collision - dey ; adjust for the world offset -chkbot: - cmp worldBBuffer, y ; get the world below this strip - bcs changedir ; if the world is higher than the base of the monster, change direction - iny ; check all strips - dex - bne chkbot - - ldx #MONSTER_WIDTH ; height okay, so finally move the monster - ldy zaTempIndex ; starting at strip 1 - -: - lda enemyHgtBuffer, y ; get the strip height - clc - adc #MONSTER_SPEED ; adjust the height - sta enemyHgtBuffer, y ; save it - iny ; do for all strips - dex - bne :- - beq chkplayerhgt ; JuMP to see if the monster and player now overlap - -done: - rts - -.endproc - -;----------------------------------------------------------------------------- -.proc gameWorldMove - - jsr gameUpdateDangerBar ; when the world moves, the danger bar needs to be updated - - clc - inc bufferInsert ; advance where buffer data is inserted - ldx bufferInsert ; get the new right edge - inx ; step past where radar columns might be - inx - inx - lda #0 ; write a null to kill old circular data - sta enemyBuffer, x - sta enemyHgtBuffer, x - ldx bufferInsert ; get the right edge again - - lda direction ; world prt moves based on level forward/reverse direction - bne left - - clc ; moving through to the right, advance the world 1 column - lda zWorldPtr - adc #3 - sta zWorldPtr - bcc :+ - inc zWorldPtr + 1 - clc -: - ldy #0 ; get the world bottom - lda (zWorldPtr), y - sta worldBBuffer, x - - iny ; get the world top - lda (zWorldPtr), y - sta worldTBuffer, x - - lda terrainOrigin ; if the terrain is still scrolling in - bne done ; then don't populate enemies - - iny ; get the enemy flags - lda (zWorldPtr), y ; get the enemy flag - beq done ; no enemies, carry on - jmp gameWorldFlag ; populate the world with enemies - -left: ; to the left (in the data, back to front), 1 column "subtract" - sec - lda zWorldPtr - sbc #$03 - sta zWorldPtr - bcs :+ - dec zWorldPtr + 1 - -: - clc ; make carry clear since gameWorldFlag expects to be called with carry clear - ldy #6 ; get the world bottom - lda (zWorldPtr), y - sta worldBBuffer, x - - iny ; get the world top - lda (zWorldPtr), y - sta worldTBuffer, x - - lda terrainOrigin ; if the terrain is still scrolling in - bne done ; then don't populate enemies - - ldy #8 ; look ahead 1 col - lda (zWorldPtr), y ; get the enemy flag - bit Bit1Mask ; is this a missile - beq radar ; not a missile, maybe there's a radar coming? - jmp gameWorldFlag ; this is a missile - go add it - -radar: - ldy #2 ; Look ahead even further for a radar coming on-screen - lda (zWorldPtr), y ; get the enemy flag - bit Bit2Mask ; is this a radar - beq done ; no, then nothing more to do - jmp gameWorldFlag ; yes - add the radar - -done: - rts - -.endproc - -;----------------------------------------------------------------------------- -.proc gameFindStage - - zaStage = tempBlock + 1 - - ldy #2 ; world data is bottom, top and then flags. need flags in this routine - - lda direction ; world prt moves based on level forward/reverse direction - bne left - - lda #worldDataStart - sta zWorldPtr + 1 - - lda stage ; see how many stage markers to skip - beq done ; stage 0 - skip none, start of data is good - sta zaStage - -rloop: - lda (zWorldPtr), y ; get the flags - bit Bit7Mask ; see if it's a stage marker - beq :+ - dec zaStage ; found a stage but step once more not to trigger in-game - -: - lda zWorldPtr ; step the pointer over the data triplet - clc - adc #3 - sta zWorldPtr - bcc :+ - inc zWorldPtr + 1 -: - jsr gameUpdateDangerBar ; update the danger meter - lda zaStage ; now check if the stage is found - beq done ; and exit if it has - bne rloop - -left: ; world is moving backwards so - lda #<(worldDataEnd - 3) ; start at the end of the data, looking - sta zWorldPtr ; at the 1st triplet of data - lda #>(worldDataEnd - 3) - sta zWorldPtr + 1 - - lda #(NUM_STAGES-1) ; see how many stage markers to skip - sec - sbc stage - beq done - sta zaStage ; save the counter - -lloop: - lda (zWorldPtr), y ; get the flags - bit Bit7Mask ; and see if it's a stage flag - beq :+ - dec zaStage ; may be the stage being sought but step once more - -: - lda zWorldPtr ; move the ptr backwards through the data - sec ; to the previous data triplet - sbc #3 - sta zWorldPtr - bcs :+ - dec zWorldPtr + 1 - -: - jsr gameUpdateDangerBar ; update the danger meter - lda zaStage ; see if this is the stage being sought - beq done ; and exit if it is - bne lloop - -done: - clc - rts - -.endproc - -;----------------------------------------------------------------------------- -; Use the 4 user font characters (at $80+) to draw a dotted line danger bar -.proc gameUpdateDangerBar - - dec dangerTickCount ; count down to adding a dot - beq tick ; time to add a dot? - rts - -tick: - lda #DANGER_TICKS ; reset the countdown - sta dangerTickCount - ldx dangerTickIdx ; get the index for how far into the count - lda textDangerBar, x ; get the character - cmp #' ' ; 1st time - this is a space so init - beq dot - cmp #$84 ; 4 dots last character so move to next column? - beq :+ - inc textDangerBar, x ; add a dot by advancing the font - bne hud ; JuMP to hud update -: - inx ; move to next character in the display - stx dangerTickIdx ; save the index -dot: - lda #$80 ; 1 dot - load the single dot font character - sta textDangerBar, x ; put it in the display - -hud: - lda #2 ; update the hud twice so both buffers - sta updateHUD ; get updated - clc - rts - -.endproc - -;----------------------------------------------------------------------------- -; Process the flags in the world data stream. carry must be clear when called -; radar is %01, missile is %10 -.proc gameWorldFlag - - bit Bit2Mask ; radar? - beq missile ; no, see if it's a missile - lda gameMode ; In edit mode, don't draw nuke's for radars - bit Bit2Mask ; GAME_MODE_EDIT is $02 so if bit set then skip nuke check - bne :+ - lda stage - cmp #(NUM_STAGES - 1) ; stages are 0 based - this is the last stage - clc - beq nuke ; in stage 4 the radars become nuke's - -: - lda worldBBuffer, x ; load the height of the world below this enemy - sbc #0 ; carry is clear so this is -1 - tay ; save the height in y - sta enemyHgtBuffer, x ; set the height for the 1st radar strip - lda #SPR_RADAR0 ; put the strips into the enemy buffer - sta enemyBuffer, x - - inx ; go to the next strip - tya ; get the height from y - sta enemyHgtBuffer, x ; and set up this strip and the remaining strips - lda #SPR_RADAR1 - sta enemyBuffer, x - - inx - tya - sta enemyHgtBuffer, x - lda #SPR_RADAR2 - sta enemyBuffer, x - - inx - tya - sta enemyHgtBuffer, x - lda #SPR_RADAR3 - sta enemyBuffer, x - - clc - rts - -nuke: - lda worldBBuffer, x ; put the nuke strips in - sbc #0 - tay - sta enemyHgtBuffer, x - lda #SPR_NUKE0 - sta enemyBuffer, x - - inx - tya - sta enemyHgtBuffer, x - lda #SPR_NUKE1 - sta enemyBuffer, x - - clc - rts - -missile: - bit Bit1Mask ; is it a missile - beq done ; no, move on - - ldy stage ; see if in this stage some missiles become monsters - lda makeMonster, y - beq :+ ; 0 means no, not in this stage - dec monsterCnt - beq monster ; when this is 0, make a missile a monster - -: - lda worldBBuffer, x ; get the height - sbc #0 ; -1 (carry clear) to put it above ground - tay - sta enemyHgtBuffer, x ; mark as the height - lda #SPR_MISSILE0 - sta enemyBuffer, x - - inx - tya - sta enemyHgtBuffer, x - lda #SPR_MISSILE1 - sta enemyBuffer, x - - clc - rts - -monster: - lda #NUM_SKIP_MONST - sta monsterCnt - - lda worldBBuffer, x - sbc #0 - tay - sta enemyHgtBuffer, x ; set the height for the 4 radar strips - lda #SPR_MONSTER0 ; put the strips into the enemy buffer - sta enemyBuffer, x - - inx - tya - sta enemyHgtBuffer, x - lda #SPR_MONSTER1 - sta enemyBuffer, x - - inx - tya - sta enemyHgtBuffer, x - lda #SPR_MONSTER2 - sta enemyBuffer, x - - clc - rts - - done: - rts - -.endproc - -;----------------------------------------------------------------------------- -.proc gamePlayerCollision - - lda #0 - sta zCollision ; reset the collision flag - - lda playerDead ; already marked as dead? - beq :+ - rts - -: - lda #$20 ; mark the death and hold for - sta playerDead ; some frames - - lda #2 ; force a HUD redraw to show - sta updateHUD ; reduced lives - - lda #1 ; stop the world moving - sta stopScrolling - - lda gameMode ; get the game mode - bne done ; and only take a life if in gameplay (= 0) - - sed ; take away a life - lda lives ; lives are done in decimal - sec ; for easier printing - sbc #1 - sta lives - cld - clc - -done: - rts - -.endproc - -;----------------------------------------------------------------------------- -.proc gameNextPlayer - - lda lives - bne stillOk - - print textGameOver, #(0), #(8*05) ; show the game over text - jsr drawPresent - - lda #0 - bit KBDSTRB ; flush the keyboard buffer - sta lastInput -: - jsr inputCheckForInput ; wait for user interaction - beq :- - - jsr uiCheckHighScore ; Did this player make it onto the high score table - -stillOk: - lda numPlayers ; see if it's a 2-player game - beq done - - ldy activePlayer ; save the outgoing players' stats - jsr gameStatsToPlayer - - ldy #0 ; assume p1 was active - lda activePlayer ; get the active player - eor #1 ; swap 0->1 or 1->0 - tax ; next player in x - beq :+ ; if 0 is next, y is set up already - ldy #(rsEnd-rsStart) ; 1 is next, so set y up to point at p1 -: - lda playerStats, y ; get the lives (1st element is "struct") - beq done ; if none, then don't switch players - - ldy activePlayer ; incoming player has lives - save current active in Y - stx activePlayer ; switch to this (incoming) player - - ldy activePlayer ; install the players' stats - jsr gamePlayerToStats - -done: - rts - -.endproc - -;----------------------------------------------------------------------------- -; Copy the "live" stats to the backup location for a player -; y is the index of the player (0 or 1) -.proc gameStatsToPlayer - - ldx #(rsEnd-rsStart) - 1 ; assume p0 destination - dey - bne :+ - ldx #((rsEnd-rsStart) * 2) - 1 ; actually p1 so adjust copy dest location -: - ldy #(rsEnd-rsStart) - 1 ; set y to the end of the runtime stats buffer -: - lda rsStart, y ; load runtime stat - sta playerStats, x ; save as player stat - dex ; do for all bytes needing to be copied - dey - bpl :- ; copy all bytes - - rts - -.endproc - -;----------------------------------------------------------------------------- -; Copy the backup player stats to the "live" stats location -; y is the index of the player (0 or 1) -.proc gamePlayerToStats - - ldx #(rsEnd-rsStart) - 1 ; assume p0 destination - dey - bne :+ - ldx #((rsEnd-rsStart) * 2) - 1 ; actually p1 so adjust destination -: - ldy #(rsEnd-rsStart) - 1 ; set y to the end of the runtime stats -: - lda playerStats, x ; load a player stat byte - sta rsStart, y ; copy it to a runtime stat byte - dex ; next bytes - dey - bpl :- ; do for all bytes that need copying - - rts - -.endproc - -;----------------------------------------------------------------------------- -.proc gameWinSequence - - iterations = tempBlock + 0 ; how many times to do this loop - - inc lives ; give the player another life - lda #1 - sta updateHUD - jsr uiUpdateGameHud - jsr drawPresent ; get the score and live visible - - lda #$07 ; flash the screen iteration times - sta iterations - -: - jsr drawInvertVisibleScreen - - dec iterations - bne :- - - lda direction ; flip the direction - eor #1 - sta direction - beq :+ ; if dir zero - going out again from stage 0 - lda #3 ; zero based - second last stage - don't play nuke stage again -: - sta stage - - jsr uiWinScreen ; show the BONUS screen - - ldx #(NUM_STAGES - 2) ; start at the stage before the last (0 based) -: - dex ; step back - but the second last stage was already marked - bmi :+ ; if at -1 then all stages checked - lda makeMonster, x ; see if this stage has rockets turn into monsters yet - bne :- ; if yes, then keep looking for a stage without that - lda #1 ; mark this stage - sta makeMonster, x ; as now also having monster-rockets -: - - ldy activePlayer ; make sure the stats are backed up - jmp gameStatsToPlayer - -.endproc - -;----------------------------------------------------------------------------- -; Removes an enemy from screen that overlaps with zEnemyCol -; zaDrawSpriteWidth says how many columns to check - the bomb could -; kill in one of 2 columns, otherwise just one -.proc gameKillEnemy - - zaDrawSprWidth = tempBlock + 3 ; Parameter - zaSprColumn = tempBlock + 2 ; Internal segment/column of enemy sprite - zaEnemyColLocal = tempBlock + 4 ; Internal Backup copy of zEnemyCol but modified - - lda zEnemyCol - sta zaEnemyColLocal ; make a backup that's safe to change - - lda #0 ; reset the collision flag - sta zCollision - - ldy #$ff - sty enemyHitType - -loop: ; for the width to check - ldx zaEnemyColLocal - lda enemyBuffer, x ; see if there's an enemy - beq next - sta enemyHit ; save the flags of the enemy that was struck - - lsr ; see if it's a radar or missile - bcc other ; lsb clear means not a missile - lsr ; missile or nuke. 1 more shift to get column in lsb's - bcc missile - ldy #1 ; hit a nuke - sty victory - ldy #0 ; nuke is 0 in the score table - beq continue - -missile: - ldy #1 ; missile and nuke 2 columns wide - bne continue - -other: - lsr ; check next bit - bcc monster ; if also clear then a monster - ldy #3 ; radar is 4 columns wide - bne continue - -monster: - ldy #2 ; monster is 3 columns wide - -continue: - sty enemyHitType ; 0 = nuke, 1 = missile, 2 = monster, 3 = radar, $ff - nothing - bne :+ ; now Y is being used as column (width - 1) of the enemy - iny ; for the nuke, make y = 1 (it's still 0 here as the type) -: - and #%00000011 ; mask column (or strip of the sprite) - sta zaSprColumn ; save it - - lda audioFrame - ora #AUDIO_EXPLOSION ; Add explosion to audio frame - sta audioFrame - lda #0 ; start the explosion at frame 0 - sta audioExplFrame - - - lda zaEnemyColLocal ; see where the sprite starts - sec ; by subtracting the strip number (index) - sbc zaSprColumn ; from the current world column - tax ; and save that - - lda enemyHgtBuffer, x ; get the height of the enemy that's being killed - and #%11111000 ; mask off 3 bits for the explosion sprite frame cntr - sta explosionBuffer, x ; save as the explosion - - lda #0 ; write 0 to the enemy strip columns - sta enemyBuffer, x - sta enemyHgtBuffer, x - inx - sta enemyBuffer, x - sta enemyHgtBuffer, x - dey - beq next ; early out on missiles and nukes - inx - sta enemyBuffer, x - sta enemyHgtBuffer, x - dey - beq next ; early out on monsters - inx - sta enemyBuffer, x - sta enemyHgtBuffer, x - -next: - inc zaEnemyColLocal - dec zaDrawSprWidth - bne loop - - clc - rts - -.endproc - -;----------------------------------------------------------------------------- -; Add score for the enemy destroyed and mark the HUD as needing an update -; Acc is 0 = nuke, 1 = missile, 2 = monster, 3 = radar from enemyHitType -; The scoreTable score is "amended" in that flying objects get 4 added -; Scores appear on the hud at 10x the score variable value -.proc gameAddScore - - asl ; score table is 2 bytes wide - tax ; save the type - lda enemyHit ; see if this enemy was flying - and #%10000000 - bne flying - - lda #0 ; not flying - beq :+ - -flying: - lda #4 ; was flying -: - sed ; use decimal mode - adc scoreTable, x ; add across all 3 score bytes, as needed (3 bytes up to 999999 score) - adc score - sta score - inx - lda scoreTable, x - adc score + 1 - sta score + 1 - bcc :+ - lda #0 ; only adc and sbc work right in sed - adc score + 2 - sta score + 2 - clc -: - cld ; turn off decimal mode - - lda #2 - sta updateHUD - - rts - -.endproc diff --git a/src/apple2/input.inc b/src/apple2/input.inc deleted file mode 100644 index 1c1d330..0000000 --- a/src/apple2/input.inc +++ /dev/null @@ -1,414 +0,0 @@ -;----------------------------------------------------------------------------- -; input.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "CODE" - -;----------------------------------------------------------------------------- -.proc inputReadJoystick - - joyMask = tempBlock + 21 - - ldx #$0 ; start the x counter at 0 - ldy #$0 ; start the y counter at 0 - lda PTRIG ; trigger the fact that the joystick will be read - -readBoth: - lda PADDL0 ; get the value for X axis - bpl :+ ; if MSB is zero, done with X -upX: - inx ; increment the counter - bne :+ ; while x <> 0 go check y - dex ; if x reaches 0 it's overflow, set to 255 -: - lda PADDL0 + 1 ; read the value for the Y axis - bpl readX ; if MSB is zero Y is done - iny ; increment the Y counter - bne readBoth ; branch to the start to check both axis - dey ; if Y reaches 0 it's overflow, set to 255 and drop through to check x only - -readX: - lda PADDL0 ; get the value for X axis - bmi upX ; Y is done but X is not so go increment x - - lda #$ff ; Done analog. Start the digital mask with all On - - cpx #$20 ; compare to the low end dead zone - bcs :+ ; if greater than, then not left - eor #KEY_LEFT ; the joystick is left (bit is off) - bne chkY ; JuMP as acc is now non-zero -: - cpx #$60 ; check the upper bound of the dead-zone - bcc chkY ; if less than, then not right - eor #KEY_RIGHT ; gt high end of dead zone so joystick is right - -chkY: - cpy #$20 ; do the same for the Y axis as for the X axis - bcs :+ - eor #KEY_UP - bne buttons -: - cpy #$60 - bcc buttons - eor #KEY_DOWN - -buttons: - ldx BUTN0 ; read the button 0 state - cpx #$80 ; if ge 128 the button is fully depressed - bcc :+ - eor #KEY_FIRE ; mark the button as down - -: - ldx BUTN1 ; do the same for button 1 as for button 0 - cpx #$80 - bcc :+ - eor #KEY_BOMB - -: - sta joyMask ; save the mask - - rts - -.endproc - -;----------------------------------------------------------------------------- -; Reads the joystick and moves the player. -.proc inputGame - - zaRawInput = tempBlock + 1 - zaRawEor = tempBlock + 2 - - lda fireCoolDown - beq :+ - dec fireCoolDown -: - jsr inputReadJoystick - - sta zaRawInput ; save the input - eor #$ff ; invert the bits - sta zaRawEor ; save this state too - - lda zaRawInput ; no vertical move so process vertical joystick - -up: - bit Bit4Mask ; set when moving up - bne down - lda playerShipY ; and move the ship up 2 rows - sec - sbc #3 - cmp #(SHIP_HEIGHT+WORLD_START) ; limit at the top - bcc preLeft ; if too high, just ignore saving the move - sta playerShipY ; save the new position - bcs preLeft ; up, so skip down and check horizontal - -down: - bit Bit3Mask ; ser for joystick down - bne left - lda playerShipY ; move the ship 2 rows down - clc - adc #3 - cmp #(WORLD_END+1) ; limit at the bottom - bcs preBomb ; skip saving the new position if too low - sta playerShipY ; new position okay so save it - -preLeft: - lda zaRawInput ; no horizontal movement so process horiz joystick - -left: - bit Bit2Mask ; left sets this bit - bne right ; not set see if right is set - ldx playerShipX ; the ship should move left - dex ; move left one column - bmi preBomb ; if off-screen to the left, ignore - stx playerShipX ; save the movement - lda audioFrame - ora #AUDIO_MOTOR_REW - sta audioFrame - bne preBomb - -right: - bit Bit1Mask ; bit set when right joystick active - bne bomb ; if nothing, go process player movement - - ldx playerShipX ; get the ship position - inx ; move one column to the right - cpx #(((XSIZE/3)*2) - SHIP_WIDTH - 1) ; limit to two-thirds toward the right - bcs preBomb ; if over limit, ignore - stx playerShipX ; save movement - lda audioFrame - ora #AUDIO_MOTOR_FWD - sta audioFrame - -preBomb: - lda zaRawInput - -bomb: - bit Bit8Mask ; Button_A = bomb - bne fire - lda lastInput ; debounce the key for single shot - and zaRawEor - and Bit8Mask - beq nobomb ; bomb key not down - lda playerShipY ; bomb requested but can't - cmp #(WORLD_END-BOMB_HEIGHT) ; drop it when there's no room - bcs nobomb ; before the world end (else it draws out of bounds) - ldx #NUM_BOMBS-1 ; iterate over all bombs -: - lda bombY, x - beq drop ; find one that's available - dex - bpl :- - bmi nobomb ; none available -drop: - lda playerShipX ; bomb is relative to player - clc - adc #2 - sta bombX, x - lda playerShipY - adc #6 - sta bombY, x - lda #BOMB_FRWRD_FRMS ; set it to fly forward - sta bombDir, x - lda audioFrame - ora #AUDIO_BOMB_DROP - sta audioFrame -nobomb: - lda zaRawInput - -fire: - bit Bit7Mask ; Button_B = fire - bne joyDone - lda fireCoolDown - bne joyDone - lda lastInput ; debounce the key for single shot - and zaRawEor - and Bit7Mask - beq joyDone - lda playerShipX ; Put even/odd into carry - lsr - lda playerShipX ; bullets start relative to ship - adc #4 ; 4 for even, 5 for odd - adc bulletIndex - tax - lda playerShipY - sec - sbc #4 - sta bulletsBuffer, x ; put height into 3 columns - lda #3 - sta fireCoolDown - lda audioFrame - ora #AUDIO_FIRE - sta audioFrame - -joyDone: - lda zaRawInput ; remember the key-state for next time - sta lastInput ; so that fire and bombs can be debounced - - lda KBD ; leave with a key in the accumulator - bit KBDSTRB ; reset the key - - clc ; keep carry clear between routines - rts - -.endproc - -;----------------------------------------------------------------------------- -.proc inputEdit - - rawInput = tempBlock + 17 - rawEor = tempBlock + 18 - brushType = tempBlock + 16 - - lda KBD - bit Bit8Mask - beq :+ - bit KBDSTRB - and #$7f - bne :++ -: - lda #0 -: - pha - - jsr inputReadJoystick - sta rawInput ; save the input state - - pla - pha - cmp #' ' - bne :+ - lda rawInput - eor #KEY_SELECT - sta rawInput - pla - pha - -: - cmp #'B' - bne :+ - lda rawInput - eor #KEY_START - sta rawInput - -: - lda rawInput - eor #$ff ; invert the bits so 1 means button down - sta rawEor ; save the inverted bits - bit Bit6Mask ; see if select button is held - bne Button_B ; if it is down, key processing done - and lastInput ; otherwise debounce the keys - sta rawEor ; and save this state as the key state - - Button_B: - bit Bit7Mask ; Button_B - beq Button_A - lda #AUDIO_UI_TICK ; make a sound - sta audioFrame - jsr serviceAudio - lda brushType - bne radar - ora #KEY_RIGHT ; when pressed, move right as well - sta rawEor - jsr editSetTerrainBottom - jmp :+ - -radar: - jsr editSetRadar -: - lda rawEor ; no horizontal movement so process horiz joystick - -Button_A: - bit Bit8Mask ; Button_A - beq up - lda #AUDIO_UI_TICK ; make a sound - sta audioFrame - jsr serviceAudio - lda brushType - bne missile - ora #KEY_RIGHT - sta rawEor - jsr editSetTerrainTop - jmp :+ - -missile: - jsr editSetMissile -: - lda rawEor ; no horizontal movement so process horiz joystick - -up: - bit Bit4Mask ; set when moving up - beq down - ldx playerShipY - cpx #9 - bcc :+ - dex - stx playerShipY -: - lda rawEor ; no horizontal movement so process horiz joystick - -down: - bit Bit3Mask ; ser for joystick down - beq left - ldx playerShipY - cpx #WORLD_END - bcs :+ - inx - stx playerShipY -: - lda rawEor ; no horizontal movement so process horiz joystick - -left: - bit Bit2Mask ; left sets this bit - beq right ; not set see if right is set - jsr editGameWorldLeft - lda rawEor ; no horizontal movement so process horiz joystick - -right: - bit Bit1Mask ; bit set when right joystick active - beq Button_Start - jsr editGameWorldRight - -Button_Start: - lda rawInput ; This is a toggle so never auto-repeat - eor #$ff ; start from source - and lastInput ; and debounce - bit Bit5Mask ; test if Start button down - beq joyDone - lda #AUDIO_UI_TICK ; make a sound - sta audioFrame - jsr serviceAudio - lda brushType ; if down, toggle the brush type between terrain and enemies - eor #1 - sta brushType - jsr uiShowEditLabels ; update the HUD - -joyDone: - lda rawInput ; preserve this input for next frame as last input - sta lastInput ; so that fire and bombs can be debounced - - pla ; get the keyboard in accumulator - clc ; keep carry clear between routines - rts - -.endproc - -;----------------------------------------------------------------------------- -; Checks for a user input on keyboard or joystick -; upon exit - acc 0 means nothing, <> 0 means user input detected -.proc inputCheckForInput - - rawInput = tempBlock + 20 ; internal - - lda KBD - bit Bit8Mask - bne done ; if there's a key then done here - - jsr inputReadJoystick ; check the joystick - sta rawInput ; keep the raw bits - eor #$ff ; invert - and lastInput ; debounce - pha ; save this - lda rawInput ; back up the raw to the last - sta lastInput - pla ; and get back the debounced bits - beq done - - bit Bit7Mask ; FIRE should eq 1 player - beq :+ - lda #KEY_RIGHT - bne check ; JuMP - -: - bit Bit8Mask ; BOMB should eq 2 player - beq check - lda #KEY_LEFT - -check: - ldx #1 -: - lsr - bcs :+ - inx - bne :- -: - txa - -done: - and #$7f - beq :+ - - pha ; Save the "key" - lda #AUDIO_UI_TICK ; make a sound - sta audioFrame - jsr serviceAudio - pla ; restore the "key" - -: - rts ; upon return 0 means no interaction, anything else is a user input - -.endproc - diff --git a/src/apple2/logo.hgr b/src/apple2/logo.hgr deleted file mode 100644 index 8996695..0000000 Binary files a/src/apple2/logo.hgr and /dev/null differ diff --git a/src/apple2/logo.inc b/src/apple2/logo.inc deleted file mode 100644 index 3af3963..0000000 --- a/src/apple2/logo.inc +++ /dev/null @@ -1,10 +0,0 @@ -;----------------------------------------------------------------------------- -; logo.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Oliver Schmidt, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "HGR" -.incbin "logo.hgr" diff --git a/src/apple2/logodata.inc b/src/apple2/logodata.inc deleted file mode 100644 index 42ef310..0000000 --- a/src/apple2/logodata.inc +++ /dev/null @@ -1,56 +0,0 @@ -;----------------------------------------------------------------------------- -; logodata.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "RODATA" - -;----------------------------------------------------------------------------- -; x/y coordinates for lines that spell out Penetrator -dataLogoLines: -.byte $00, $0C, $00, $26 -.byte $01, $0D, $07, $13 -.byte $06, $14, $01, $19 -.byte $02, $21, $08, $1C -.byte $09, $1B, $02, $1B -.byte $02, $1C, $05, $22 -.byte $06, $22, $0B, $1D -.byte $0C, $1C, $0C, $17 -.byte $0D, $17, $10, $1F -.byte $11, $1E, $11, $16 -.byte $14, $1B, $19, $15 -.byte $19, $14, $14, $14 -.byte $14, $15, $13, $16 -.byte $13, $17, $17, $1D -.byte $17, $1C, $1B, $16 -.byte $1B, $15, $1D, $09 -.byte $1E, $0A, $1E, $1A -.byte $1D, $14, $21, $14 -.byte $22, $15, $23, $16 -.byte $22, $1B, $24, $12 -.byte $25, $11, $28, $11 -.byte $28, $12, $29, $13 -.byte $25, $19, $26, $17 -.byte $27, $16, $29, $16 -.byte $29, $17, $2C, $1C -.byte $2B, $1D, $29, $1F -.byte $28, $1F, $27, $1F -.byte $26, $1E, $25, $1D -.byte $25, $1C, $27, $1A -.byte $28, $1A, $29, $1A -.byte $2C, $1C, $2E, $16 -.byte $2E, $15, $30, $0E -.byte $31, $10, $31, $22 -.byte $2F, $1A, $34, $1A -.byte $32, $21, $35, $1B -.byte $36, $1B, $39, $1E -.byte $39, $1F, $36, $22 -.byte $36, $22, $34, $20 -.byte $38, $26, $3A, $1C -.byte $3B, $1B, $3C, $1B -.byte $3D, $1B, $3E, $1B -.byte $3E, $1C, $3F, $1D -dataLogoLinesEnd: diff --git a/src/apple2/macros.inc b/src/apple2/macros.inc deleted file mode 100644 index b7adfbd..0000000 --- a/src/apple2/macros.inc +++ /dev/null @@ -1,128 +0,0 @@ -;----------------------------------------------------------------------------- -; macros.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.macro printZAStr sx, sy - - .if .paramcount <> 2 - .error "Parameters issue for macro printZAStr" - .endif - - .local textX, textY - - textX = tempBlock + 10 - textY = tempBlock + 11 - - lda sx - sta textX - lda sy - sta textY - jsr textOut - -.endmacro - -;----------------------------------------------------------------------------- -.macro print szText, sx, sy - - .if .paramcount <> 3 - .error "Parameters issue for macro print" - .endif - - .local zaStrL, zaStrH, textX, textY - - zaStrL = tempBlock + 1 - zaStrH = tempBlock + 2 - - lda #szText - sta zaStrH - - printZAStr sx, sy - -.endmacro - -;----------------------------------------------------------------------------- -.macro printBCD number, digits, force, sx, sy - - .if .paramcount <> 5 - .error "Parameters issue for macro printBCD" - .endif - - .local zaStrL, zaStrH - - zaStrL = tempBlock + 1 - zaStrH = tempBlock + 2 - - lda #number - sta zaStrH - ldy digits - ldx force - jsr textBCDtoSZ - - print textNumber, sx, sy - -.endmacro - -;----------------------------------------------------------------------------- -.macro printBig szText, sx, sy, wx, hy - - .if .paramcount <> 5 - .error "Parameters issue for macro printBig" - .endif - - .local zaStrL, zaStrH, width, textX, textY, height - - zaStrL = tempBlock + 1 - zaStrH = tempBlock + 2 - textX = tempBlock + 12 - textY = tempBlock + 13 - width = tempBlock + 14 ; shared with drawPlotXY - height = tempBlock + 15 - - - lda #szText - sta zaStrH - lda sx - sta textX - lda sy - sta textY - lda wx - sta width - lda hy - sta height - jsr textBigPrint - -.endmacro - -;----------------------------------------------------------------------------- -.macro wait time - - .if .paramcount <> 1 - .error "Parameters issue for macro wait" - .endif - - .local loop, loopo - - lda time - sta tempBlock + 20 - ldx #0 -loopo: - ldy #$10 -loop: - dex - bne loop - dey - bne loop - dec tempBlock + 20 - bne loopo - -.endmacro diff --git a/src/apple2/penetrator.asm b/src/apple2/penetrator.asm deleted file mode 100644 index cf9f2ec..0000000 --- a/src/apple2/penetrator.asm +++ /dev/null @@ -1,114 +0,0 @@ -;----------------------------------------------------------------------------- -; penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. -; -; Use the ca65 assembler and make to build - -;----------------------------------------------------------------------------- -; assembler directives -.debuginfo on -.listbytes unlimited - -;----------------------------------------------------------------------------- -.segment "CODE" - -;----------------------------------------------------------------------------- -jmp main ; This ends up at $080d (sys 2061's target) - -;----------------------------------------------------------------------------- -.include "apple2.inc" ; Apple II locations from cc65 -.include "defs.inc" ; constants -.include "macros.inc" ; vpoke, vpeek, print* & wait. -.include "zpvars.inc" ; Zero Page usage (variables) -.include "audio.inc" ; Play notes fro audio events -.include "input.inc" ; Keyboard/Joystick routines -.include "ui.inc" ; The front-end code -.include "edit.inc" ; In-game editor -.include "game.inc" ; All gameplay code -.include "terrain.inc" ; Code that writes the terrain to HRG -.include "draw.inc" ; Code that writes to HRG -.include "text.inc" ; The text and text printing code -.include "file.inc" ; LOAD / SAVE routine -.include "variables.inc" ; Game Variables (DATA segment) -.include "trndata.inc" ; Terrain triplets -.include "fontdata.inc" ; The ZA Spectrum font as 2bpp, 2 bytes/char -.include "logodata.inc" ; Lines to spell Penetrator and intro graphic -.include "rodata.inc" ; Read Only (RODATA segment sprites, etc) -.include "logo.inc" ; The include to include the HGR image - -;----------------------------------------------------------------------------- -.segment "CODE" - -;----------------------------------------------------------------------------- -.proc main - - jsr mainGameSetup -: - jsr inputCheckForInput ; wait for user interaction - beq :- - jsr drawClearScreen - jsr drawPresent -: - jsr uiTitleScreen - jsr uiMainMenu - jmp :- - -.endproc - -;----------------------------------------------------------------------------- -.proc mainGameSetup - - lda #$0 - sta backLayer ; set back layer to 0 - sta audioFrame ; set all audio channels to off (0) - sta numPlayers ; Init initially to 0 (not set for training) - - lda PATHNAME ; length of file path - tax ; put in index -: - lda PATHNAME, x ; get character - cmp #'/' ; look backwards for directory seperator - beq :+ - dex - bne :- - -: - inx ; 1 or 1 past / is where the file name starts - stx pathPos ; save that location - - jsr loadHighScores ; load high scores from disc - bcc cont ; on success, skip the init - - ldx #((textHSEnd-textHS) - 1) ; empty the high score names to spaces -store: - lda textHS, x - beq :+ ; skip the null terminators - lda #$20 ; load the space (" ") character - sta textHS, x ; write it to the text areas -: - dex - bpl store - - lda #$0 - ldx #((highScoresEnd-highScores) - 1) ; set high score table scores to 0 -: - sta highScores, x - dex - bpl :- - -cont: - lda #(AUDIO_EXPLOSION | AUDIO_BOMB_DROP | AUDIO_FIRE | AUDIO_UI_TICK) - sta audioMask ; set the mask for default ON channels - - ldx #((BitMasksEnd - BitMasks) - 1) -: - lda BitMasks, x - sta Bit1Mask, x - dex - bpl :- - - rts - -.endproc diff --git a/src/apple2/penetrator.cfg b/src/apple2/penetrator.cfg deleted file mode 100644 index a907e48..0000000 --- a/src/apple2/penetrator.cfg +++ /dev/null @@ -1,19 +0,0 @@ -SYMBOLS { - __EXEHDR__: type = import; - __FILETYPE__: type = export, value = $0006; -} -MEMORY { - ZP: file = "", start = $0050, size = $0100 - $0050; - HEADER: file = %O, start = $4000 - $003A, size = $003A; - MAIN: file = %O, define = yes, start = $4000, size = $BF00 - $4000; - BSS: file = "", start = $0800, size = $2000 - $0800; -} -SEGMENTS { - ZEROPAGE: load = ZP, type = zp; - EXEHDR: load = HEADER, type = ro; - HGR: load = MAIN, type = rw; - CODE: load = MAIN, type = rw, start = $6000; - RODATA: load = MAIN, type = ro; - DATA: load = MAIN, type = rw; - BSS: load = BSS, type = bss; -} diff --git a/src/apple2/rodata.inc b/src/apple2/rodata.inc deleted file mode 100644 index 399f5b5..0000000 --- a/src/apple2/rodata.inc +++ /dev/null @@ -1,797 +0,0 @@ -;----------------------------------------------------------------------------- -; rodata.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "RODATA" - -;----------------------------------------------------------------------------- -; the lo byte for the memory at the start of every screen row -rowL: - .repeat $C0, Row - .byte XINSET + Row & $08 << 4 | Row & $C0 >> 1 | Row & $C0 >> 3 - .endrep - -;----------------------------------------------------------------------------- -; the hi byte for the memory at the start of every screen row -rowH: - .repeat $C0, Row - .byte >$0000 | Row & $07 << 2 | Row & $30 >> 4 - .endrep - -;----------------------------------------------------------------------------- -; pixels in format for drawPlotXY -plotPix: .byte %00001111, %01111000 - -;----------------------------------------------------------------------------- -; Offsets for printing the high score table on the title screen -scoreTextOffset: -.byte textHighScore1-textHS -.byte textHighScore2-textHS -.byte textHighScore3-textHS -.byte textHighScore4-textHS -.byte textHighScore5-textHS -scoreTextPosX: -.byte 10, 02, 18, 1, 19 -scoreTextPosY: -.byte 8 , 16, 16, 24, 24 -scorePosX: -.byte 17, 09, 25, 08, 26 - -;----------------------------------------------------------------------------- -radarAL: -.byte radar0A, >(radar0U + 1), >(radar0A + 1), >(radar0U + 2) -.byte >radar1A, >(radar1U + 1), >(radar1A + 1), >(radar1U + 2) -.byte >radar2A, >(radar2U + 1), >(radar2A + 1), >(radar2U + 2) -.byte >radar3A, >(radar3U + 1), >(radar3A + 1), >(radar3U + 2) -.byte >radar4A, >(radar4U + 1), >(radar4A + 1), >(radar4U + 2) -.byte >radar5A, >(radar5U + 1), >(radar5A + 1), >(radar5U + 2) -.byte >radar6A, >(radar6U + 1), >(radar6A + 1), >(radar6U + 2) -.byte >radar7A, >(radar7U + 1), >(radar7A + 1), >(radar7U + 2) -radarUL: -.byte radar0U -.byte >radar1U -.byte >radar2U -.byte >radar3U -.byte >radar4U -.byte >radar5U -.byte >radar6U -.byte >radar7U -radarAS: -.byte 4, 3, 2, 1 -radarAD: -.byte 2, 3, 2, 3 -radarAR: -.byte 1, 1, 0, 0 - -;----------------------------------------------------------------------------- -missileAL: -.byte missile0A, >missile1A, >(missile0U + 1), >(missile1U + 1) -missileUL: -.byte missile0U, >missile1U -missileAD: -.byte 1, 1, 2, 2 - -;----------------------------------------------------------------------------- -bombAL: -.byte bomb0A, >bomb1A -bombUL: -.byte bomb0U, >bomb1U -bombH: -.byte 6, 5 - -;----------------------------------------------------------------------------- -monsterAL: -.byte monsterA, >(monsterU + 1), >(monsterA+1) -monsterAS: -.byte 3, 2, 1 -monsterAR: -.byte 1, 0, 0 - -;----------------------------------------------------------------------------- -nukeAL: -.byte nukeA, >(nukeU + 1) -nukeUL: -.byte nukeU -nukeAD: -.byte 1, 2 - -;----------------------------------------------------------------------------- -explosionAL: -.byte explosion0A -.byte >explosion1A -.byte >explosion2A -.byte >explosion3A -explosionUL: -.byte explosion0U -.byte >explosion1U -.byte >explosion2U -.byte >explosion3U - -;----------------------------------------------------------------------------- -layersL: -.byte ram_layer0, >ram_layer1 - -;----------------------------------------------------------------------------- -; nuke, missile, monster, radar -scoreTable: -.word $0100, $0001, $0002, $0010 - -;----------------------------------------------------------------------------- -BitMasks: -.byte %00000001 -.byte %00000010 -.byte %00000100 -.byte %00001000 -.byte %00010000 -.byte %00100000 -.byte %01000000 -.byte %10000000 -.byte %00000011 -.byte %00001100 -.byte %01100000 -.byte %10001110 -.byte %11110000 -BitMasksEnd: - -;----------------------------------------------------------------------------- -; Audio delay values -explDelay: - .byte $04, $08, $06, $04 - -;----------------------------------------------------------------------------- -; Sprite Information -; Images to the right in human form, not Apple II form (i.e. bytes don't -; neccesarily match visuals). Rendering is bottom up so stored upside-down. - -missile0A: -.byte $41 ; X.....X -.byte $41 ; X.....X -.byte $41 ; X.....X -.byte $63 ; XX...XX -.byte $63 ; XX...XX -.byte $7F ; XXXXXXX -.byte $3E ; .XXXXX. -.byte $22 ; .X...X. -.byte $3E ; .XXXXX. -.byte $1C ; ..XXX.. -.byte $1C ; ..XXX.. -.byte $08 ; ...X... -.byte $08 ; ...X... -.byte $08 ; ...X... - -missile0U: -.byte $10, $08 ; ....X.....X... -.byte $10, $08 ; ....X.....X... -.byte $10, $08 ; ....X.....X... -.byte $30, $0C ; ....XX...XX... -.byte $30, $0C ; ....XX...XX... -.byte $70, $0F ; ....XXXXXXX... -.byte $60, $07 ; .....XXXXX.... -.byte $20, $04 ; .....X...X.... -.byte $60, $07 ; .....XXXXX.... -.byte $40, $03 ; ......XXX..... -.byte $40, $03 ; ......XXX..... -.byte $00, $01 ; .......X...... -.byte $00, $01 ; .......X...... -.byte $00, $01 ; .......X...... - -missile1A: -.byte $55 ; X.X.X.X -.byte $5D ; X.XXX.X -.byte $49 ; X..X..X -.byte $6B ; XX.X.XX -.byte $63 ; XX...XX -.byte $7F ; XXXXXXX -.byte $3E ; .XXXXX. -.byte $22 ; .X...X. -.byte $3E ; .XXXXX. -.byte $1C ; ..XXX.. -.byte $1C ; ..XXX.. -.byte $08 ; ...X... -.byte $08 ; ...X... -.byte $08 ; ...X... - -missile1U: -.byte $50, $0A ; ....X.X.X.X... -.byte $50, $0B ; ....X.XXX.X... -.byte $10, $09 ; ....X..X..X... -.byte $30, $0D ; ....XX.X.XX... -.byte $30, $0C ; ....XX...XX... -.byte $70, $0F ; ....XXXXXXX... -.byte $60, $07 ; .....XXXXX.... -.byte $20, $04 ; .....X...X.... -.byte $60, $07 ; .....XXXXX.... -.byte $40, $03 ; ......XXX..... -.byte $40, $03 ; ......XXX..... -.byte $00, $01 ; .......X...... -.byte $00, $01 ; .......X...... -.byte $00, $01 ; .......X...... - - -radar0A: -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $70, $07 ; ....XXXXXX.... -.byte $70, $07 ; ....XXXXXX.... -.byte $20, $02 ; .....X..X..... -.byte $70, $07 ; ....XXXXXX.... -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $7E, $3F ; .XXXXXXXXXXXX. -.byte $7F, $7F ; XXXXXXXXXXXXXX -.byte $7F, $7F ; XXXXXXXXXXXXXX -.byte $7F, $7F ; XXXXXXXXXXXXXX -.byte $7E, $3F ; .XXXXXXXXXXXX. -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $70, $07 ; ....XXXXXX.... -.byte $40, $01 ; ......XX...... -.byte $40, $01 ; ......XX...... - -radar0U: -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $24, $00 ; .........X..X........ -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $60, $7F, $07 ; .....XXXXXXXXXXXX.... -.byte $70, $7F, $0F ; ....XXXXXXXXXXXXXX... -.byte $70, $7F, $0F ; ....XXXXXXXXXXXXXX... -.byte $70, $7F, $0F ; ....XXXXXXXXXXXXXX... -.byte $60, $7F, $07 ; .....XXXXXXXXXXXX.... -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $18, $00 ; ..........XX......... -.byte $00, $18, $00 ; ..........XX......... - -radar1A: -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $70, $07 ; ....XXXXXX.... -.byte $70, $07 ; ....XXXXXX.... -.byte $20, $02 ; .....X..X..... -.byte $78, $03 ; ...XXXXXX..... -.byte $7C, $01 ; ..XXXXXX...... -.byte $7C, $03 ; ..XXXXXXX..... -.byte $7C, $07 ; ..XXXXXXXX.... -.byte $78, $0F ; ...XXXXXXXX... -.byte $70, $0F ; ....XXXXXXX... -.byte $60, $0F ; .....XXXXXX... -.byte $70, $0F ; ....XXXXXXX... -.byte $58, $07 ; ...XX.XXXX.... -.byte $08, $02 ; ...X....X..... -.byte $00, $00 ; .............. - -radar1U: -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $24, $00 ; .........X..X........ -.byte $00, $3F, $00 ; .......XXXXXX........ -.byte $40, $1F, $00 ; ......XXXXXX......... -.byte $40, $3F, $00 ; ......XXXXXXX........ -.byte $40, $7F, $00 ; ......XXXXXXXX....... -.byte $00, $7F, $01 ; .......XXXXXXXX...... -.byte $00, $7E, $01 ; ........XXXXXXX...... -.byte $00, $7C, $01 ; .........XXXXXX...... -.byte $00, $7E, $01 ; ........XXXXXXX...... -.byte $00, $7B, $00 ; .......XX.XXXX....... -.byte $00, $21, $00 ; .......X....X........ -.byte $00, $00, $00 ; ..................... - -radar2A: -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $70, $07 ; ....XXXXXX.... -.byte $70, $07 ; ....XXXXXX.... -.byte $20, $02 ; .....X..X..... -.byte $70, $03 ; ....XXXXX..... -.byte $78, $01 ; ...XXXXX...... -.byte $7C, $03 ; ..XXXXXXX..... -.byte $60, $07 ; .....XXXXX.... -.byte $40, $07 ; ......XXXX.... -.byte $40, $07 ; ......XXXX.... -.byte $60, $07 ; .....XXXXX.... -.byte $30, $07 ; ....XX.XXX.... -.byte $18, $03 ; ...XX..XX..... -.byte $00, $01 ; .......X...... -.byte $00, $00 ; .............. - -radar2U: -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $24, $00 ; .........X..X........ -.byte $00, $3E, $00 ; ........XXXXX........ -.byte $00, $1F, $00 ; .......XXXXX......... -.byte $40, $3F, $00 ; ......XXXXXXX........ -.byte $00, $7C, $00 ; .........XXXXX....... -.byte $00, $78, $00 ; ..........XXXX....... -.byte $00, $78, $00 ; ..........XXXX....... -.byte $00, $7C, $00 ; .........XXXXX....... -.byte $00, $76, $00 ; ........XX.XXX....... -.byte $00, $33, $00 ; .......XX..XX........ -.byte $00, $10, $00 ; ...........X......... -.byte $00, $00, $00 ; ..................... - -radar3A: -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $70, $07 ; ....XXXXXX.... -.byte $70, $07 ; ....XXXXXX.... -.byte $20, $02 ; .....X..X..... -.byte $78, $03 ; ...XXXXXX..... -.byte $7C, $01 ; ..XXXXXX...... -.byte $44, $03 ; ..X...XXX..... -.byte $04, $07 ; ..X....XXX.... -.byte $64, $0E ; ..X..XX.XXX... -.byte $68, $0C ; ...X.XX..XX... -.byte $10, $08 ; ....X.....X... -.byte $30, $08 ; ....XX....X... -.byte $48, $04 ; ...X..X..X.... -.byte $08, $03 ; ...X...XX..... -.byte $00, $00 ; .............. - -radar3U: -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $24, $00 ; .........X..X........ -.byte $00, $3F, $00 ; .......XXXXXX........ -.byte $40, $1F, $00 ; ......XXXXXX......... -.byte $40, $38, $00 ; ......X...XXX........ -.byte $40, $70, $00 ; ......X....XXX....... -.byte $40, $6C, $01 ; ......X..XX.XXX...... -.byte $00, $4D, $01 ; .......X.XX..XX...... -.byte $00, $02, $01 ; ........X.....X...... -.byte $00, $06, $01 ; ........XX....X...... -.byte $00, $49, $00 ; .......X..X..X....... -.byte $00, $31, $00 ; .......X...XX........ -.byte $00, $00, $00 ; ..................... - -radar4A: -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $70, $07 ; ....XXXXXX.... -.byte $70, $07 ; ....XXXXXX.... -.byte $20, $02 ; .....X..X..... -.byte $70, $07 ; ....XXXXXX.... -.byte $0C, $18 ; ..XX......XX.. -.byte $02, $20 ; .X..........X. -.byte $01, $40 ; X............X -.byte $41, $41 ; X.....XX.....X -.byte $41, $41 ; X.....XX.....X -.byte $42, $21 ; .X....XX....X. -.byte $4C, $19 ; ..XX..XX..XX.. -.byte $70, $07 ; ....XXXXXX.... -.byte $40, $01 ; ......XX...... -.byte $40, $01 ; ......XX...... - -radar4U: -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $24, $00 ; .........X..X........ -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $40, $01, $03 ; ......XX......XX..... -.byte $20, $00, $04 ; .....X..........X.... -.byte $10, $00, $08 ; ....X............X... -.byte $10, $18, $08 ; ....X.....XX.....X... -.byte $10, $18, $08 ; ....X.....XX.....X... -.byte $20, $18, $04 ; .....X....XX....X.... -.byte $40, $19, $03 ; ......XX..XX..XX..... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $18, $00 ; ..........XX......... -.byte $00, $18, $00 ; ..........XX......... - -radar5A: -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $70, $07 ; ....XXXXXX.... -.byte $70, $07 ; ....XXXXXX.... -.byte $20, $02 ; .....X..X..... -.byte $60, $0F ; .....XXXXXX... -.byte $40, $1F ; ......XXXXXX.. -.byte $60, $11 ; .....XXX...X.. -.byte $70, $10 ; ....XXX....X.. -.byte $38, $13 ; ...XXX.XX..X.. -.byte $18, $0B ; ...XX..XX.X... -.byte $08, $04 ; ...X.....X.... -.byte $08, $06 ; ...X....XX.... -.byte $10, $09 ; ....X..X..X... -.byte $60, $08 ; .....XX...X... -.byte $00, $00 ; .............. - -radar5U: -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $24, $00 ; .........X..X........ -.byte $00, $7C, $01 ; .........XXXXXX...... -.byte $00, $78, $03 ; ..........XXXXXX..... -.byte $00, $1C, $02 ; .........XXX...X..... -.byte $00, $0E, $02 ; ........XXX....X..... -.byte $00, $37, $02 ; .......XXX.XX..X..... -.byte $00, $33, $01 ; .......XX..XX.X...... -.byte $00, $41, $00 ; .......X.....X....... -.byte $00, $61, $00 ; .......X....XX....... -.byte $00, $12, $01 ; ........X..X..X...... -.byte $00, $0C, $01 ; .........XX...X...... -.byte $00, $00, $00 ; ..................... - -radar6A: -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $70, $07 ; ....XXXXXX.... -.byte $70, $07 ; ....XXXXXX.... -.byte $20, $02 ; .....X..X..... -.byte $60, $07 ; .....XXXXX.... -.byte $40, $0F ; ......XXXXX... -.byte $60, $1F ; .....XXXXXXX.. -.byte $70, $03 ; ....XXXXX..... -.byte $70, $01 ; ....XXXX...... -.byte $70, $01 ; ....XXXX...... -.byte $70, $03 ; ....XXXXX..... -.byte $70, $06 ; ....XXX.XX.... -.byte $60, $0C ; .....XX..XX... -.byte $40, $00 ; ......X....... -.byte $00, $00 ; .............. - -radar6U: -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $24, $00 ; .........X..X........ -.byte $00, $7C, $00 ; .........XXXXX....... -.byte $00, $78, $01 ; ..........XXXXX...... -.byte $00, $7C, $03 ; .........XXXXXXX..... -.byte $00, $3E, $00 ; ........XXXXX........ -.byte $00, $1E, $00 ; ........XXXX......... -.byte $00, $1E, $00 ; ........XXXX......... -.byte $00, $3E, $00 ; ........XXXXX........ -.byte $00, $6E, $00 ; ........XXX.XX....... -.byte $00, $4C, $01 ; .........XX..XX...... -.byte $00, $08, $00 ; ..........X.......... -.byte $00, $00, $00 ; ..................... - -radar7A: -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $7C, $1F ; ..XXXXXXXXXX.. -.byte $70, $07 ; ....XXXXXX.... -.byte $70, $07 ; ....XXXXXX.... -.byte $20, $02 ; .....X..X..... -.byte $60, $0F ; .....XXXXXX... -.byte $40, $1F ; ......XXXXXX.. -.byte $60, $1F ; .....XXXXXXX.. -.byte $70, $1F ; ....XXXXXXXX.. -.byte $78, $0F ; ...XXXXXXXX... -.byte $78, $07 ; ...XXXXXXX.... -.byte $78, $03 ; ...XXXXXX..... -.byte $78, $07 ; ...XXXXXXX.... -.byte $70, $0D ; ....XXXX.XX... -.byte $20, $08 ; .....X....X... -.byte $00, $00 ; .............. - -radar7U: -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $40, $7F, $03 ; ......XXXXXXXXXX..... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $7E, $00 ; ........XXXXXX....... -.byte $00, $24, $00 ; .........X..X........ -.byte $00, $7C, $01 ; .........XXXXXX...... -.byte $00, $78, $03 ; ..........XXXXXX..... -.byte $00, $7C, $03 ; .........XXXXXXX..... -.byte $00, $7E, $03 ; ........XXXXXXXX..... -.byte $00, $7F, $01 ; .......XXXXXXXX...... -.byte $00, $7F, $00 ; .......XXXXXXX....... -.byte $00, $3F, $00 ; .......XXXXXX........ -.byte $00, $7F, $00 ; .......XXXXXXX....... -.byte $00, $5E, $01 ; ........XXXX.XX...... -.byte $00, $04, $01 ; .........X....X...... -.byte $00, $00, $00 ; ..................... - -explosion0A: - .byte $04, $00 ; ..X........... - .byte $0C, $00 ; ..XX.......... - .byte $00, $41 ; .......X.....X - .byte $00, $00 ; .............. - .byte $00, $10 ; ...........X.. - .byte $49, $01 ; X..X..XX...... - .byte $60, $07 ; .....XXXXX.... - .byte $60, $0F ; .....XXXXXX... - .byte $60, $2F ; .....XXXXXX.X. - .byte $60, $03 ; .....XXXX..... - .byte $08, $02 ; ...X....X..... - .byte $00, $10 ; ...........X.. - .byte $30, $00 ; ....XX........ - .byte $31, $00 ; X...XX........ - .byte $01, $62 ; X.......X...XX - .byte $00, $00 ; .............. - -explosion0U: - .byte $20, $00, $00 ; .....X............... - .byte $60, $00, $00 ; .....XX.............. - .byte $00, $08, $04 ; ..........X.....X.... - .byte $00, $00, $00 ; ..................... - .byte $00, $00, $01 ; ..............X...... - .byte $48, $0C, $00 ; ...X..X..XX.......... - .byte $00, $3E, $00 ; ........XXXXX........ - .byte $00, $7E, $00 ; ........XXXXXX....... - .byte $00, $7E, $02 ; ........XXXXXX.X..... - .byte $00, $1E, $00 ; ........XXXX......... - .byte $40, $10, $00 ; ......X....X......... - .byte $00, $00, $01 ; ..............X...... - .byte $00, $03, $00 ; .......XX............ - .byte $08, $03, $00 ; ...X...XX............ - .byte $08, $10, $06 ; ...X.......X...XX.... - .byte $00, $00, $00 ; ..................... - -explosion1A: - .byte $06, $00 ; .XX........... - .byte $04, $42 ; ..X.....X....X - .byte $00, $00 ; .............. - .byte $00, $20 ; ............X. - .byte $44, $01 ; ..X...XX...... - .byte $10, $0D ; ....X..X.XX... - .byte $50, $17 ; ....X.XXXX.X.. - .byte $60, $0A ; .....XX.X.X... - .byte $60, $0C ; .....XX..XX... - .byte $68, $41 ; ...X.XXX.....X - .byte $18, $02 ; ...XX...X..... - .byte $00, $08 ; ..........X... - .byte $00, $20 ; ............X. - .byte $30, $00 ; ....XX........ - .byte $14, $40 ; ..X.X........X - .byte $00, $04 ; .........X.... - -explosion1U: - .byte $30, $00, $00 ; ....XX............... - .byte $20, $10, $04 ; .....X.....X....X.... - .byte $00, $00, $00 ; ..................... - .byte $00, $00, $02 ; ...............X..... - .byte $20, $0C, $00 ; .....X...XX.......... - .byte $00, $69, $00 ; .......X..X.XX....... - .byte $00, $3D, $01 ; .......X.XXXX.X...... - .byte $00, $56, $00 ; ........XX.X.X....... - .byte $00, $66, $00 ; ........XX..XX....... - .byte $40, $0E, $04 ; ......X.XXX.....X.... - .byte $40, $11, $00 ; ......XX...X......... - .byte $00, $40, $00 ; .............X....... - .byte $00, $00, $02 ; ...............X..... - .byte $00, $03, $00 ; .......XX............ - .byte $20, $01, $04 ; .....X.X........X.... - .byte $00, $20, $00 ; ............X........ - -explosion2A: -.byte $02, $04 ; .X.......X.... -.byte $00, $00 ; .............. -.byte $20, $40 ; .....X.......X -.byte $01, $21 ; X......X....X. -.byte $04, $09 ; ..X....X..X... -.byte $10, $00 ; ....X......... -.byte $10, $14 ; ....X....X.X.. -.byte $24, $20 ; ..X..X......X. -.byte $20, $08 ; .....X....X... -.byte $12, $00 ; .X..X......... -.byte $08, $02 ; ...X....X..... -.byte $0A, $21 ; .X.X...X....X. -.byte $00, $00 ; .............. -.byte $10, $40 ; ....X........X -.byte $04, $00 ; ..X........... -.byte $09, $40 ; X..X.........X - -explosion2U: -.byte $10, $20, $00 ; ....X.......X........ -.byte $00, $00, $00 ; ..................... -.byte $00, $02, $04 ; ........X.......X.... -.byte $08, $08, $02 ; ...X......X....X..... -.byte $20, $48, $00 ; .....X....X..X....... -.byte $00, $01, $00 ; .......X............. -.byte $00, $21, $01 ; .......X....X.X...... -.byte $20, $02, $02 ; .....X..X......X..... -.byte $00, $42, $00 ; ........X....X....... -.byte $10, $01, $00 ; ....X..X............. -.byte $40, $10, $00 ; ......X....X......... -.byte $50, $08, $02 ; ....X.X...X....X..... -.byte $00, $00, $00 ; ..................... -.byte $00, $01, $04 ; .......X........X.... -.byte $20, $00, $00 ; .....X............... -.byte $48, $00, $04 ; ...X..X.........X.... - -explosion3A: -.byte $00, $00 ; .............. -.byte $02, $10 ; .X.........X.. -.byte $20, $04 ; .....X...X.... -.byte $01, $01 ; X......X...... -.byte $00, $40 ; .............X -.byte $04, $00 ; ..X........... -.byte $08, $10 ; ...X.......X.. -.byte $41, $00 ; X.....X....... -.byte $00, $20 ; ............X. -.byte $01, $01 ; X......X...... -.byte $10, $00 ; ....X......... -.byte $00, $08 ; ..........X... -.byte $02, $02 ; .X......X..... -.byte $04, $00 ; ..X........... -.byte $00, $10 ; ...........X.. -.byte $01, $00 ; X............. - -explosion3U: -.byte $00, $00, $00 ; ..................... -.byte $10, $00, $01 ; ....X.........X...... -.byte $00, $22, $00 ; ........X...X........ -.byte $08, $08, $00 ; ...X......X.......... -.byte $00, $00, $04 ; ................X.... -.byte $20, $00, $00 ; .....X............... -.byte $40, $00, $01 ; ......X.......X...... -.byte $08, $04, $00 ; ...X.....X........... -.byte $00, $00, $02 ; ...............X..... -.byte $08, $08, $00 ; ...X......X.......... -.byte $00, $01, $00 ; .......X............. -.byte $00, $40, $00 ; .............X....... -.byte $10, $10, $00 ; ....X......X......... -.byte $20, $00, $00 ; .....X............... -.byte $00, $00, $01 ; ..............X...... -.byte $08, $00, $00 ; ...X................. - -monsterA: -.byte $78, $00 ; ...XXXX....... -.byte $4C, $01 ; ..XX..XX...... -.byte $7C, $01 ; ..XXXXXX...... -.byte $7E, $03 ; .XXXXXXXX..... -.byte $37, $07 ; XXX.XX.XXX.... -.byte $33, $06 ; XX..XX..XX.... -.byte $33, $06 ; XX..XX..XX.... -.byte $7B, $06 ; XX.XXXX.XX.... -.byte $7F, $07 ; XXXXXXXXXX.... -.byte $7E, $03 ; .XXXXXXXX..... -.byte $7F, $07 ; XXXXXXXXXX.... -.byte $7B, $06 ; XX.XXXX.XX.... -.byte $01, $04 ; X........X.... - -monsterU: -.byte $00, $0F ; .......XXXX... -.byte $40, $19 ; ......XX..XX.. -.byte $40, $1F ; ......XXXXXX.. -.byte $60, $3F ; .....XXXXXXXX. -.byte $70, $76 ; ....XXX.XX.XXX -.byte $30, $66 ; ....XX..XX..XX -.byte $30, $66 ; ....XX..XX..XX -.byte $30, $6F ; ....XX.XXXX.XX -.byte $70, $7F ; ....XXXXXXXXXX -.byte $60, $3F ; .....XXXXXXXX. -.byte $70, $7F ; ....XXXXXXXXXX -.byte $30, $6F ; ....XX.XXXX.XX -.byte $10, $40 ; ....X........X - -nukeA: -.byte $3F ; XXXXXX. -.byte $12 ; .X..X.. -.byte $0C ; ..XX... -.byte $12 ; .X..X.. -.byte $2D ; X.XX.X. -.byte $2D ; X.XX.X. -.byte $12 ; .X..X.. -.byte $0C ; ..XX... - -nukeU: -.byte $70, $07 ; ....XXXXXX.... -.byte $20, $02 ; .....X..X..... -.byte $40, $01 ; ......XX...... -.byte $20, $02 ; .....X..X..... -.byte $50, $05 ; ....X.XX.X.... -.byte $50, $05 ; ....X.XX.X.... -.byte $20, $02 ; .....X..X..... -.byte $40, $01 ; ......XX...... - -bomb0A: -.byte $04 ; ..X.... -.byte $04 ; ..X.... -.byte $0E ; .XXX... -.byte $1F ; XXXXX.. -.byte $15 ; X.X.X.. -.byte $11 ; X...X.. - -bomb0U: -.byte $40, $00 ;......X....... -.byte $40, $00 ;......X....... -.byte $60, $01 ;.....XXX...... -.byte $70, $03 ;....XXXXX..... -.byte $50, $02 ;....X.X.X..... -.byte $10, $02 ;....X...X..... - -bomb1A: -.byte $07 ; XXX.... -.byte $0C ; ..XX... -.byte $3E ; .XXXXX. -.byte $0C ; ..XX... -.byte $07 ; XXX.... - -bomb1U: -.byte $70, $00 ; ....XXX....... -.byte $40, $01 ; ......XX...... -.byte $60, $07 ; .....XXXXX.... -.byte $40, $01 ; ......XX...... -.byte $70, $00 ; ....XXX....... - -shipA: -.byte $7C, $7F, $03 ; ..XXXXXXXXXXXXXX..... -.byte $78, $03, $00 ; ...XXXXXX............ -.byte $70, $1F, $00 ; ....XXXXXXXX......... -.byte $60, $7F, $0F ; .....XXXXXXXXXXXXX... -.byte $60, $7F, $7F ; .....XXXXXXXXXXXXXXXX -.byte $60, $63, $07 ; .....XXXX...XXXXX.... -.byte $60, $31, $00 ; .....XXX...XX........ -.byte $70, $1F, $00 ; ....XXXXXXXX......... -.byte $78, $03, $00 ; ...XXXXXX............ -.byte $7C, $00, $00 ; ..XXXXX.............. -.byte $1E, $00, $00 ; .XXXX................ -.byte $7F, $07, $00 ; XXXXXXXXXX........... - -shipU: -.byte $40, $7F, $3F, $00 ; ......XXXXXXXXXXXXXX..... -.byte $00, $3F, $00, $00 ; .......XXXXXX............ -.byte $00, $7E, $07, $00 ; ........XXXXXXXXX........ -.byte $00, $7C, $7F, $01 ; .........XXXXXXXXXXXXX... -.byte $00, $7C, $7F, $0F ; .........XXXXXXXXXXXXXXXX -.byte $00, $3C, $78, $00 ; .........XXXX....XXXX.... -.byte $00, $1C, $0C, $00 ; .........XXX....XX....... -.byte $00, $7E, $07, $00 ; ........XXXXXXXXX........ -.byte $00, $3F, $00, $00 ; .......XXXXXX............ -.byte $40, $0F, $00, $00 ; ......XXXXX.............. -.byte $60, $03, $00, $00 ; .....XXXX................ -.byte $70, $7F, $00, $00 ; ....XXXXXXXXXX........... diff --git a/src/apple2/terrain.inc b/src/apple2/terrain.inc deleted file mode 100644 index da63645..0000000 --- a/src/apple2/terrain.inc +++ /dev/null @@ -1,402 +0,0 @@ -;----------------------------------------------------------------------------- -; terrain.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "CODE" - -;----------------------------------------------------------------------------- -.proc terrainShow - - zaIndex = tempBlock + 1 - zaWorldBot = tempBlock + 2 - zaWorldTop = tempBlock + 3 - zaSide = tempBlock + 4 - - ldy #WORLD_START ; start row - lda #(WORLD_END - WORLD_START + 1) ; no of rows to clear - ldx backLayer ; inactive (back) layer - jsr drawClearRows ; clean the part where the world must draw - - lda terrainOrigin - lsr - sta zScreenCol - - ldy bufferDraw ; make enemyBuffer relative to screen col 0 - dey ; but back up 1 to the last drawn height - - lda worldBBuffer, y ; prime the drawing with these heights - sta zaWorldBot ; as the last height is where the col 0 - lda worldTBuffer, y ; draw needs to come from - sta zaWorldTop - - iny ; get back to col 0 equivalent index - sty zaIndex ; and save this index - -loop: - lda #0 - sta zaSide - lda worldBBuffer, y - ldy zaWorldBot ; get the last height - sta zaWorldBot ; save new bottom as last - jsr terrainDrawLeftColumn - - inc zaSide - ldy zaIndex - lda worldTBuffer, y - ldy zaWorldTop ; get the last height - sta zaWorldTop ; save new bottom as last - cmp #9 - bcc :+ - jsr terrainDrawLeftColumn - -: - lda #0 - sta zaSide - inc zaIndex - ldy zaIndex - lda worldBBuffer, y - ldy zaWorldBot ; get the last height - sta zaWorldBot ; save new bottom as last - jsr terrainDrawRightColumn - - inc zaSide - ldy zaIndex - lda worldTBuffer, y - ldy zaWorldTop ; get the last height - sta zaWorldTop ; save new bottom as last - cmp #9 - bcc :+ - jsr terrainDrawRightColumn - -: - ldy zaIndex - cpy bufferInsert - beq done - iny - sty zaIndex - inc zScreenCol - bne loop - -done: - clc - rts - -.endproc - -;----------------------------------------------------------------------------- -; y is last height, a is new height -.proc terrainDrawLeftColumn - - zaSide = tempBlock + 4 - zaDiff = tempBlock + 5 - zaDir = tempBlock + 6 ; 2 bytes used - - sty zaDiff - sec - sbc zaDiff ; get the delta (new - old) - tax ; save delta in x - bcs eqdown ; new .ge. old - -up: ; new < old so go up - lda rowL, y - adc zScreenCol - sta writeUpStart + 1 - lda rowH, y - adc zVramH - sta writeUpStart + 2 - lda #%00000011 ; start with a 2 pixel flat area -writeUpStart: - sta PLACEHOLDER - dey ; go 1 row up - inx - beq skup ; if at new height now, skip the "up line" portion -: - lda rowL, y ; draw the "up line" portion now - adc zScreenCol - sta writeUp + 1 - lda rowH, y - adc zVramH - sta writeUp + 2 - lda #%00000100 ; write a single pixel up the rows -writeUp: - sta PLACEHOLDER - dey ; row up - inx - bne :- ; keep going till old .eq. new - -skup: - lda rowL, y ; finish off the transition - adc zScreenCol - sta writeUpEnd + 1 - lda rowH, y - adc zVramH - sta writeUpEnd + 2 - lda #%00001000 ; by writing a pixel to connect to new -writeUpEnd: - sta PLACEHOLDER ; (which will become old, in next column, to draw from) - - lda #$ff - ldx zaSide - sta zaDir, x - - rts - -eqdown: - clc ; carry still set from subtract - beq eq ; if new .eq. old it's a flat line - -down: ; new > old so go down - see up, same but inc|dec is reversed - lda rowL, y - adc zScreenCol - sta writeDownStart + 1 - lda rowH, y - adc zVramH - sta writeDownStart + 2 - lda #%00000011 -writeDownStart: - sta PLACEHOLDER - iny - dex - beq skdn - -: - lda rowL, y - adc zScreenCol - sta writeDown + 1 - lda rowH, y - adc zVramH - sta writeDown + 2 - lda #%00000100 -writeDown: - sta PLACEHOLDER - iny - dex - bne :- - -skdn: - lda rowL, y - adc zScreenCol - sta writeDownEnd + 1 - lda rowH, y - adc zVramH - sta writeDownEnd + 2 - lda #%00001000 -writeDownEnd: - sta PLACEHOLDER - - lda #$01 - ldx zaSide - sta zaDir, x - - rts - -eq: ; flat line from old to new when equal - lda rowL, y - adc zScreenCol - sta writeFlat + 1 - lda rowH, y - adc zVramH - sta writeFlat + 2 - lda #%00001111 -writeFlat: ; 4 pixels in a line - sta PLACEHOLDER - - lda #$00 - ldx zaSide - sta zaDir, x - - rts - -.endproc - -;----------------------------------------------------------------------------- -; y is last height, a is new height -.proc terrainDrawRightColumn - - zaSide = tempBlock + 4 - zaDiff = tempBlock + 5 - zaDir = tempBlock + 6 ; 2 bytes used - zaSaveX = tempBlock + 8 - - sty zaDiff - sec - sbc zaDiff ; get the delta (new - old) - tax ; save delta in x - bcc up - jmp eqdown ; new .ge. old - -up: ; new < old so go up - lda rowL, y - adc zScreenCol - sta writeUpStart + 1 - sta writeUpStart + 4 - lda rowH, y - adc zVramH - sta writeUpStart + 2 - sta writeUpStart + 5 - lda #%00010000 ; start with a 2 pixel flat area -writeUpStart: - ora PLACEHOLDER - sta PLACEHOLDER - dey ; go 1 row up - inx - beq skup ; if at new height now, skip the "up line" portion - - stx zaSaveX - ldx zaSide - lda zaDir, x - ldx zaSaveX - cmp #1 - bne fastUp - clc -: - lda rowL, y ; draw the "up line" portion now - adc zScreenCol - sta writeUp + 1 - sta writeUp + 4 - lda rowH, y - adc zVramH - sta writeUp + 2 - sta writeUp + 5 - lda #%00100000 ; write a single pixel up the rows -writeUp: - ora PLACEHOLDER - sta PLACEHOLDER - dey ; row up - inx - bne :- ; keep going till old .eq. new - beq skup - -fastUp: - clc -: - lda rowL, y ; draw the "up line" portion now - adc zScreenCol - sta writeUpFast + 1 - lda rowH, y - adc zVramH - sta writeUpFast + 2 - lda #%00100000 ; write a single pixel up the rows -writeUpFast: - sta PLACEHOLDER - dey ; row up - inx - bne :- ; keep going till old .eq. new - -skup: - lda rowL, y ; finish off the transition - adc zScreenCol - sta writeUpEnd + 1 - sta writeUpEnd + 4 - lda rowH, y - adc zVramH - sta writeUpEnd + 2 - sta writeUpEnd + 5 - lda #%01000000 ; by writing a pixel to connect to new -writeUpEnd: - ora PLACEHOLDER - sta PLACEHOLDER ; (which will become old, in next column, to draw from) - - rts - -eqdown: - clc ; carry still set from subtract - bne down ; if new .eq. old it's a flat line - jmp eq - -down: ; new > old so go down - see up, same but inc|dec is reversed - lda rowL, y - adc zScreenCol - sta writeDownStart + 1 - sta writeDownStart + 4 - lda rowH, y - adc zVramH - sta writeDownStart + 2 - sta writeDownStart + 5 - lda #%00010000 -writeDownStart: - ora PLACEHOLDER - sta PLACEHOLDER - iny - dex - beq skdn - - stx zaSaveX - ldx zaSide - lda zaDir, x - ldx zaSaveX - cmp #$ff - bne fastDown - clc - -: - lda rowL, y - adc zScreenCol - sta writeDown + 1 - sta writeDown + 4 - lda rowH, y - adc zVramH - sta writeDown + 2 - sta writeDown + 5 - lda #%00100000 -writeDown: - ora PLACEHOLDER - sta PLACEHOLDER - iny - dex - bne :- - beq skdn - -fastDown: - clc -: - lda rowL, y - adc zScreenCol - sta writeDownFast + 1 - lda rowH, y - adc zVramH - sta writeDownFast + 2 - lda #%00100000 -writeDownFast: - sta PLACEHOLDER - iny - dex - bne :- - -skdn: - lda rowL, y - adc zScreenCol - sta writeDownEnd + 1 - sta writeDownEnd + 4 - lda rowH, y - adc zVramH - sta writeDownEnd + 2 - sta writeDownEnd + 5 - lda #%01000000 -writeDownEnd: - ora PLACEHOLDER - sta PLACEHOLDER - - rts - -eq: ; flat line from old to new when equal - lda rowL, y - adc zScreenCol - sta writeFlat + 1 - sta writeFlat + 4 - lda rowH, y - adc zVramH - sta writeFlat + 2 - sta writeFlat + 5 - lda #%01110000 -writeFlat: ; 4 pixels in a line - ora PLACEHOLDER - sta PLACEHOLDER - - rts - -.endproc diff --git a/src/apple2/text.inc b/src/apple2/text.inc deleted file mode 100644 index ba692aa..0000000 --- a/src/apple2/text.inc +++ /dev/null @@ -1,389 +0,0 @@ -;----------------------------------------------------------------------------- -; text.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "RODATA" - -.feature string_escapes - -; In game text -textTopLine: .asciiz "Stage . Player - - Score 0" -textDanger: .asciiz "Danger" -textShips: .asciiz "Ships" -textTrainer: .asciiz "Trainer" -textPlayer: .asciiz "P L A Y E R " - -; title screen -textHighScores: .asciiz "High Scores" -textPhilip: .asciiz " Written by - Philip Mitchell - " -textCopyright: .asciiz "** Copyright \"Beam Software\" **" -textApple2: .asciiz " Apple II version by " -textStefan: .asciiz " Stefan Wessels, Dec 2019 " -textSupport: .asciiz " Lots of great Apple II " -textOliver: .asciiz " Support from Oliver Schmidt " -textSource: .asciiz " Source on GitHub: " -textGitHub: .asciiz " StewBC/penetrator-apple2 " -textGameOver: .asciiz "********** GAME OVER **********" - -; main menu -textInstructions: .asciiz "INSTRUCTIONS" -textPress: .asciiz "PRESS" -textUnderline: .asciiz "-----" -textOneTwo: .asciiz "\"1\" OR \"2\" FOR NUMBER OF PLAYERS" -textTrain: .asciiz "\"T\" FOR TRAINING CONTROL CENTER" -textEdit: .asciiz "\"E\" FOR THE LANDSCAPE EDITOR" -textLoad: .asciiz "\"L\" TO LOAD ANOTHER LANDSCAPE" -textSirens: .asciiz "\"S\" SET AUDIO: " -textQuit: .asciiz "\"Q\" QUIT" - -; main menu audio options -textAudio1: .asciiz "ENGINE, SFX" -textAudio2: .asciiz "SFX " -textAudio3: .asciiz "NONE " - -; training mode menu -textTrainingMode: .asciiz "TRAINING MODE" -textPressStage: .asciiz "PRESS NUMBER OF DESIRED STAGE" -textOneToFour: .asciiz "(1 - 4) TO START." -textBackup: .asciiz "ESC to back up or exit mode" - -; edit mode screen -textEditStage: .asciiz "STAGE" -textEditHelp: .byte "PRESS 'C' FOR ",$86," COMMAND SUMMARY", $00 -textEditBrush: .asciiz "BRUSH: " -textEditTerrain: .asciiz "TERRAIN" -textEditEnemies: .asciiz "ENEMIES" -textEditDnArrow: .byte $85, $00 - -; edit help screen -textEdtHlp01: .asciiz "LANDSCAPE EDITOR COMMANDS" -textEdtHlp02: .asciiz "--------- ------ --------" -textEdtHlp03: .asciiz "JOYSTICK- MOVE THE CURSOR" -textEdtHlp04: .asciiz "KBD-B - TOGGLE BETWEEN TERRAIN" -textEdtHlp05: .asciiz " AND ENEMY BRUSHES" -textEdtHlp06: .asciiz "SPACE - CONTINIOUS MOVEMENT" -textEdtHlp07: .asciiz "" -textEdtHlp08: .asciiz "JOYBTN1 - SET TERRAIN TOP" -textEdtHlp09: .asciiz " OR PLACE A MISSILE" -textEdtHlp10: .asciiz "JOYBTN0 - SET TERRAIN BOTTOM OR" -textEdtHlp11: .asciiz " PLACE A RADAR" -textEdtHlp12: .asciiz "1 - 5 - SKIP TO STAGE" -textEdtHlp13: .asciiz "S - SAVE THIS WORLD" -textEdtHlp14: .asciiz "L - LOAD A WORLD" -textEdtHlp15: .asciiz "ERASE ENEMIES USING A/B" -textEdtHlp16: .asciiz "WITH THE ENEMIES BRUSH" -textEdtHlp17: .asciiz "ESC - END THE EDIT SESSION" - -; win screen -textBonus: .asciiz "BONUS" -textPoints: .asciiz "POINTS" -text1000: .asciiz "1000" -textWow: .asciiz "WOW" -textHome: .asciiz "HOME" - -; high score name entry -textCongrats: .asciiz "***** CONGRATULATIONS *****" -textHSPlayer: .asciiz "PLAYER -- " -textTop5: .asciiz "Your score is in the top 5" -textTypeName: .asciiz "Please type in your name" - -; file name entry -textFileLoad: .asciiz "FILE LOAD" -textFileSave: .asciiz "FILE SAVE" -textFileLines: .asciiz "---------" -textFileInfoL: .asciiz "Load" -textFileInfoS: .asciiz "Save" -textFileInfo: .asciiz "world data" -textFileEnter: .asciiz "Please enter a file name" -textFileSuccess: .asciiz "SUCCESS." -textFileThe: .asciiz "The" -textFileFailed: .asciiz "Failed. Error Code" - -hihgScoreFileName:.asciiz "PENSCORES" - -;----------------------------------------------------------------------------- -.segment "CODE" - -;----------------------------------------------------------------------------- -; Use the print macro to call this code -; Writes a null-terminated string to the back buffer -; temp1/2 Ptr to the string -; textX - the string draw X position (in col coords) -; textY - the string draw Y position -.proc textOut - - textX = tempBlock + 10 - textY = tempBlock + 11 - xPos = tempBlock + 12 - yPos = tempBlock + 13 - - zaStrL = tempBlock + 1 ; parameter - string lo - zaStrH = tempBlock + 2 ; parameter - string hi - zaFontL = tempBlock + 4 ; internal - point at the character memory Lo - zaFontH = tempBlock + 5 ; internal - point at the character memory Hi - zaFontOffset = tempBlock + 6 ; 0-15 - index from zaFont - -loop: - ldy #0 - lda (zaStrL), y ; get the character in the string - bne :+ ; if non-null process it - rts ; exit on 0 terminator - -: - jsr setFont - lda textY ; get the screen Y for text - sta yPos ; init the row working buffer - -plotLoop: - ldy yPos ; at the working row offset - lda rowL, y ; get the memory address - adc textX ; add in column (x pos of text) - sta write + 1 ; point lo at memory - lda rowH, y - adc zVramH - sta write + 2 - - ldy zaFontOffset ; get the offset into the font - lda (zaFontL), y ; get the actual left character byte -write: - sta PLACEHOLDER ; plot the left hand side - cpy #7 - bcs nextChar ; 0-7 then done with this character (bottom always blank) - inc zaFontOffset ; move a byte for last row plotted - inc yPos ; move down a row on screen - - bne plotLoop ; always take this branch - -nextChar: - inc textX ; character column - inc zaStrL ; next character in string - bne loop - inc zaStrH - bne loop ; always branch back - -.endproc - -;----------------------------------------------------------------------------- -; Like textOut but uses drawPoltXY to plot each pixel in the text -; so you can write big strings using width and height. -; a setting of width and height both 1 results in a character that's -; 32x32 on-screen -.proc textBigPrint - - zaStrL = tempBlock + 1 ; parameter - string lo - zaStrH = tempBlock + 2 ; parameter - string hi - zaBitCnt = tempBlock + 3 ; internal - how many bits to process for a byte to write - zaFontL = tempBlock + 4 ; internal - point at the character memory Lo - zaFontH = tempBlock + 5 ; internal - point at the character memory Hi - zaFontOffset = tempBlock + 6 ; internal - 0-15 - index from zaFont - - width = tempBlock + 14 ; shared with drawPlotXY - height = tempBlock + 15 - - textX = tempBlock + 12 - textY = tempBlock + 13 - xPos = tempBlock + 7 - yPos = tempBlock + 8 - -loop: - ldy #0 - lda (zaStrL), y ; get the character in the string - bne :+ ; if non-null process it - rts ; exit on 0 terminator - -: - jsr setFont - - lda textY ; get the screen Y for text - sta yPos - - inc zaFontOffset - -plotLoop: - - lda textX - sta xPos - - ldx #6 ; each font character byte uses 7 pixels - stx zaBitCnt - - ldy zaFontOffset ; get the offset into the font - lda (zaFontL), y ; get the actual left character byte - lsr - jsr drawBits - - inc zaFontOffset ; go to the next line - ldy zaFontOffset - - cpy #7 ; characters are 8 bytes long, care about 7 - bcs nextChar ; if 16 then done with this character - lda yPos ; adjust the "plot" down a line - clc - adc height - sta yPos - - bne plotLoop ; always take this branch - -nextChar: - lda width ; move along in X to the next character - asl ; 6x the width + 2 - asl - adc width - adc width - adc #2 - adc textX ; add to current "plot" position - sta textX - inc zaStrL ; next character in string - bne loop - inc zaStrH - bne loop ; always branch back - -drawBits: - lsr ; shift a bit into carry - pha ; save the shifted byte - bcc :+ ; if carry is set, need to plot a pixel - clc - ldx xPos ; get the x and y of where to plot - ldy yPos - jsr drawPlotXY ; draw the pixel -: - lda xPos ; move along one "pixel" - clc - adc width - sta xPos - pla ; restore the shifted character - dec zaBitCnt ; see if all bytes were handled - ldx zaBitCnt - bne drawBits - rts - -.endproc - -;----------------------------------------------------------------------------- -; Point zaFont(H|L) at the character definition for the character in the accumulator -; y register must be 0 when calling this routine -.proc setFont - - zaFontL = tempBlock + 4 ; internal - point at the character memory Lo - zaFontH = tempBlock + 5 ; internal - point at the character memory Hi - zaFontOffset = tempBlock + 6 ; internal - 0-15 - index from zaFont - - sty zaFontOffset ; start at 0th byte in font - sty zaFontH - sty zaFontL - - sec ; subtract 32 as font starts at char 32 (space) - sbc #$20 - asl ; mult 8 as that's how many bytes per char - rol zaFontH - asl - rol zaFontH - asl - rol zaFontH - adc #font - adc zaFontH - sta zaFontH ; now font points at the character data - - rts - -.endproc - -;----------------------------------------------------------------------------- -; Turns a BCD number into a text string at textNumber. -; zaStr is a ptr to the number in BCD -; y reg is the number of bytes to convert -; x reg <> 0 means print at least one digit, even if 0 -.proc textBCDtoSZ - - zaStrL = tempBlock + 1 - zaStrH = tempBlock + 2 - zaForce = tempBlock + 3 - - stx zaForce - dey ; zero based so -1 - ldx #0 - -leading: ; skip leading 0's with spaces - lda #' ' ; prep buffer with two spaces - sta textNumber, x ; if the byte to output is $00 - sta textNumber + 1, x ; so leading 0's are skipped - lda (zaStrL), y ; get the high byte - bit Bit8765Mask ; check 1st digit - bne loop1 ; if not zero - start printing - inx ; skip the zero by accepting the space - and #$0f ; check the 2nd digit - beq :+ ; go skip if zero - jsr digit ; print the digit - bne loop2 ; and join the main print loop -: - inx ; skip the next char in the output string - dey ; go to next byte in the BCD number - bpl leading ; keep going till all bytes done - ldy zaForce ; nothing printed - see if at least 1 digit - beq done ; needs to be printed and if no - then done - dex ; step back one digit in the string - lda #'0' ; get a zero - sta textNumber, x ; put it in the string - inx - bne done ; JuMP to done - -loop: ; main loop once a digit is found - lda (zaStrL), y ; get the 2 decimal digits -loop1: - jsr both ; print them both starting with left -loop2: - dey ; next score part - bpl loop ; keep going while there are score parts - -done: - lda #0 ; load a null-terminator - sta textNumber, x ; store it in the output string - rts - -both: - pha ; save the 2 digits - lsr ; shift right down - lsr - lsr - lsr - jsr digit ; go print it - pla ; restore both - and #$0f ; mask off the right leaving left -digit: ; print the digit - ora #$30 ; add "0" to the decimal - sta textNumber, x ; put it in the string - inx ; advance the string pointer - rts - -.endproc - -;----------------------------------------------------------------------------- -; Prints the accumulator to the szHez text as 2 hex bytes -.proc toHex - - ldx #0 ; offset into the szHex buffer - pha ; save a for lower 4 bits - lsr ; move upper 4 bits to lo - lsr - lsr - lsr - jsr :+ ; process upper 4 bits - pla ; restore a to process lower 4 bits -: - and #$0f ; mask to only the 4 bits now in lo - cmp #10 ; see if it's > 9 - bcc :+ - adc #6 ; move from 10+ to a+ - : - adc #$30 ; and move to '0' and beyond - sta szHex, x ; save this in the buffer - inx ; go to next buffer location - rts ; and return to self or caller - -.endproc \ No newline at end of file diff --git a/src/apple2/trndata.inc b/src/apple2/trndata.inc deleted file mode 100644 index 2c3cfe0..0000000 --- a/src/apple2/trndata.inc +++ /dev/null @@ -1,2353 +0,0 @@ -;----------------------------------------------------------------------------- -; trndata.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "RODATA" - -;----------------------------------------------------------------------------- -; terrain at bottom, top & type -; Type represents this: -; 01 - Missile -; 02 - Rocket -; 40 - End of stage -worldDataStart: -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AB, $08, $00 -.byte $AB, $08, $00 -.byte $A7, $08, $00 -.byte $9F, $08, $00 -.byte $97, $08, $00 -.byte $8F, $08, $00 -.byte $83, $08, $00 -.byte $77, $08, $00 -.byte $6F, $08, $00 -.byte $67, $08, $00 -.byte $5B, $08, $00 -.byte $47, $08, $00 -.byte $3F, $08, $00 -.byte $2F, $08, $00 -.byte $33, $08, $00 -.byte $33, $08, $00 -.byte $3B, $08, $00 -.byte $3F, $08, $00 -.byte $4B, $08, $00 -.byte $57, $08, $00 -.byte $57, $08, $00 -.byte $63, $08, $00 -.byte $67, $08, $00 -.byte $73, $08, $00 -.byte $83, $08, $00 -.byte $93, $08, $00 -.byte $97, $08, $00 -.byte $97, $08, $01 -.byte $97, $08, $00 -.byte $97, $08, $00 -.byte $9B, $08, $00 -.byte $9B, $08, $00 -.byte $9F, $08, $00 -.byte $A7, $08, $00 -.byte $A7, $08, $00 -.byte $A7, $08, $00 -.byte $A7, $08, $00 -.byte $A7, $08, $00 -.byte $AB, $08, $00 -.byte $AB, $08, $02 -.byte $AB, $08, $00 -.byte $AB, $08, $00 -.byte $AB, $08, $00 -.byte $AB, $08, $00 -.byte $AB, $08, $01 -.byte $AB, $08, $00 -.byte $AB, $08, $00 -.byte $AB, $08, $00 -.byte $AB, $08, $00 -.byte $A7, $08, $00 -.byte $A7, $08, $00 -.byte $A7, $08, $00 -.byte $A7, $08, $00 -.byte $A3, $08, $00 -.byte $A3, $08, $01 -.byte $A3, $08, $00 -.byte $A3, $08, $00 -.byte $A3, $08, $00 -.byte $A3, $08, $02 -.byte $A3, $08, $00 -.byte $A3, $08, $00 -.byte $A3, $08, $00 -.byte $A3, $08, $00 -.byte $A3, $08, $01 -.byte $A3, $08, $00 -.byte $A3, $08, $00 -.byte $A3, $08, $00 -.byte $97, $08, $00 -.byte $97, $08, $01 -.byte $97, $08, $00 -.byte $97, $08, $00 -.byte $93, $08, $00 -.byte $97, $08, $00 -.byte $97, $08, $00 -.byte $97, $08, $00 -.byte $9B, $08, $00 -.byte $9B, $08, $00 -.byte $A3, $08, $00 -.byte $A3, $08, $01 -.byte $A3, $08, $00 -.byte $A3, $08, $00 -.byte $B3, $08, $00 -.byte $B3, $08, $02 -.byte $B3, $08, $00 -.byte $B3, $08, $00 -.byte $B3, $08, $00 -.byte $B3, $08, $00 -.byte $A3, $08, $00 -.byte $97, $08, $00 -.byte $8B, $08, $00 -.byte $7B, $08, $00 -.byte $7B, $08, $01 -.byte $7B, $08, $00 -.byte $7B, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $01 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $93, $08, $00 -.byte $8F, $08, $00 -.byte $8F, $08, $00 -.byte $97, $08, $00 -.byte $97, $08, $00 -.byte $97, $08, $00 -.byte $97, $08, $00 -.byte $93, $08, $00 -.byte $8F, $08, $00 -.byte $87, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $02 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $8B, $08, $00 -.byte $8B, $08, $01 -.byte $8B, $08, $00 -.byte $8B, $08, $00 -.byte $8B, $08, $00 -.byte $93, $08, $00 -.byte $93, $08, $02 -.byte $93, $08, $00 -.byte $93, $08, $00 -.byte $93, $08, $00 -.byte $9B, $08, $00 -.byte $9B, $08, $02 -.byte $9B, $08, $00 -.byte $9B, $08, $00 -.byte $9B, $08, $00 -.byte $9B, $08, $00 -.byte $9B, $08, $01 -.byte $9B, $08, $00 -.byte $9B, $08, $00 -.byte $9B, $08, $00 -.byte $9B, $08, $00 -.byte $97, $08, $00 -.byte $87, $08, $00 -.byte $87, $08, $01 -.byte $87, $08, $00 -.byte $87, $08, $00 -.byte $6F, $08, $00 -.byte $53, $08, $00 -.byte $53, $08, $01 -.byte $53, $08, $00 -.byte $53, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $02 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AB, $08, $00 -.byte $9F, $08, $00 -.byte $93, $08, $00 -.byte $93, $08, $01 -.byte $93, $08, $00 -.byte $93, $08, $00 -.byte $93, $08, $00 -.byte $97, $08, $00 -.byte $8B, $08, $00 -.byte $8B, $08, $01 -.byte $8B, $08, $00 -.byte $8B, $08, $00 -.byte $8B, $08, $00 -.byte $83, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $02 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $77, $08, $00 -.byte $77, $08, $02 -.byte $77, $08, $00 -.byte $77, $08, $00 -.byte $77, $08, $00 -.byte $77, $08, $00 -.byte $6F, $08, $00 -.byte $6F, $08, $01 -.byte $6F, $08, $00 -.byte $6F, $08, $00 -.byte $6F, $08, $00 -.byte $6F, $08, $01 -.byte $6F, $08, $00 -.byte $6F, $08, $00 -.byte $6F, $08, $00 -.byte $6F, $08, $01 -.byte $6F, $08, $00 -.byte $6F, $08, $00 -.byte $6F, $08, $00 -.byte $6F, $08, $01 -.byte $6F, $08, $00 -.byte $6F, $08, $00 -.byte $6F, $08, $00 -.byte $73, $08, $00 -.byte $77, $08, $00 -.byte $7B, $08, $00 -.byte $7F, $08, $00 -.byte $7B, $08, $00 -.byte $7F, $08, $00 -.byte $83, $08, $00 -.byte $83, $08, $02 -.byte $83, $08, $00 -.byte $83, $08, $00 -.byte $83, $08, $00 -.byte $83, $08, $00 -.byte $83, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $01 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $7B, $08, $00 -.byte $7B, $08, $00 -.byte $77, $08, $00 -.byte $73, $08, $00 -.byte $73, $08, $01 -.byte $73, $08, $00 -.byte $73, $08, $00 -.byte $6B, $08, $00 -.byte $6B, $08, $00 -.byte $67, $08, $00 -.byte $67, $08, $00 -.byte $5F, $08, $00 -.byte $5F, $08, $00 -.byte $5F, $08, $00 -.byte $67, $08, $00 -.byte $67, $08, $00 -.byte $6F, $08, $00 -.byte $6F, $08, $00 -.byte $6F, $08, $00 -.byte $6F, $08, $00 -.byte $6F, $08, $00 -.byte $77, $08, $00 -.byte $77, $08, $02 -.byte $77, $08, $00 -.byte $77, $08, $00 -.byte $77, $08, $00 -.byte $7B, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $01 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $8F, $08, $00 -.byte $8F, $08, $00 -.byte $87, $08, $00 -.byte $87, $08, $01 -.byte $87, $08, $00 -.byte $87, $08, $00 -.byte $93, $08, $00 -.byte $A3, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $B3, $08, $00 -.byte $B3, $08, $02 -.byte $B3, $08, $00 -.byte $B3, $08, $00 -.byte $B3, $08, $00 -.byte $B3, $08, $00 -.byte $B3, $08, $00 -.byte $B3, $08, $00 -.byte $B3, $08, $00 -.byte $B3, $08, $00 -.byte $B3, $08, $01 -.byte $B3, $08, $00 -.byte $B3, $08, $00 -.byte $B3, $08, $00 -.byte $A3, $08, $00 -.byte $A3, $08, $00 -.byte $A3, $08, $00 -.byte $93, $08, $00 -.byte $93, $08, $00 -.byte $83, $08, $00 -.byte $83, $08, $02 -.byte $83, $08, $00 -.byte $83, $08, $00 -.byte $83, $08, $00 -.byte $87, $08, $00 -.byte $87, $08, $01 -.byte $87, $08, $00 -.byte $87, $08, $00 -.byte $87, $08, $00 -.byte $8B, $08, $00 -.byte $8B, $08, $00 -.byte $8B, $08, $01 -.byte $8B, $08, $00 -.byte $8B, $08, $00 -.byte $8B, $08, $00 -.byte $87, $08, $00 -.byte $7F, $08, $00 -.byte $7B, $08, $00 -.byte $77, $08, $00 -.byte $77, $08, $00 -.byte $6F, $08, $00 -.byte $63, $08, $00 -.byte $5F, $08, $00 -.byte $63, $08, $00 -.byte $63, $08, $00 -.byte $67, $08, $00 -.byte $6B, $08, $00 -.byte $6F, $08, $00 -.byte $6B, $08, $00 -.byte $67, $08, $00 -.byte $63, $08, $00 -.byte $5F, $08, $00 -.byte $5F, $08, $00 -.byte $5F, $08, $01 -.byte $5F, $08, $00 -.byte $5F, $08, $00 -.byte $5F, $08, $00 -.byte $5F, $08, $00 -.byte $5F, $08, $00 -.byte $5F, $08, $00 -.byte $57, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $01 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $02 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $4F, $08, $00 -.byte $4F, $08, $00 -.byte $53, $08, $00 -.byte $53, $08, $00 -.byte $57, $08, $00 -.byte $4F, $08, $00 -.byte $4F, $08, $00 -.byte $4B, $08, $00 -.byte $47, $08, $00 -.byte $43, $08, $00 -.byte $47, $08, $00 -.byte $4B, $08, $00 -.byte $47, $08, $00 -.byte $43, $08, $00 -.byte $3F, $08, $00 -.byte $33, $08, $00 -.byte $2F, $08, $00 -.byte $2F, $08, $00 -.byte $2B, $08, $00 -.byte $23, $08, $00 -.byte $1B, $08, $00 -.byte $1B, $08, $00 -.byte $1B, $08, $00 -.byte $1B, $08, $00 -.byte $1F, $08, $00 -.byte $1F, $08, $00 -.byte $1F, $08, $01 -.byte $1F, $08, $00 -.byte $1F, $08, $00 -.byte $1F, $08, $00 -.byte $1F, $08, $02 -.byte $1F, $08, $00 -.byte $1F, $08, $00 -.byte $1F, $08, $00 -.byte $1F, $08, $00 -.byte $23, $08, $00 -.byte $27, $08, $00 -.byte $2F, $08, $00 -.byte $33, $08, $00 -.byte $37, $08, $00 -.byte $3B, $08, $00 -.byte $3F, $08, $00 -.byte $43, $08, $00 -.byte $47, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $01 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $4F, $08, $00 -.byte $53, $08, $00 -.byte $57, $08, $00 -.byte $57, $08, $00 -.byte $57, $08, $00 -.byte $5B, $08, $00 -.byte $5F, $08, $00 -.byte $63, $08, $00 -.byte $67, $08, $00 -.byte $63, $08, $00 -.byte $5F, $08, $00 -.byte $5F, $08, $00 -.byte $5B, $08, $00 -.byte $5B, $08, $00 -.byte $5F, $08, $00 -.byte $63, $08, $00 -.byte $67, $08, $00 -.byte $63, $08, $00 -.byte $67, $08, $00 -.byte $6B, $08, $00 -.byte $73, $08, $00 -.byte $73, $08, $02 -.byte $73, $08, $00 -.byte $73, $08, $00 -.byte $73, $08, $00 -.byte $77, $08, $00 -.byte $7B, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $83, $08, $00 -.byte $87, $08, $00 -.byte $87, $08, $00 -.byte $83, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $7B, $08, $00 -.byte $77, $08, $00 -.byte $73, $08, $00 -.byte $73, $08, $00 -.byte $77, $08, $00 -.byte $77, $08, $00 -.byte $7B, $08, $00 -.byte $7B, $08, $00 -.byte $6B, $08, $00 -.byte $6B, $08, $01 -.byte $6B, $08, $00 -.byte $6B, $08, $00 -.byte $63, $08, $00 -.byte $5F, $08, $00 -.byte $5B, $08, $00 -.byte $57, $08, $00 -.byte $5B, $08, $00 -.byte $5F, $08, $00 -.byte $5F, $08, $00 -.byte $5B, $08, $00 -.byte $5B, $08, $02 -.byte $5B, $08, $00 -.byte $5B, $08, $00 -.byte $5B, $08, $00 -.byte $5B, $08, $00 -.byte $5B, $08, $00 -.byte $57, $08, $00 -.byte $53, $08, $00 -.byte $4F, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $02 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $47, $08, $00 -.byte $43, $08, $00 -.byte $3F, $08, $00 -.byte $3F, $08, $02 -.byte $3F, $08, $00 -.byte $3F, $08, $40 -.byte $3F, $08, $00 -.byte $43, $08, $00 -.byte $47, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $02 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $4F, $08, $00 -.byte $53, $08, $00 -.byte $57, $08, $00 -.byte $57, $08, $02 -.byte $57, $08, $00 -.byte $57, $08, $00 -.byte $57, $08, $00 -.byte $5B, $08, $00 -.byte $5F, $08, $00 -.byte $5F, $08, $02 -.byte $5F, $08, $00 -.byte $5F, $08, $00 -.byte $5F, $08, $00 -.byte $5F, $08, $00 -.byte $5B, $08, $00 -.byte $5B, $08, $00 -.byte $53, $08, $00 -.byte $53, $08, $01 -.byte $53, $08, $00 -.byte $53, $08, $00 -.byte $4F, $08, $00 -.byte $4B, $08, $00 -.byte $4B, $08, $01 -.byte $4B, $08, $00 -.byte $4B, $08, $00 -.byte $43, $08, $00 -.byte $43, $08, $00 -.byte $43, $08, $00 -.byte $43, $08, $00 -.byte $33, $08, $00 -.byte $33, $08, $01 -.byte $33, $08, $00 -.byte $33, $08, $00 -.byte $33, $08, $00 -.byte $47, $08, $00 -.byte $53, $08, $00 -.byte $57, $08, $00 -.byte $63, $08, $00 -.byte $67, $08, $00 -.byte $73, $08, $00 -.byte $77, $08, $00 -.byte $8B, $08, $00 -.byte $93, $0C, $00 -.byte $9F, $14, $00 -.byte $9F, $18, $01 -.byte $9F, $1C, $00 -.byte $9F, $1C, $00 -.byte $9F, $1C, $02 -.byte $9F, $20, $00 -.byte $9F, $24, $00 -.byte $9F, $24, $00 -.byte $A7, $28, $00 -.byte $A7, $28, $02 -.byte $A7, $28, $00 -.byte $A7, $2C, $00 -.byte $A7, $30, $00 -.byte $AB, $30, $00 -.byte $AB, $34, $00 -.byte $A7, $34, $00 -.byte $93, $38, $00 -.byte $93, $3C, $01 -.byte $93, $3C, $00 -.byte $93, $3C, $00 -.byte $8F, $38, $00 -.byte $8B, $34, $00 -.byte $8B, $34, $02 -.byte $8B, $30, $00 -.byte $8B, $34, $00 -.byte $8B, $30, $00 -.byte $97, $2C, $00 -.byte $97, $28, $02 -.byte $97, $2C, $00 -.byte $97, $28, $00 -.byte $97, $24, $00 -.byte $9B, $20, $00 -.byte $97, $24, $00 -.byte $8F, $28, $00 -.byte $8F, $2C, $01 -.byte $8F, $2C, $00 -.byte $8F, $28, $00 -.byte $7F, $24, $00 -.byte $7F, $20, $01 -.byte $7F, $24, $00 -.byte $7F, $24, $00 -.byte $83, $20, $00 -.byte $83, $1C, $00 -.byte $87, $18, $00 -.byte $93, $1C, $00 -.byte $93, $20, $00 -.byte $9B, $24, $00 -.byte $9B, $20, $00 -.byte $93, $24, $00 -.byte $93, $18, $01 -.byte $93, $18, $00 -.byte $93, $18, $00 -.byte $8F, $1C, $00 -.byte $8F, $20, $01 -.byte $8F, $24, $00 -.byte $8F, $28, $00 -.byte $93, $2C, $00 -.byte $93, $30, $01 -.byte $93, $2C, $00 -.byte $93, $28, $00 -.byte $9F, $2C, $00 -.byte $A3, $38, $00 -.byte $A3, $3C, $00 -.byte $9F, $40, $00 -.byte $9F, $3C, $00 -.byte $9B, $38, $00 -.byte $9B, $34, $00 -.byte $93, $38, $00 -.byte $93, $38, $01 -.byte $93, $38, $00 -.byte $93, $34, $00 -.byte $97, $30, $00 -.byte $97, $2C, $00 -.byte $9B, $2C, $00 -.byte $9B, $2C, $00 -.byte $9F, $28, $00 -.byte $A3, $24, $00 -.byte $A3, $20, $02 -.byte $A3, $1C, $00 -.byte $A3, $18, $00 -.byte $A3, $14, $00 -.byte $A7, $18, $00 -.byte $AB, $1C, $00 -.byte $AB, $20, $01 -.byte $AB, $24, $00 -.byte $AB, $2C, $00 -.byte $A7, $28, $00 -.byte $A7, $28, $00 -.byte $A3, $28, $00 -.byte $A3, $28, $00 -.byte $9F, $24, $00 -.byte $97, $20, $00 -.byte $8F, $1C, $00 -.byte $8F, $1C, $02 -.byte $8F, $20, $00 -.byte $8F, $20, $00 -.byte $8F, $24, $00 -.byte $93, $24, $00 -.byte $93, $20, $02 -.byte $93, $20, $00 -.byte $93, $24, $00 -.byte $93, $20, $00 -.byte $A3, $20, $00 -.byte $A7, $20, $00 -.byte $A7, $24, $00 -.byte $AB, $28, $00 -.byte $AB, $2C, $00 -.byte $AF, $30, $00 -.byte $B3, $34, $00 -.byte $B3, $38, $02 -.byte $B3, $3C, $00 -.byte $B3, $3C, $00 -.byte $B3, $4C, $00 -.byte $AF, $4C, $00 -.byte $AF, $4C, $00 -.byte $AF, $48, $00 -.byte $AB, $48, $00 -.byte $AB, $44, $00 -.byte $A7, $44, $00 -.byte $A7, $48, $02 -.byte $A7, $44, $00 -.byte $A7, $40, $00 -.byte $A7, $3C, $00 -.byte $A3, $3C, $00 -.byte $A7, $40, $00 -.byte $A7, $40, $01 -.byte $A7, $3C, $00 -.byte $A7, $38, $00 -.byte $93, $34, $00 -.byte $93, $34, $01 -.byte $93, $34, $00 -.byte $93, $30, $00 -.byte $8F, $2C, $00 -.byte $8F, $28, $00 -.byte $8F, $28, $01 -.byte $8F, $2C, $00 -.byte $8F, $28, $00 -.byte $8B, $24, $00 -.byte $8B, $28, $02 -.byte $8B, $2C, $00 -.byte $8B, $30, $00 -.byte $8B, $30, $00 -.byte $93, $2C, $00 -.byte $93, $28, $01 -.byte $93, $2C, $00 -.byte $93, $30, $00 -.byte $9F, $34, $00 -.byte $A3, $38, $00 -.byte $A3, $3C, $00 -.byte $A7, $38, $00 -.byte $A3, $38, $00 -.byte $A3, $38, $00 -.byte $9F, $34, $00 -.byte $93, $34, $00 -.byte $A3, $30, $00 -.byte $A3, $2C, $00 -.byte $9B, $2C, $00 -.byte $8F, $28, $00 -.byte $8F, $28, $01 -.byte $8F, $28, $00 -.byte $8F, $2C, $00 -.byte $8F, $30, $00 -.byte $9F, $30, $00 -.byte $AB, $2C, $00 -.byte $AB, $30, $00 -.byte $A7, $34, $00 -.byte $A7, $30, $01 -.byte $A7, $2C, $00 -.byte $A7, $2C, $00 -.byte $97, $28, $00 -.byte $97, $24, $02 -.byte $97, $24, $00 -.byte $97, $20, $00 -.byte $97, $24, $00 -.byte $AB, $20, $00 -.byte $AF, $1C, $00 -.byte $AF, $18, $01 -.byte $AF, $14, $00 -.byte $AF, $10, $00 -.byte $AB, $14, $00 -.byte $AB, $14, $00 -.byte $A7, $18, $00 -.byte $A7, $14, $01 -.byte $A7, $10, $00 -.byte $A7, $14, $00 -.byte $77, $10, $00 -.byte $77, $14, $02 -.byte $77, $18, $00 -.byte $77, $1C, $00 -.byte $77, $1C, $00 -.byte $7F, $20, $00 -.byte $7F, $20, $00 -.byte $8F, $20, $00 -.byte $9F, $24, $00 -.byte $9F, $28, $01 -.byte $9F, $28, $00 -.byte $9F, $28, $00 -.byte $A3, $2C, $00 -.byte $A3, $30, $00 -.byte $9F, $30, $00 -.byte $9F, $34, $00 -.byte $9B, $34, $00 -.byte $97, $30, $00 -.byte $9B, $30, $00 -.byte $9B, $34, $01 -.byte $9B, $30, $00 -.byte $9B, $30, $00 -.byte $9F, $2C, $00 -.byte $A3, $28, $00 -.byte $A3, $24, $00 -.byte $9F, $28, $00 -.byte $9F, $28, $00 -.byte $9B, $24, $00 -.byte $9B, $20, $00 -.byte $97, $20, $00 -.byte $97, $24, $02 -.byte $97, $24, $00 -.byte $97, $28, $00 -.byte $97, $24, $00 -.byte $9F, $28, $00 -.byte $A3, $24, $00 -.byte $AB, $24, $00 -.byte $AF, $24, $00 -.byte $AF, $20, $00 -.byte $AB, $1C, $00 -.byte $AB, $18, $00 -.byte $9B, $0C, $00 -.byte $9B, $0C, $01 -.byte $9B, $0C, $00 -.byte $9B, $10, $00 -.byte $9B, $10, $00 -.byte $97, $14, $00 -.byte $8B, $14, $00 -.byte $8B, $18, $01 -.byte $8B, $18, $00 -.byte $8B, $14, $00 -.byte $8F, $14, $00 -.byte $93, $18, $00 -.byte $97, $1C, $00 -.byte $9B, $1C, $00 -.byte $9F, $20, $00 -.byte $A3, $20, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $01 -.byte $B3, $24, $00 -.byte $B3, $2C, $00 -.byte $AF, $30, $00 -.byte $B3, $30, $00 -.byte $B3, $2C, $00 -.byte $AB, $28, $00 -.byte $AB, $24, $02 -.byte $AB, $20, $00 -.byte $AB, $24, $00 -.byte $AB, $28, $00 -.byte $AF, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $28, $01 -.byte $B3, $2C, $00 -.byte $B3, $34, $00 -.byte $AF, $38, $00 -.byte $AB, $3C, $00 -.byte $AB, $40, $00 -.byte $B3, $3C, $00 -.byte $B3, $38, $01 -.byte $B3, $3C, $00 -.byte $B3, $3C, $00 -.byte $AF, $40, $00 -.byte $A7, $44, $00 -.byte $A7, $48, $01 -.byte $A7, $48, $00 -.byte $A7, $54, $00 -.byte $9F, $54, $00 -.byte $9F, $58, $02 -.byte $9F, $5C, $00 -.byte $9F, $5C, $00 -.byte $9F, $5C, $00 -.byte $A3, $58, $00 -.byte $A7, $58, $00 -.byte $AB, $5C, $00 -.byte $AB, $5C, $00 -.byte $A7, $58, $00 -.byte $A7, $54, $00 -.byte $A3, $58, $00 -.byte $9F, $5C, $00 -.byte $9F, $5C, $00 -.byte $A3, $60, $00 -.byte $A7, $64, $00 -.byte $A7, $68, $01 -.byte $A7, $6C, $00 -.byte $A7, $70, $00 -.byte $B3, $70, $00 -.byte $B3, $6C, $01 -.byte $B3, $68, $00 -.byte $B3, $68, $00 -.byte $AF, $68, $00 -.byte $AF, $64, $00 -.byte $AB, $60, $00 -.byte $AB, $60, $00 -.byte $AF, $5C, $00 -.byte $B3, $60, $00 -.byte $B3, $5C, $00 -.byte $AF, $58, $00 -.byte $AB, $54, $00 -.byte $AB, $54, $02 -.byte $AB, $58, $00 -.byte $AB, $58, $00 -.byte $AB, $54, $00 -.byte $A7, $50, $00 -.byte $A7, $50, $00 -.byte $A7, $4C, $00 -.byte $A3, $48, $00 -.byte $9F, $44, $00 -.byte $9F, $44, $01 -.byte $9F, $44, $00 -.byte $9F, $44, $00 -.byte $A3, $40, $00 -.byte $A7, $3C, $00 -.byte $A7, $3C, $00 -.byte $9F, $38, $00 -.byte $9F, $28, $01 -.byte $9F, $28, $00 -.byte $9F, $24, $00 -.byte $A3, $28, $00 -.byte $A7, $2C, $00 -.byte $AB, $30, $00 -.byte $AF, $30, $00 -.byte $B3, $2C, $00 -.byte $AF, $28, $00 -.byte $AF, $28, $01 -.byte $AF, $24, $00 -.byte $AF, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $28, $02 -.byte $B3, $2C, $00 -.byte $B3, $30, $00 -.byte $B3, $34, $00 -.byte $B3, $34, $00 -.byte $AF, $30, $00 -.byte $AF, $30, $00 -.byte $AB, $2C, $00 -.byte $AB, $28, $00 -.byte $AB, $24, $00 -.byte $A3, $28, $00 -.byte $A3, $34, $01 -.byte $A3, $38, $00 -.byte $A3, $38, $00 -.byte $A3, $44, $00 -.byte $A7, $48, $00 -.byte $A7, $4C, $00 -.byte $AB, $48, $00 -.byte $AF, $44, $00 -.byte $AB, $44, $00 -.byte $A7, $48, $00 -.byte $A7, $4C, $00 -.byte $9F, $50, $00 -.byte $9F, $4C, $01 -.byte $9F, $48, $00 -.byte $9F, $44, $00 -.byte $A3, $40, $00 -.byte $A7, $3C, $00 -.byte $B3, $38, $00 -.byte $B3, $38, $00 -.byte $AF, $3C, $00 -.byte $AB, $38, $00 -.byte $B3, $34, $00 -.byte $B3, $30, $01 -.byte $B3, $2C, $00 -.byte $B3, $28, $00 -.byte $AF, $24, $00 -.byte $AF, $28, $00 -.byte $AB, $28, $00 -.byte $AB, $2C, $02 -.byte $AB, $28, $00 -.byte $AB, $2C, $00 -.byte $AB, $30, $00 -.byte $AF, $38, $00 -.byte $B3, $34, $00 -.byte $B3, $30, $01 -.byte $B3, $24, $00 -.byte $B3, $1C, $00 -.byte $AF, $18, $00 -.byte $AB, $1C, $00 -.byte $A7, $20, $00 -.byte $A3, $24, $00 -.byte $A3, $24, $02 -.byte $A3, $20, $00 -.byte $A3, $20, $00 -.byte $A3, $20, $00 -.byte $9B, $24, $00 -.byte $9B, $24, $01 -.byte $9B, $24, $00 -.byte $9B, $24, $00 -.byte $A3, $28, $00 -.byte $A7, $28, $00 -.byte $A3, $2C, $00 -.byte $9F, $30, $00 -.byte $9B, $30, $00 -.byte $93, $34, $00 -.byte $93, $34, $02 -.byte $93, $34, $00 -.byte $93, $38, $00 -.byte $93, $38, $00 -.byte $A3, $3C, $00 -.byte $A7, $40, $00 -.byte $AB, $40, $00 -.byte $B3, $40, $00 -.byte $AF, $44, $00 -.byte $AB, $44, $00 -.byte $AB, $40, $00 -.byte $A7, $40, $00 -.byte $A7, $3C, $00 -.byte $AB, $3C, $00 -.byte $AF, $38, $00 -.byte $AB, $3C, $00 -.byte $9F, $3C, $00 -.byte $9F, $38, $01 -.byte $9F, $34, $00 -.byte $9F, $30, $00 -.byte $93, $30, $00 -.byte $93, $30, $01 -.byte $93, $2C, $00 -.byte $93, $2C, $00 -.byte $9F, $28, $00 -.byte $A7, $24, $00 -.byte $AB, $24, $00 -.byte $A7, $24, $00 -.byte $A3, $28, $00 -.byte $9F, $28, $00 -.byte $93, $2C, $00 -.byte $8F, $30, $00 -.byte $8B, $30, $00 -.byte $87, $30, $00 -.byte $83, $2C, $00 -.byte $73, $2C, $00 -.byte $73, $28, $02 -.byte $73, $28, $00 -.byte $73, $24, $00 -.byte $73, $20, $00 -.byte $77, $20, $00 -.byte $73, $1C, $00 -.byte $73, $20, $02 -.byte $73, $24, $00 -.byte $73, $24, $00 -.byte $73, $28, $00 -.byte $7F, $28, $00 -.byte $83, $2C, $00 -.byte $87, $2C, $00 -.byte $8B, $30, $00 -.byte $8F, $30, $00 -.byte $8B, $34, $00 -.byte $87, $34, $00 -.byte $83, $34, $00 -.byte $7F, $38, $00 -.byte $7F, $3C, $02 -.byte $7F, $40, $00 -.byte $7F, $3C, $00 -.byte $7F, $38, $00 -.byte $77, $38, $00 -.byte $6F, $3C, $00 -.byte $6F, $3C, $01 -.byte $6F, $40, $40 -.byte $6F, $44, $00 -.byte $6B, $40, $00 -.byte $6F, $40, $00 -.byte $73, $3C, $00 -.byte $77, $3C, $00 -.byte $7B, $38, $00 -.byte $7F, $34, $00 -.byte $83, $30, $00 -.byte $87, $2C, $00 -.byte $97, $2C, $00 -.byte $97, $30, $01 -.byte $97, $34, $00 -.byte $97, $38, $00 -.byte $9B, $38, $00 -.byte $9F, $3C, $00 -.byte $9F, $40, $00 -.byte $A3, $44, $00 -.byte $A3, $44, $00 -.byte $A7, $48, $00 -.byte $AB, $48, $00 -.byte $AB, $4C, $01 -.byte $AB, $4C, $00 -.byte $AB, $4C, $00 -.byte $A7, $48, $00 -.byte $A7, $48, $00 -.byte $A3, $48, $00 -.byte $A7, $48, $00 -.byte $A7, $44, $00 -.byte $AB, $40, $00 -.byte $AF, $40, $00 -.byte $B3, $44, $00 -.byte $B3, $44, $01 -.byte $B3, $48, $00 -.byte $B3, $4C, $00 -.byte $B3, $34, $00 -.byte $B3, $34, $01 -.byte $B3, $34, $00 -.byte $B3, $34, $00 -.byte $AF, $34, $00 -.byte $B3, $34, $00 -.byte $AF, $34, $00 -.byte $AB, $34, $00 -.byte $A7, $34, $00 -.byte $A7, $34, $02 -.byte $A7, $34, $00 -.byte $A7, $34, $00 -.byte $A7, $34, $00 -.byte $B3, $34, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $A7, $0C, $00 -.byte $A7, $0C, $01 -.byte $A7, $0C, $00 -.byte $A7, $0C, $00 -.byte $A7, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $01 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $83, $0C, $00 -.byte $83, $0C, $01 -.byte $83, $0C, $00 -.byte $83, $0C, $00 -.byte $83, $0C, $00 -.byte $57, $0C, $00 -.byte $57, $0C, $00 -.byte $57, $0C, $00 -.byte $57, $0C, $00 -.byte $57, $0C, $00 -.byte $57, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $01 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $6B, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $01 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $87, $0C, $00 -.byte $87, $0C, $00 -.byte $87, $0C, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $B3, $60, $00 -.byte $B3, $60, $01 -.byte $B3, $60, $00 -.byte $B3, $60, $00 -.byte $B3, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $B3, $60, $00 -.byte $B3, $60, $01 -.byte $B3, $60, $00 -.byte $B3, $60, $00 -.byte $B3, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $B3, $60, $00 -.byte $B3, $60, $01 -.byte $B3, $60, $00 -.byte $B3, $60, $00 -.byte $B3, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $87, $60, $00 -.byte $B3, $60, $00 -.byte $B3, $60, $01 -.byte $B3, $60, $00 -.byte $B3, $60, $00 -.byte $B3, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $7B, $60, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $01 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $7B, $24, $00 -.byte $7B, $24, $00 -.byte $7B, $24, $00 -.byte $7B, $24, $00 -.byte $7B, $24, $00 -.byte $3F, $24, $00 -.byte $3F, $24, $00 -.byte $3F, $24, $00 -.byte $3F, $24, $00 -.byte $3F, $24, $00 -.byte $3F, $24, $00 -.byte $3F, $24, $00 -.byte $3F, $24, $00 -.byte $3F, $24, $00 -.byte $8B, $24, $00 -.byte $8B, $24, $00 -.byte $8B, $24, $01 -.byte $8B, $24, $00 -.byte $8B, $24, $00 -.byte $8B, $24, $00 -.byte $3F, $24, $00 -.byte $3F, $24, $00 -.byte $3F, $24, $00 -.byte $3F, $24, $00 -.byte $3F, $24, $00 -.byte $3F, $24, $00 -.byte $3F, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $01 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $77, $24, $00 -.byte $77, $24, $00 -.byte $77, $24, $00 -.byte $77, $24, $00 -.byte $77, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $24, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $02 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $88, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $7B, $48, $00 -.byte $7B, $48, $00 -.byte $7B, $10, $00 -.byte $7B, $10, $00 -.byte $7B, $10, $00 -.byte $7B, $10, $00 -.byte $7B, $10, $00 -.byte $7B, $10, $00 -.byte $7B, $10, $00 -.byte $7B, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $01 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $33, $10, $00 -.byte $77, $10, $00 -.byte $77, $10, $00 -.byte $77, $10, $00 -.byte $77, $10, $00 -.byte $77, $10, $00 -.byte $93, $10, $00 -.byte $93, $10, $01 -.byte $93, $10, $00 -.byte $93, $10, $00 -.byte $93, $10, $00 -.byte $77, $10, $00 -.byte $77, $10, $00 -.byte $77, $10, $00 -.byte $77, $10, $00 -.byte $77, $10, $00 -.byte $77, $48, $00 -.byte $77, $48, $00 -.byte $77, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $01 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $97, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $9B, $48, $00 -.byte $9B, $48, $00 -.byte $9B, $48, $01 -.byte $9B, $48, $00 -.byte $9B, $48, $00 -.byte $9B, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $02 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $01 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $73, $48, $00 -.byte $73, $48, $02 -.byte $73, $48, $00 -.byte $73, $48, $00 -.byte $73, $0C, $00 -.byte $73, $0C, $00 -.byte $73, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $01 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $01 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $43, $0C, $00 -.byte $43, $0C, $00 -.byte $43, $0C, $00 -.byte $2F, $0C, $00 -.byte $2F, $0C, $00 -.byte $2F, $0C, $00 -.byte $2F, $0C, $00 -.byte $2F, $0C, $00 -.byte $2F, $0C, $00 -.byte $2F, $0C, $00 -.byte $2F, $0C, $00 -.byte $2F, $0C, $00 -.byte $2F, $0C, $00 -.byte $2F, $0C, $00 -.byte $2F, $0C, $00 -.byte $2F, $0C, $00 -.byte $87, $0C, $00 -.byte $87, $0C, $00 -.byte $87, $0C, $01 -.byte $87, $0C, $00 -.byte $87, $0C, $00 -.byte $87, $0C, $00 -.byte $5F, $0C, $00 -.byte $5F, $0C, $00 -.byte $5F, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $02 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $0C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $84, $00 -.byte $B3, $84, $00 -.byte $B3, $84, $00 -.byte $B3, $84, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $A0, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $02 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $40 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $02 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $10, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $01 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $AF, $58, $00 -.byte $AF, $4C, $00 -.byte $B3, $48, $00 -.byte $B3, $48, $01 -.byte $B3, $48, $00 -.byte $B3, $48, $00 -.byte $B3, $38, $00 -.byte $AF, $3C, $00 -.byte $AB, $38, $00 -.byte $A7, $38, $00 -.byte $A7, $38, $00 -.byte $A7, $38, $00 -.byte $A7, $38, $00 -.byte $AB, $3C, $00 -.byte $AB, $40, $00 -.byte $B3, $40, $00 -.byte $B3, $44, $02 -.byte $B3, $44, $00 -.byte $B3, $44, $00 -.byte $B3, $40, $00 -.byte $AF, $3C, $00 -.byte $AB, $38, $00 -.byte $A7, $34, $00 -.byte $A3, $30, $00 -.byte $9B, $18, $00 -.byte $9B, $18, $01 -.byte $9B, $18, $00 -.byte $9B, $18, $00 -.byte $A3, $14, $00 -.byte $A7, $18, $00 -.byte $AB, $1C, $00 -.byte $B3, $20, $00 -.byte $B3, $38, $01 -.byte $B3, $38, $00 -.byte $B3, $38, $00 -.byte $B3, $38, $00 -.byte $AF, $4C, $00 -.byte $AB, $38, $00 -.byte $AB, $38, $01 -.byte $AB, $38, $00 -.byte $AB, $38, $00 -.byte $AB, $38, $00 -.byte $A7, $34, $00 -.byte $A7, $30, $00 -.byte $A3, $2C, $00 -.byte $A3, $2C, $01 -.byte $A3, $2C, $00 -.byte $A3, $2C, $00 -.byte $9F, $2C, $00 -.byte $9F, $30, $00 -.byte $9F, $2C, $00 -.byte $9B, $28, $00 -.byte $9B, $24, $02 -.byte $9B, $24, $00 -.byte $9B, $24, $00 -.byte $9B, $28, $00 -.byte $97, $2C, $00 -.byte $9B, $2C, $00 -.byte $9F, $30, $00 -.byte $9F, $30, $00 -.byte $A3, $34, $00 -.byte $A3, $38, $00 -.byte $A3, $3C, $00 -.byte $AF, $3C, $00 -.byte $B3, $38, $00 -.byte $B3, $34, $00 -.byte $AF, $34, $00 -.byte $9B, $38, $00 -.byte $9B, $34, $00 -.byte $97, $30, $00 -.byte $8F, $2C, $00 -.byte $8F, $2C, $01 -.byte $8F, $2C, $00 -.byte $8F, $2C, $00 -.byte $83, $24, $00 -.byte $83, $20, $00 -.byte $87, $24, $00 -.byte $9B, $24, $00 -.byte $AF, $28, $00 -.byte $AF, $2C, $00 -.byte $B3, $30, $00 -.byte $B3, $34, $02 -.byte $B3, $38, $00 -.byte $B3, $3C, $00 -.byte $B3, $3C, $00 -.byte $AF, $38, $00 -.byte $AF, $34, $00 -.byte $AB, $34, $00 -.byte $A7, $30, $00 -.byte $A3, $2C, $00 -.byte $A7, $28, $00 -.byte $AB, $24, $00 -.byte $AB, $24, $00 -.byte $B3, $20, $00 -.byte $B3, $20, $01 -.byte $B3, $20, $00 -.byte $B3, $20, $00 -.byte $B3, $20, $00 -.byte $AF, $2C, $00 -.byte $AB, $30, $00 -.byte $AB, $30, $00 -.byte $AF, $34, $00 -.byte $B3, $34, $00 -.byte $B3, $3C, $02 -.byte $B3, $40, $00 -.byte $B3, $44, $00 -.byte $B3, $44, $00 -.byte $B3, $44, $00 -.byte $B3, $50, $00 -.byte $AF, $54, $00 -.byte $AB, $5C, $00 -.byte $AB, $60, $00 -.byte $AF, $64, $00 -.byte $B3, $60, $00 -.byte $B3, $60, $02 -.byte $B3, $68, $00 -.byte $B3, $68, $00 -.byte $B3, $6C, $00 -.byte $B3, $6C, $00 -.byte $B3, $6C, $01 -.byte $B3, $6C, $00 -.byte $B3, $6C, $00 -.byte $B3, $64, $00 -.byte $B3, $60, $02 -.byte $B3, $60, $00 -.byte $B3, $5C, $00 -.byte $B3, $5C, $00 -.byte $B3, $58, $00 -.byte $AF, $58, $00 -.byte $AB, $58, $00 -.byte $A7, $54, $00 -.byte $A3, $44, $00 -.byte $9F, $44, $00 -.byte $9F, $44, $00 -.byte $9F, $44, $00 -.byte $A3, $44, $00 -.byte $A3, $44, $00 -.byte $A7, $34, $00 -.byte $9F, $28, $00 -.byte $9F, $28, $01 -.byte $9F, $28, $00 -.byte $9F, $28, $00 -.byte $9F, $28, $00 -.byte $9B, $30, $00 -.byte $97, $38, $00 -.byte $93, $3C, $00 -.byte $8F, $3C, $00 -.byte $93, $38, $00 -.byte $93, $34, $02 -.byte $93, $34, $00 -.byte $93, $38, $00 -.byte $93, $38, $00 -.byte $9B, $3C, $00 -.byte $9F, $40, $00 -.byte $A3, $3C, $00 -.byte $A3, $3C, $00 -.byte $A7, $38, $00 -.byte $AB, $38, $00 -.byte $B3, $34, $00 -.byte $B3, $34, $00 -.byte $B3, $34, $00 -.byte $AF, $30, $00 -.byte $AB, $30, $00 -.byte $A7, $2C, $00 -.byte $A7, $2C, $01 -.byte $A7, $2C, $00 -.byte $A7, $28, $00 -.byte $9F, $28, $00 -.byte $9B, $1C, $00 -.byte $9B, $14, $00 -.byte $97, $10, $00 -.byte $93, $14, $00 -.byte $8F, $14, $00 -.byte $77, $18, $00 -.byte $77, $18, $01 -.byte $77, $1C, $00 -.byte $77, $1C, $00 -.byte $73, $18, $00 -.byte $6F, $18, $00 -.byte $6F, $20, $00 -.byte $73, $24, $00 -.byte $77, $28, $00 -.byte $73, $34, $00 -.byte $73, $3C, $01 -.byte $73, $3C, $00 -.byte $73, $3C, $00 -.byte $77, $38, $00 -.byte $7B, $34, $00 -.byte $7B, $34, $00 -.byte $77, $38, $00 -.byte $73, $3C, $00 -.byte $73, $3C, $00 -.byte $7B, $3C, $00 -.byte $83, $40, $00 -.byte $83, $48, $00 -.byte $87, $48, $00 -.byte $8B, $48, $00 -.byte $93, $4C, $00 -.byte $93, $4C, $02 -.byte $93, $4C, $00 -.byte $93, $50, $00 -.byte $93, $50, $00 -.byte $9B, $4C, $00 -.byte $9F, $48, $00 -.byte $9F, $48, $00 -.byte $A3, $48, $00 -.byte $A7, $44, $00 -.byte $A7, $40, $00 -.byte $9F, $34, $00 -.byte $9F, $34, $01 -.byte $9F, $34, $00 -.byte $9F, $34, $00 -.byte $9F, $34, $00 -.byte $93, $24, $00 -.byte $93, $24, $00 -.byte $8F, $24, $00 -.byte $87, $24, $00 -.byte $87, $24, $01 -.byte $87, $24, $00 -.byte $87, $24, $00 -.byte $87, $24, $00 -.byte $83, $24, $00 -.byte $7F, $24, $00 -.byte $73, $24, $00 -.byte $73, $1C, $02 -.byte $73, $18, $00 -.byte $73, $18, $00 -.byte $73, $1C, $00 -.byte $77, $1C, $00 -.byte $7B, $20, $00 -.byte $83, $24, $00 -.byte $83, $28, $00 -.byte $87, $28, $00 -.byte $87, $24, $00 -.byte $87, $20, $00 -.byte $8B, $1C, $00 -.byte $93, $18, $00 -.byte $93, $18, $01 -.byte $93, $18, $00 -.byte $93, $18, $00 -.byte $97, $14, $00 -.byte $9B, $18, $00 -.byte $9F, $18, $00 -.byte $9F, $1C, $00 -.byte $9F, $20, $00 -.byte $9B, $24, $00 -.byte $93, $28, $00 -.byte $93, $2C, $01 -.byte $93, $2C, $00 -.byte $93, $2C, $00 -.byte $93, $2C, $00 -.byte $97, $2C, $00 -.byte $9B, $30, $00 -.byte $9F, $2C, $00 -.byte $AF, $30, $00 -.byte $B3, $38, $00 -.byte $B3, $38, $01 -.byte $B3, $38, $00 -.byte $B3, $38, $00 -.byte $B3, $38, $00 -.byte $B3, $38, $00 -.byte $AF, $30, $00 -.byte $AB, $2C, $00 -.byte $A7, $2C, $00 -.byte $A7, $30, $02 -.byte $A7, $30, $00 -.byte $A7, $34, $00 -.byte $A7, $34, $00 -.byte $AB, $38, $00 -.byte $AB, $34, $00 -.byte $B3, $38, $00 -.byte $B3, $38, $02 -.byte $B3, $3C, $00 -.byte $B3, $40, $00 -.byte $B3, $44, $00 -.byte $AF, $48, $00 -.byte $AB, $4C, $00 -.byte $AB, $50, $01 -.byte $AB, $50, $00 -.byte $AB, $50, $00 -.byte $AB, $4C, $00 -.byte $A7, $4C, $00 -.byte $A3, $48, $00 -.byte $9F, $48, $00 -.byte $9B, $44, $00 -.byte $97, $40, $00 -.byte $93, $3C, $00 -.byte $93, $3C, $00 -.byte $8F, $40, $00 -.byte $8B, $44, $00 -.byte $8B, $40, $00 -.byte $8F, $3C, $00 -.byte $8F, $38, $00 -.byte $93, $34, $00 -.byte $93, $30, $00 -.byte $97, $30, $00 -.byte $9B, $34, $00 -.byte $9F, $38, $00 -.byte $9B, $28, $00 -.byte $97, $28, $00 -.byte $97, $28, $01 -.byte $97, $28, $00 -.byte $97, $28, $00 -.byte $93, $28, $00 -.byte $93, $24, $02 -.byte $93, $24, $00 -.byte $93, $20, $00 -.byte $93, $1C, $00 -.byte $8F, $20, $00 -.byte $8B, $24, $00 -.byte $8B, $28, $00 -.byte $87, $2C, $00 -.byte $8B, $2C, $00 -.byte $8F, $28, $00 -.byte $8F, $24, $00 -.byte $93, $24, $00 -.byte $93, $20, $00 -.byte $93, $1C, $00 -.byte $97, $20, $00 -.byte $9F, $20, $00 -.byte $9F, $24, $00 -.byte $A3, $28, $00 -.byte $A7, $28, $00 -.byte $AB, $28, $00 -.byte $AB, $2C, $02 -.byte $AB, $2C, $00 -.byte $AB, $2C, $00 -.byte $AB, $38, $00 -.byte $AB, $3C, $00 -.byte $AB, $3C, $00 -.byte $A7, $40, $00 -.byte $A3, $48, $00 -.byte $9F, $50, $00 -.byte $A3, $54, $00 -.byte $A7, $54, $00 -.byte $A7, $50, $00 -.byte $A7, $54, $00 -.byte $AB, $50, $00 -.byte $AB, $54, $00 -.byte $B3, $58, $00 -.byte $B3, $58, $01 -.byte $B3, $58, $00 -.byte $B3, $58, $00 -.byte $AF, $58, $00 -.byte $AF, $58, $00 -.byte $AF, $58, $00 -.byte $AB, $58, $00 -.byte $AB, $58, $01 -.byte $AB, $58, $00 -.byte $AB, $54, $00 -.byte $AB, $54, $00 -.byte $A3, $50, $00 -.byte $A3, $44, $00 -.byte $9B, $44, $00 -.byte $9B, $44, $01 -.byte $9B, $44, $00 -.byte $9B, $44, $00 -.byte $97, $34, $00 -.byte $8F, $34, $00 -.byte $8F, $34, $01 -.byte $8F, $34, $00 -.byte $8F, $34, $00 -.byte $93, $34, $00 -.byte $8F, $20, $00 -.byte $8B, $1C, $00 -.byte $87, $20, $00 -.byte $83, $20, $00 -.byte $7F, $20, $00 -.byte $7F, $24, $02 -.byte $7F, $24, $00 -.byte $7F, $28, $00 -.byte $7F, $28, $00 -.byte $87, $24, $00 -.byte $8B, $28, $00 -.byte $8B, $2C, $00 -.byte $8F, $2C, $00 -.byte $93, $30, $00 -.byte $9F, $30, $00 -.byte $9F, $30, $01 -.byte $9F, $30, $00 -.byte $9F, $30, $00 -.byte $9F, $3C, $00 -.byte $9B, $3C, $00 -.byte $97, $30, $00 -.byte $8F, $30, $00 -.byte $8F, $30, $01 -.byte $8F, $30, $00 -.byte $8F, $30, $00 -.byte $93, $30, $00 -.byte $97, $38, $00 -.byte $9B, $3C, $00 -.byte $9F, $3C, $00 -.byte $A3, $40, $00 -.byte $A3, $44, $00 -.byte $9F, $44, $00 -.byte $9B, $48, $00 -.byte $97, $4C, $00 -.byte $93, $48, $00 -.byte $83, $44, $00 -.byte $7F, $40, $00 -.byte $7F, $3C, $00 -.byte $7B, $3C, $00 -.byte $73, $30, $00 -.byte $73, $30, $01 -.byte $73, $30, $00 -.byte $73, $30, $00 -.byte $77, $30, $00 -.byte $77, $28, $00 -.byte $6B, $24, $00 -.byte $6B, $28, $02 -.byte $6B, $2C, $00 -.byte $6B, $2C, $00 -.byte $6B, $28, $00 -.byte $73, $20, $00 -.byte $6B, $20, $00 -.byte $6B, $20, $01 -.byte $6B, $20, $00 -.byte $6B, $20, $00 -.byte $6F, $24, $00 -.byte $73, $20, $00 -.byte $6F, $1C, $00 -.byte $67, $1C, $00 -.byte $67, $14, $02 -.byte $67, $14, $00 -.byte $67, $10, $00 -.byte $67, $14, $00 -.byte $6F, $14, $00 -.byte $6F, $18, $00 -.byte $73, $1C, $00 -.byte $73, $20, $00 -.byte $7B, $24, $00 -.byte $7F, $24, $00 -.byte $83, $28, $00 -.byte $83, $28, $00 -.byte $8F, $2C, $00 -.byte $93, $30, $00 -.byte $9B, $34, $00 -.byte $A7, $34, $00 -.byte $A7, $38, $02 -.byte $A7, $3C, $00 -.byte $A7, $3C, $00 -.byte $A7, $38, $00 -.byte $B3, $38, $00 -.byte $B3, $38, $02 -.byte $B3, $38, $00 -.byte $B3, $38, $00 -.byte $B3, $3C, $00 -.byte $AF, $3C, $00 -.byte $AF, $3C, $01 -.byte $AF, $3C, $00 -.byte $AF, $3C, $00 -.byte $AF, $3C, $00 -.byte $A3, $3C, $00 -.byte $A3, $3C, $01 -.byte $A3, $3C, $00 -.byte $A3, $34, $00 -.byte $9F, $30, $00 -.byte $9F, $30, $00 -.byte $9F, $30, $00 -.byte $8F, $28, $00 -.byte $8F, $28, $41 -.byte $8F, $28, $00 -.byte $8F, $28, $00 -.byte $83, $1C, $00 -.byte $7B, $1C, $00 -.byte $7B, $1C, $01 -.byte $7B, $1C, $00 -.byte $7B, $1C, $00 -.byte $7B, $20, $00 -.byte $77, $24, $00 -.byte $67, $24, $00 -.byte $67, $20, $02 -.byte $67, $1C, $00 -.byte $67, $18, $00 -.byte $67, $14, $00 -.byte $7B, $0C, $00 -.byte $7B, $0C, $01 -.byte $7B, $0C, $00 -.byte $7B, $0C, $00 -.byte $7B, $0C, $00 -.byte $8B, $0C, $00 -.byte $8B, $18, $00 -.byte $9B, $18, $00 -.byte $9B, $20, $01 -.byte $9B, $20, $00 -.byte $9B, $20, $00 -.byte $9F, $20, $00 -.byte $9F, $1C, $02 -.byte $9F, $20, $00 -.byte $9F, $24, $00 -.byte $9F, $20, $00 -.byte $A3, $1C, $00 -.byte $AB, $18, $00 -.byte $AB, $14, $00 -.byte $AF, $10, $00 -.byte $AF, $0C, $00 -.byte $B3, $10, $00 -.byte $AB, $10, $00 -.byte $AB, $14, $02 -.byte $AB, $18, $00 -.byte $AB, $1C, $00 -.byte $AB, $20, $00 -.byte $AF, $24, $00 -.byte $AF, $20, $00 -.byte $B3, $20, $00 -.byte $B3, $1C, $01 -.byte $B3, $18, $00 -.byte $B3, $14, $00 -.byte $B3, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $A7, $08, $00 -.byte $9F, $08, $00 -.byte $93, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $6F, $08, $00 -.byte $6F, $08, $01 -.byte $6F, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $77, $08, $00 -.byte $6B, $08, $00 -.byte $6B, $08, $00 -.byte $6B, $08, $00 -.byte $6B, $08, $01 -.byte $6B, $08, $00 -.byte $6B, $08, $00 -.byte $6B, $08, $00 -.byte $6B, $08, $00 -.byte $9F, $08, $00 -.byte $9F, $08, $02 -.byte $9F, $08, $00 -.byte $9F, $08, $02 -.byte $9F, $08, $00 -.byte $6B, $08, $00 -.byte $6B, $08, $00 -.byte $6B, $08, $00 -.byte $6B, $08, $01 -.byte $6B, $08, $00 -.byte $6B, $08, $00 -.byte $6B, $08, $00 -.byte $6B, $08, $00 -.byte $77, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $6F, $08, $00 -.byte $6F, $08, $01 -.byte $6F, $08, $00 -.byte $7F, $08, $00 -.byte $7F, $08, $00 -.byte $93, $0C, $00 -.byte $9F, $0C, $00 -.byte $A7, $0C, $00 -.byte $AF, $0C, $00 -.byte $AF, $0C, $00 -.byte $AF, $0C, $00 -.byte $AF, $0C, $00 -.byte $AF, $14, $00 -.byte $AF, $1C, $00 -.byte $AF, $1C, $00 -.byte $AF, $1C, $00 -.byte $AF, $1C, $00 -.byte $AF, $1C, $00 -.byte $AF, $20, $00 -.byte $AF, $20, $00 -.byte $AF, $20, $00 -.byte $AF, $28, $00 -.byte $AF, $28, $00 -.byte $AF, $28, $00 -.byte $AF, $2C, $00 -.byte $AF, $2C, $00 -.byte $AB, $2C, $00 -.byte $9F, $34, $00 -.byte $8F, $34, $00 -.byte $8B, $34, $00 -.byte $8B, $34, $00 -.byte $7F, $40, $00 -.byte $6F, $48, $00 -.byte $6B, $48, $00 -.byte $63, $48, $00 -.byte $67, $58, $00 -.byte $77, $58, $00 -.byte $83, $64, $00 -.byte $83, $68, $00 -.byte $83, $60, $00 -.byte $93, $58, $00 -.byte $97, $50, $00 -.byte $97, $50, $00 -.byte $A3, $50, $00 -.byte $A7, $48, $00 -.byte $A7, $48, $00 -.byte $A7, $40, $00 -.byte $AB, $3C, $00 -.byte $AF, $38, $00 -.byte $AF, $2C, $00 -.byte $AF, $20, $00 -.byte $AF, $18, $00 -.byte $AF, $14, $00 -.byte $AF, $0C, $00 -.byte $AF, $0C, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 -.byte $AF, $08, $00 - -worldDataEnd: diff --git a/src/apple2/ui.inc b/src/apple2/ui.inc deleted file mode 100644 index 7210284..0000000 --- a/src/apple2/ui.inc +++ /dev/null @@ -1,1144 +0,0 @@ -;----------------------------------------------------------------------------- -; ui.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "CODE" - -;----------------------------------------------------------------------------- -.proc uiTitleScreen - - zaCounterL = tempBlock + 17 ; timer for flipping text - zaCounterH = tempBlock + 18 - zaState = tempBlock + 19 ; which text to show - - lda #0 - bit KBDSTRB ; flush the keyboard buffer before uiWriteName - sta lastInput - - jsr drawClearScreen - jsr uiWriteName ; also looks for a key press - - jsr uiShowHighScores - jsr drawPresent ; present and - jsr uiShowHighScores ; show again so it's on both layers - -loopo: - lda #0 ; set all keys to down for joystick - bit KBDSTRB - sta lastInput ; debounce the last key if it was a joy button - sta zaCounterL - sta zaState - -loop: - lda #$08 - sta zaCounterH - - lda zaState - bne :+ - print textPhilip , #(00), #(8*21) ; the text shows in 3 stages - print textCopyright, #(00), #(8*22) - lda zaState - -: - cmp #1 - bne :+ - print textApple2 , #(00), #(8*21) - print textStefan , #(00), #(8*22) - lda zaState - -: - cmp #2 - bne :+ - print textSupport , #(00), #(8*21) - print textOliver , #(00), #(8*22) - lda zaState - -: - cmp #3 - bne :+ - print textSource , #(00), #(8*21) - print textGitHub , #(00), #(8*22) - -: - jsr drawPresent ; show the sceen - -: - jsr inputCheckForInput ; wait for user interaction - bne done - dec zaCounterL - bne :- - dec zaCounterH - bne :- - - inc zaState - lda zaState - cmp #4 - bcc :+ - jmp loopo -: - jmp loop - -done: - rts - -.endproc - -;----------------------------------------------------------------------------- -.proc uiShowHighScores - - zaStrL = tempBlock + 1 - zaStrH = tempBlock + 2 - zaForce = tempBlock + 3 - textX = tempBlock + 10 - textY = tempBlock + 11 - scorePtrL = tempBlock + 14 ; 2 + 3 used by textOut - scorePtrH = tempBlock + 15 - scoreIdx = tempBlock + 16 - scoreShown = tempBlock + 17 - - lda #highScores - sta scorePtrH - lda #0 ; and init two counters - sta scoreIdx ; which high-score is being processed - sta scoreShown ; were any high-scores printed - -loop: - ldy #3 ; 3 bytes to a score - ldx #0 ; don't force a number - lda scorePtrL ; get the score to convert - sta zaStrL - lda scorePtrH - sta zaStrH - jsr textBCDtoSZ ; convert it - dex ; step back from the null-terminator - lda textNumber, x ; get the last character out - cmp #' ' ; was it a space - bne show ; no - there was a score so show it - beq heading ; as soon as there's no score there won't be any more - -next: - inc scoreIdx ; go to next score - lda scoreIdx - cmp #5 ; all 5 scores shown? - bcc cont ; if not, carry on processing - -heading: - lda scoreShown ; were any score printed - beq done ; if not, nothing more - print textHighScores, #(11), #(8*0) ; Show the scores' heading - -done: - rts - -cont: - lda scorePtrL ; advance the score ptr to the next 3 bytes - adc #3 - sta scorePtrL - bcc loop - inc scorePtrH - bne loop ; JuMP - -show: ; a high-score was set, so show it - inc scoreShown - inx ; back to the null terminator - lda #'0' ; Show score as 10x the actual score - sta textNumber, x ; append the 0 to the buffer - ldx scoreIdx ; get the index of which score - lda #textNumber - sta zaStrH - lda scorePosX, x ; get the X position of where - sta textX - lda scoreTextPosY, x ; and the Y position - sta textY - jsr textOut ; now render the text - - ldx scoreIdx ; get the score index again - lda scoreTextOffset, x ; and figure out the start of the name text for this score - clc - adc #textHS - sta zaStrH - lda scoreTextPosX, x ; get the x position - sta textX - lda scoreTextPosY, x ; and the y position - sta textY - jsr textOut ; and render the text - - jmp next ; and go to the next score - -.endproc - -;----------------------------------------------------------------------------- -; Uses line drawing to spell out the Penetrator logo -.proc uiWriteName - - x0 = tempBlock + 0 ; local variables - x1 = tempBlock + 1 - y0 = tempBlock + 2 - y1 = tempBlock + 3 - dx = tempBlock + 4 - dy = tempBlock + 5 - sx = tempBlock + 6 - sy = tempBlock + 7 - dyNeg = tempBlock + 8 - err = tempBlock + 9 - err2 = tempBlock + 10 - index = tempBlock + 11 - remain = tempBlock + 12 - skip = tempBlock + 13 - width = tempBlock + 14 - height = tempBlock + 15 - - lda #0 - sta audioExplFrame ; use this as a delay counter for logo sound - - lda #((dataLogoLinesEnd - dataLogoLines) / 4) - sta remain - - ldx #0 - stx index ; current line - stx skip ; impatient user - - lda #1 ; set up the plot - sta width - - lda #1 - sta height - -loop: - dec remain ; iterate over all lines - bpl :+ - lda #0 - sta audioExplFrame - rts -: - ldx index - - lda dataLogoLines,x ; Load x0,y0 x1,y1 into variables - sta x0 - inx - lda dataLogoLines,x - sta y0 - inx - lda dataLogoLines,x - sta x1 - inx - lda dataLogoLines,x - sta y1 - inx - - stx index ; update the index to next line params - - ldy #2 ; dx = abs(x1-x0) - sx=2 - lda x1 - sec - sbc x0 - bcs :+ ; x1 >= x0 - eor #$ff ; abs - adc #1 - ldy #0 ; sx=0 - -: - sta dx - dey ; sx=-1|1 - sty sx - - - ldy #2 ; dy = abs(y1-y0) - sy=2 - lda y1 - sec - sbc y0 - bcs :+ ; y1 >= y0 - eor #$ff ; abs - adc #1 - ldy #0 ; sy=0 - sec -: - sta dy - lda #0 - sbc dy - sta dyNeg ; = -dy - dey ; sy=-1|1 - sty sy - - - lda dx ; err = dx-dy - sec - sbc dy - sta err - -plot: - ldx x0 - ldy y0 - jsr drawPlotXY ; plot a "pixel" at x y - - jsr drawPresent ; present this plot - - ldx x0 ; do for the 2nd buffer the same - ldy y0 - jsr drawPlotXY - - lda skip ; if key/button pressed - fast draw logo - bne :+ - lda audioMask - beq nosnd -snd: - ldy audioExplFrame - ldx #4 - jsr playNote ; play the note - dec audioExplFrame ; alter the note - dec audioExplFrame - bmi nosnd ; variable decay so that the duration - dec audioExplFrame ; is a close match to when the logo ends - dec audioExplFrame -nosnd: - jsr inputCheckForInput ; check for user interaction - sta skip - bne :+ - wait #$01 - -: - lda x0 ; if(x0=x1 && y0=y1) done - cmp x1 - bne :+ - lda y0 - cmp y1 - bne :+ - jmp loop - -: - lda err ; e2 = err << 1 - asl - sta err2 - - - lda dyNeg ; if(e2 > -dy) - sec - sbc err2 - bpl :+ - - - lda err ; err = err - dy - sec - sbc dy - sta err - - lda x0 ; x0 = x0 + sx - clc - adc sx - sta x0 - -: - lda dx ; if(e2 < dx) - sec - sbc err2 - bpl :+ - jmp plot - -: - lda err ; err = err + dx - clc - adc dx - sta err - - lda y0 ; y0 = y0 + sy - clc - adc sy - sta y0 - jmp plot - -.endproc - -;----------------------------------------------------------------------------- -; Shows the main menu and waits for user choice -.proc uiMainMenu - - jsr drawClearScreen - -redraw: - print textInstructions, #(10), #(8*04) - print textPress , #(13), #(8*08) - print textUnderline , #(13), #(8*09) - print textOneTwo , #(00), #(8*11) - print textTrain , #(00), #(8*12) - print textEdit , #(02), #(8*13) - print textLoad , #(01), #(8*14) - print textSirens , #(05), #(8*15) - print textQuit , #(12), #(8*16) - - lda audioMask - beq none - - bit Bit8432Mask - bne :+ - print textAudio2 , #(20), #(8*15) - jmp present - -: - print textAudio1 , #(20), #(8*15) - jmp present - -none: - print textAudio3 , #(20), #(8*15) - -present: - jsr drawPresent - - lda #GAME_MODE_PLAY ; assume the player will play (play is 0) - sta gameMode - sta stage ; and set the stage to 0 - sta lastInput - -loop: - lda #(optionsEnd-options) ; how many options on this menu - ldx #options ; y - hi options "string" - jsr uiHandleOptions ; on return, x is the option selected (0 based) - - cpx #(optionsEnd-options) + 1 - bne :+ - rts - -: - cpx #2 ; 0 & 1 for 1/2 player game - bcs train ; greater means another option - - stx numPlayers ; x happens to be the value for numPlayers - jmp gamePlay ; go gameplay and return to title screen - -train: - bne edit ; still on the cpx #2 here - jmp uiTrainerMode ; 2 means train, and then return to title screen - -edit: - cpx #3 - bne load - - jsr editLoop ; 3 means edit - jmp uiMainMenu ; and go to main menu, not title - -load: - cpx #4 - bne sirens - lda #1 ; 1 means load - jsr uiFileLoadSave ; call the code to do file name and load - jmp uiMainMenu - -sirens: ; For Apple II this is the "set sound type" - cpx #5 - bne quit - - lda audioMask - beq audioSetAll - bit Bit8432Mask - bne :+ - lda #0 - beq :++ -: - lda #(AUDIO_EXPLOSION | AUDIO_BOMB_DROP | AUDIO_FIRE | AUDIO_UI_TICK) - bne :+ - -audioSetAll: - lda #%01111111 -: - sta audioMask - jmp redraw - -quit: - inc PWREDUP ; Make sure this isn't a power vector - - jsr MLI ; call the prodos mli ($bf00) - never returns here - .byte QUIT_CALL ; call type = quit - .addr quitParam ; pointer to parameter table - -quitParam: - .byte 4 ; number of parameters is 4 - .byte 0 ; quit type - .word 0000 ; reserved - .byte 0 ; reserved - .word 0000 ; reserved - -options: .byte "12TELSQ" -optionsEnd: - -.endproc - -;----------------------------------------------------------------------------- -; Shows the trainer menu asking for a stage to train (1-4). Allows -; backspace to go back to main menu -.proc uiTrainerMode - - jsr drawClearScreen - - print textTrainingMode, #(11), #(8*04) - print textPressStage , #(02), #(8*12) - print textOneToFour , #(08), #(8*13) - print textBackup , #(03), #(8*23) - - jsr drawPresent - - lda #GAME_MODE_TRAIN - sta gameMode - - lda #(optionsEnd-options) - ldx #options - jsr uiHandleOptions - - cpx #4 ; backspace option - bcc stageSel - cpx #(optionsEnd-options)+1 ; time out goes to title, not main menu like backup - bne :+ - rts -: - jmp uiMainMenu ; on backspace go back to main menu - -stageSel: - stx stage - jmp gamePlay - rts - -options: .byte "1234", $1b ; $1b is ESC -optionsEnd: - -.endproc - -;----------------------------------------------------------------------------- -; Take the number of options in accumulator -; Take a pointer to a number of options in x (lo) y (hi) -; returns when an option was selected, the index of the selected option in x -.proc uiHandleOptions - - sta len + 1 ; set the length for the number of options to look at - stx option + 1 ; set address of the options "string" - sty option + 2 - - lda #0 - bit KBDSTRB ; flush the keyboard buffer - sta lastInput - -loop: - jsr inputCheckForInput ; get the input - beq loop ; no input keep looping - bit KBDSTRB ; reset the keyboard buffer - cmp len + 1 ; if a >= num options - bcs len ; then it's a keyboard menu - tax ; it's a joystick selection - dex ; so 0 based, x-1 is the chosen option - rts ; done - -len: - ldx #0 ; placeholder 0 - -option: - cmp PLACEHOLDER,x ; placeholder address - beq done ; compare the keyboard to the options - dex - bpl option ; check all options - bmi loop ; when x is -1 it was an invalid entry so loop back - -done: - rts ; x contains the number of the chosen option - -.endproc - -;----------------------------------------------------------------------------- -.proc uiShowEditHelp - - lda #0 ; clear the keyboard buffer - bit KBDSTRB - sta lastInput - - jsr drawClearScreen ; clear the screen - - print textEdtHlp01, #(04), #(8*00) ; show all the help text - print textEdtHlp02, #(04), #(8*01) - print textEdtHlp03, #(00), #(8*03) - print textEdtHlp04, #(00), #(8*05) - print textEdtHlp05, #(00), #(8*06) - print textEdtHlp06, #(00), #(8*08) - print textEdtHlp07, #(00), #(8*09) - print textEdtHlp08, #(00), #(8*11) - print textEdtHlp09, #(00), #(8*12) - print textEdtHlp10, #(00), #(8*14) - print textEdtHlp11, #(00), #(8*15) - print textEdtHlp12, #(00), #(8*17) - print textEdtHlp13, #(00), #(8*18) - print textEdtHlp14, #(00), #(8*19) - print textEdtHlp15, #(04), #(8*21) - print textEdtHlp16, #(04), #(8*22) - print textEdtHlp17, #(03), #(8*23) - - jsr drawPresent - -: - jsr inputCheckForInput ; wait for the user to dismiss the help - beq :- - - jsr drawClearScreen ; clear the screen - - lda #2 ; and force a - sta updateHUD ; HUD update - - rts - -.endproc - - -;----------------------------------------------------------------------------- -.proc uiWinScreen - - cntrl = tempBlock + 14 ; some delay counters, past the text* temporary vars - cntrh = tempBlock + 15 - - jsr drawClearScreen - - lda #$0 ; init the counters - value - sta cntrl - lda #2 ; init the counters - value - sta cntrh ; not important what these are init with - - jsr drawPresent - - print textBonus , #(13), #(8*00) ; show the win screen text - - printBig textPoints, #$08, #$04, #$01, #$01 - printBig text1000 , #$03, #$0D, #$02, #$02 - - lda stage ; last word changes for home vs victory - beq :+ - printBig textWow , #$02, #$1D, #$03, #$03 - jmp present -: - printBig textHome , #$04, #$1D, #$02, #$03 - -present: - jsr drawPresent - - lda #0 - bit KBDSTRB ; flush the keyboard buffer - sta lastInput - -loop: - dec cntrl - bne :+ - dec cntrh - bne :+ - ldy #$0 - sty cntrl - ldy #2 - sty cntrh - jsr drawInvertVisibleScreen -: - jsr inputCheckForInput - beq loop ; exit on a key / button - -done: - rts - -.endproc - -;----------------------------------------------------------------------------- -; Show the portions of the HUD that don't change between runs -.proc uiShowGameLabels - - lda #2 ; mark the HUD as needing update - sta updateHUD - -loop: - - print textTopLine , #(00), #(8*00) - print textPlayerNum, #(17), #(8*00) - print textDanger , #(00), #(8*23) - lda gameMode - bne :+ - - print textShips , #(23), #(8*23) - beq show ; JuMP to show - print always leaves with Z flag set - -: - print textTrainer , #(24), #(8*23) - -show: - jsr uiUpdateGameHud - jsr drawPresent - - lda updateHUD - beq done - jmp loop - -done: - rts - -.endproc - -;----------------------------------------------------------------------------- -; show the HUD variables that change over time -.proc uiUpdateGameHud - - clc ; prep the HUD text for the stage - lda stage - adc #'1' ; zero based but HUD display 1-5 not 0-4 - sta textStage - - print textStage , #(06), #(8*00) - print textDangerBar, #(06), #(8*23) - - printBCD score , #3, #0, #(25), #(8*00) - - lda gameMode - bne :+ - - printBCD lives , #1, #1, #(30), #(8*23) - -: - dec updateHUD ; dec "show" counter - - rts - -.endproc - -;----------------------------------------------------------------------------- -; Show the portions of the HUD that don't change between runs -.proc uiShowEditLabels - - brushType = tempBlock + 16 - - lda #2 ; mark the HUD as needing update - sta updateHUD - - clc ; prep the HUD text for the stage - lda stage - adc #'1' ; zero based but HUD display 1-5 not 0-4 - sta textStage - -loop: - - print textEditStage , #(05), #(8*00) - print textStage , #(12), #(8*00) - print textEditHelp , #(01), #(8*23) - print textEditBrush , #(19), #(8*00) - lda brushType - bne modeEnemy - - print textEditTerrain, #(26), #(8*00) - jmp :+ - -modeEnemy: - print textEditEnemies, #(26), #(8*00) - -: - jsr drawPresent - dec updateHUD ; dec "show" counter - beq done - jmp loop - -done: - rts - -.endproc - -;----------------------------------------------------------------------------- -.proc uiCheckHighScore - - scoreIdx = tempBlock + 16 - - clc - lda score ; make sure one of the score components is non-zero - adc score + 1 ; because a zero score is not high-score eligible - adc score + 2 - bne didScore - rts - -didScore: - lda #((highScoresEnd-highScores) / 3) ; score insert point (1 past end of 0 based table) - sta scoreIdx ; save the index - ldx #((highScoresEnd-highScores) - 1) ; point x at the high byte of the last score - -nextScore: - ldy #2 ; point y at the high byte of the current score -nextByte: - lda score, y ; get the score byte - cmp highScores, x ; compare to the high score byte - bcc lt ; if it's smaller, then this high-score is bigger than the score - beq eq -: ; score > highscore so ignore remaining bytes in this comparison - dex - dey - bpl:- - bmi gt ; step over this smaller highscore -eq: - dex ; go to the next bytes - dey - bpl nextByte ; look at the whole score -gt: - dec scoreIdx ; the score is bigger than this high score so move "up" one - bne nextScore ; compare against all high-scores in the table - -lt: - ldx #((highScoresEnd-highScores) / 3) ; get the index past end - cpx scoreIdx ; see if the scoreIdx still matches - bne newHS ; if not, then a new table entry needs to be made - rts - -newHS: - dex ; x now points at last table entry (zero based) - cpx scoreIdx ; see if the score overwrites the last table entry - beq copyScore ; if yes, just copy score over last table entry - - jsr uiInsertHighScoreRow ; otherwise scores need to be moved so the score inserts - -copyScore: - lda scoreIdx ; calc the offset of the last byte of the score being replaced - asl ; start with index * 2 (and clears carry) - adc scoreIdx ; + index (* 3 now sice 3 bytes / score) - adc #2 ; and add 2 to point at the last byte - tax ; save this offset in x - ldy #2 ; last byte of the score -: - lda score, y ; copy the score - sta highScores, x ; over the high-score - dex ; for all 3 bytes - dey - bpl :- - - jsr uiGetHighScoreName ; now get the new name - jmp saveHighScores - -.endproc - -;----------------------------------------------------------------------------- -; move the score and the name in the highscore table "down" a row -; so the new entry can go into the "space" -; scoreIdx is the number of the row that will move down -.proc uiInsertHighScoreRow - - bytes = tempBlock + 15 - scoreIdx = tempBlock + 16 - rows = tempBlock + 17 - - lda #(((highScoresEnd-highScores) / 3) - 1) ; Get the length of the table 0 based - sec - sbc scoreIdx ; subtract the insert row - sta rows ; number of rows to move - asl ; mult by 3 - adc rows - sta bytes ; that's how many bytes to move -:beq:- - ldy #((highScoresEnd-highScores)-4) ; point at the second last row, last byte - ldx #((highScoresEnd-highScores)-1) ; point at the last row, last byte - -scoreLoop: - lda highScores, y ; copy the bytes - sta highScores, x - dex - dey - dec bytes - bne scoreLoop ; till all bytes copied - - lda rows ; prep to copy name rows - asl ; * 8 - 1 is * 7 (7 bytes/name - incl null terminator) - asl - asl - sec - sbc rows - sta bytes ; set the number of bytes to copy - - ldy #((textHSEnd-textHS)-8) ; point at the second last row, last byte - ldx #((textHSEnd-textHS)-1) ; point at the last row, last byte - -nameLoop: - lda textHS, y ; copy the bytes - sta textHS, x - dex - dey - dec bytes - bne nameLoop ; till all bytes copied - - rts - -.endproc - -;----------------------------------------------------------------------------- -; Let the player enter a name for the high score table -; the table entry (0 based) is in scoreIdx when called -.proc uiGetHighScoreName - - zaStrL = tempBlock + 1 ; ptr to a string to print - zaStrH = tempBlock + 2 - zaEntryL = zWorldPtr ; ptr to a string being entered (abusing world ptr) - zaEntryH = zWorldPtr + 1 - scoreIdx = tempBlock + 16 ; 0 based index into score table - entryLen = tempBlock + 17 ; how many characters the player has entered - shared with uiGetUserText - textLen = tempBlock + 18 ; how many characters the player may enter with uiGetUserText - - jsr drawClearScreen - - clc - ldx scoreIdx ; get the index into the score table - lda #textHS - sta zaEntryH - - lda #95 ; the "_" character so stomp the current entry with underscores - ldx #((textHighScore2-textHighScore1)-1) ; all scores have the same length - stx textLen ; save how long the name may be - ldy #0 ; start at character 0 -: - sta (zaEntryL), y ; write the underscores (also restores the original length) - iny ; by overwriting terminators of old entered text - dex - bne :- - stx entryLen ; save 0 to the length of the new name - -showName: - print textCongrats , #(00), #(8*05) ; show the screen - print textHSPlayer , #(10), #(8*06) - print textPlayerNum, #(20), #(8*06) - print textHSPlayer , #(10), #(8*06) - print textTop5 , #(03), #(8*08) - print textTypeName , #(04), #(8*09) - - lda zaEntryL ; prep the print string - sta zaStrL ; by using the entry string location - lda zaEntryH ; zaStrL is modified through printing - sta zaStrH ; but the entry copy is stable - - printZAStr #(13), #(8*11) ; print the name - jsr drawPresent - - jsr uiGetUserText ; Get a character - bcc enter ; on carry clear enter was pressed - jmp showName ; show the updated name - -enter: - ldy entryLen ; get how many characters entered - lda #0 ; load a null terminator - sta (zaEntryL), y ; terminate the string - -done: - jsr drawClearScreen - - rts - -.endproc - -;----------------------------------------------------------------------------- -; Show a UI screen asking for a file name to load or save -; Parameter in acc. 0 is save and 1 is load -.proc uiFileLoadSave - - zaStrL = tempBlock + 1 ; internal - ptr to a string to print - zaStrH = tempBlock + 2 ; internal - zaEntryL = zWorldPtr ; internal - ptr to a string being entered (abusing world ptr) - zaEntryH = zWorldPtr + 1 ; internal - entryLen = tempBlock + 17 ; internal - how many characters the player has entered - textLen = tempBlock + 18 ; internal - how many characters the player may enter - forLoad = tempBlock + 15 ; Parameter - 0 means save, 1 means load - allOver = tempBlock + 16 ; internal - on enter, redraw the screen 1 more time - - sta forLoad - jsr drawClearScreen - - lda #textFileName - sta zaEntryH - lda #((textFileNameEnd - textFileName) - 1) ; get how long the name may be - sta textLen - - ldy #0 - sty KBDSTRB ; clear the keyboard buffer - sty lastInput ; and the last key - sty allOver ; 1 when the name has been entered - for redraw -: ; get the length of the file name there already - lda (zaEntryL), y ; get the first letter - beq :+ ; if trailing zero then name is known - iny - bne :- -: - sty entryLen ; save the length of the name - - lda #95 ; the "_" character so stomp the remaining name with underscores -: - cpy textLen - bcs showName - sta (zaEntryL), y ; write the underscores (also restores the original length) - iny ; by overwriting terminators of old entered text - bne :- - -showName: - lda forLoad - beq :+ - print textFileLoad , #(12), #(8*02) - print textFileInfoL , #(09), #(8*08) - jmp cont -: - print textFileSave , #(12), #(8*02) - print textFileInfoS , #(09), #(8*08) - -cont: - print textFileLines , #(12), #(8*03) - print textFileInfo , #(14), #(8*08) - print textFileEnter , #(05), #(8*10) - - lda zaEntryL ; prep the print string - sta zaStrL ; by using the entry string location - lda zaEntryH ; zaStrL is modified through printing - sta zaStrH ; but the entry copy is stable - - printZAStr #(11), #(8*14) - - lda allOver ; is this the last redraw before going to disc - bne disc ; if <> 0 then time to go to disc - - jsr drawPresent ; show the screen with changes to file name - - jsr uiGetUserText ; Get a character - bcc enter ; on carry clear enter was pressed - jmp showName ; show the updated name - -enter: - ldy entryLen ; get how many characters entered - lda #0 ; and null terminate the string - sta (zaEntryL), y - - jsr setWorldFileName - - lda #1 ; enter has been pressed - it's all over - sta allOver ; time to attempt a disc action, but just redraw once more - jmp showName - -disc: - lda forLoad ; load or save - beq save - - jsr loadWorld ; load the file by the name - bcs fail ; if carry set then there's an error - jmp success ; no error - all good - -save: - jsr saveWorld ; save the file - bcs fail ; if carry set then there's an error - -success: - print textFileSuccess, #(13), #(8*18) - jmp show - -fail: ; there was an error saving the file - pha ; error code in the accumulator, so save it - print textFileThe , #(01), #(8*18) - print textFileFailed , #(10), #(8*18) - - lda forLoad ; message for load/save differ - beq :+ - - print textFileInfoL , #(05), #(8*18) - jmp errcde - -: - print textFileInfoS , #(05), #(8*18) - -errcde: - pla ; get the saved error code - jsr toHex ; print it as human readable hex and show it to the user - print szHex , #(30), #(8*18) - -show: - jsr drawPresent ; finally show the whole screen - -getkey: - jsr inputCheckForInput ; wait for the user to acknowledge - beq getkey - - jsr drawClearScreen ; - - rts - -.endproc - -;----------------------------------------------------------------------------- -; Called with zaEntry pointing at a location to receive some text -; and entryLen should be 0 and is used internally to track where the current -; edit location in the string is. -; returns with partial string when carry set -; User pressed enter and accepted the string when carry clear on return -.proc uiGetUserText - - zaEntryL = zWorldPtr ; ptr to a string being entered (abusing world ptr) - entryLen = tempBlock + 17 ; Parameter/Internal - how many characters the player has entered - textLen = tempBlock + 18 ; how many characters the player may enter - - lda #0 - bit KBDSTRB ; flush the keyboard buffer - -loop: - lda KBD ; wait for a key - bit Bit8Mask - beq loop - bit KBDSTRB - - pha - lda #AUDIO_UI_TICK - sta audioFrame - jsr serviceAudio - pla - - and #$7F - cmp #$0D ; enter key then done - beq enter - cmp #$08 ; backspace key is handled - beq erase - cmp #$20 - beq accept ; space is okay - cmp #'0' - bcc loop ; ignore below '0' - cmp #('9'+1) - bcc accept ; 0-9 okay - cmp #'A' ; < 'A' ignore - bcc loop - cmp #('Z'+1) - bcc accept - cmp #'a' - bcc loop - cmp #('z'+1) - bcs loop ; ignore past 'Z' - -accept: - ; lda theChar - ldy entryLen ; how many characters already entered - cpy textLen ; vs how many can be entered - bcs loop ; already full, don't accept - sta (zaEntryL), y ; and write this character there - inc entryLen ; and increase the length entered -goShow: - sec ; on carry set, not done - rts - -erase: - ldy entryLen ; get how many characters have been entered - beq loop ; if none then ignore the backspace key - dec entryLen ; 1 less character entered - dey - lda #95 ; load the underscore - sta (zaEntryL), y ; stomp the last character with the underscore - bne goShow ; redraw the screen - -enter: - clc - rts - -.endproc \ No newline at end of file diff --git a/src/apple2/variables.inc b/src/apple2/variables.inc deleted file mode 100644 index d7fcae2..0000000 --- a/src/apple2/variables.inc +++ /dev/null @@ -1,66 +0,0 @@ -;----------------------------------------------------------------------------- -; variables.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "DATA" - -;----------------------------------------------------------------------------- -; Player specific variables -rsStart: ; runtime stats "struct". lives MUST be 1st -lives: .res 1 ; Chances the player gets (decimal mode), indexed by activePlayer -score: .res 3 ; activePlayer's score is copied here for gameplay -stage: .res 1 ; offset to stages in worldDataStart - needed for reset -direction: .res 1 ; 0 = right, 1 = left (fly reverse through level) -makeMonster: .res NUM_STAGES ; 1 in stage offset lookup turns missiles into monsters -rsEnd: - -playerStats: .res ((rsEnd-rsStart) * 2) ; 2 copies of stats, for p1 and p2 is 2p game - -;----------------------------------------------------------------------------- -; High scores table saved to disc -scoresTable: -highScores: -highScore1: .res 3 -highScore2: .res 3 -highScore3: .res 3 -highScore4: .res 3 -highScore5: .res 3 -highScoresEnd: - -textHS: -textHighScore1: .asciiz "123456" -textHighScore2: .asciiz "123456" -textHighScore3: .asciiz "123456" -textHighScore4: .asciiz "123456" -textHighScore5: .asciiz "123456" -textHSEnd: -scoresTableEnd: - -;----------------------------------------------------------------------------- -; user facing text area -textStage: .asciiz "1" -textPlayerNum: .asciiz "1" -textNumber: .asciiz "1234567" ; score display 10x score - extra digit needed -textDangerBar: .asciiz "123" -textEnd: - -textFileName: .asciiz "PENEWORLD01" ; default file name -textFilePad: .asciiz "" ; This makes the null terminator on textFileName viable and a 12 char filename -textFileNameEnd: -szHex: .asciiz " " - -;----------------------------------------------------------------------------- -; per "run" buffers -bombX: .res NUM_BOMBS ; 2 bombs allowed, their x values -bombY: .res NUM_BOMBS ; Y values for 2 bombs (0=available) -bombDir: .res NUM_BOMBS ; direction of travel (and thus sprite) -worldTBuffer: .res BUFLENGTH ; holds the world bottom height -worldBBuffer: .res BUFLENGTH ; holds the world top height -enemyBuffer: .res BUFLENGTH ; holds enemy sprite draw data -enemyHgtBuffer: .res BUFLENGTH ; holds enemy sprite draw height data -bulletsBuffer: .res BUFLENGTH ; holds the bullet heights (0=no bullet) -explosionBuffer: .res BUFLENGTH ; holds the explosion heights (0=no explosion) diff --git a/src/apple2/zpvars.inc b/src/apple2/zpvars.inc deleted file mode 100644 index 1fb9c13..0000000 --- a/src/apple2/zpvars.inc +++ /dev/null @@ -1,76 +0,0 @@ -;----------------------------------------------------------------------------- -; zpvars.inc -; Part of penetrator, the zx spectrum game, made for Apple II -; -; Stefan Wessels, 2019 -; This is free and unencumbered software released into the public domain. - -;----------------------------------------------------------------------------- -.segment "ZEROPAGE" - -;----------------------------------------------------------------------------- -; zero page variables -zWorldPtr: .res 2 ; where data is next read from the world stream -zVramH: .res 1 ; for HRG writes, points at the Hi of the back bank RAM -zScreenCol: .res 1 ; used for drawing - the column to draw -zEnemyCol: .res 1 ; used for enemies - the column to process -zCollision: .res 1 ; drawSprite will put a 1 in when there's a write collision -tempBlock: .res 22 ; used by different routines that need local storage - -;----------------------------------------------------------------------------- -; zero page constants -; Bit patterns for the bit instruction -Bit1Mask: .res 1 -Bit2Mask: .res 1 -Bit3Mask: .res 1 -Bit4Mask: .res 1 -Bit5Mask: .res 1 -Bit6Mask: .res 1 -Bit7Mask: .res 1 -Bit8Mask: .res 1 -Bit12Mask: .res 1 -Bit34Mask: .res 1 -Bit76Mask: .res 1 -Bit8432Mask: .res 1 -Bit8765Mask: .res 1 - -;----------------------------------------------------------------------------- -; Game variables -numPlayers: .res 1 ; [0|1] where 0 is a 1 player game, 1 = 2 player game -activePlayer: .res 1 ; 0 for player 1, 1 for player 2 -gameMode: .res 1 ; 0 for gameplay, 1 for trainer, 2 for edit - -; per "run" variables -playerShipX: .res 1 ; x position in columns -playerShipY: .res 1 ; y position in rows -terrainOrigin: .res 1 ; from 0 to XSize - where to start world draw on screen -stopScrolling: .res 1 ; 1 - world will not move (for death) -playerDead: .res 1 ; 0 - gamePlay flow, > 0 players dead -monsterCnt: .res 1 ; skip # missiles before turning one into a monster -inFlight: .res 2 ; count launched missiles for launch control -victory: .res 1 ; 0 = not done, 1 = hit the nuke so done with run -nextStage: .res 1 ; -1 nothing, 0 at next stage, >0 count down -bufferInsert: .res 1 ; index where data gets added to buffers (right hand of screen) -bufferDraw: .res 1 ; index that corresponds to draw start (usually col 0 of screen) -bulletIndex: .res 1 ; like bufferDraw but bullets "travel" in opposite direction -dangerTickCount: .res 1 ; how often a dot is added to the danger line, when the world moves -dangerTickIdx: .res 1 ; the index into the text that holds the danger line of dots -moveHorz: .res 1 ; keeps track of horizontal movement - only moves every 2nd frame -moveVert: .res 1 ; keeps track of vertical movement - moves 4 rows but over 2 frames - -; helper variables -updateHUD: .res 1 ; 0 - don't draw, 1+ - clean and redraw -flipFlop: .res 1 ; counter to advance explosion frames -backLayer: .res 1 ; [0|1] - Layer not shown to user *=(to be drawn to) -enemyHit: .res 1 ; the flags of the enemy destroyed in gameKillEnemy -enemyHitType: .res 1 ; 0 = nuke, 1 = missile, 2 = monster, 3 = radar, $ff - nothing -lastInput: .res 1 ; holds the value of the prev joystick frame -pause: .res 1 ; <> 0 when the game is paused -fireCoolDown: .res 1 ; decay to zero before fire allowed -pathPos: .res 1 ; index to start of file name in path - - -; audio variables -audioMask: .res 1 ; which audio "channels" are active (and with audioFrame) -audioFrame: .res 1 ; prioritized mask for sounds to make (msb to lsb) -audioExplFrame: .res 1 ; explosion frame index, for sound \ No newline at end of file