diff --git a/Makefile b/Makefile index bf603ea..a32e76b 100644 --- a/Makefile +++ b/Makefile @@ -1,99 +1,271 @@ -# -# 4sports Makefile -# assembles source code, optionally builds a disk image and mounts it -# note: Windows users should probably use winmake.bat instead -# -# original by Quinn Dunki on 2014-08-15 -# One Girl, One Laptop Productions -# http://www.quinndunki.com/blondihacks -# -# adapted by 4am on 2021-02-12 -# - -DISK=4sports.hdv -VOLUME=INSTANT.REPLAY - -# third-party tools required to build - -# https://sourceforge.net/projects/acme-crossass/ -ACME=acme - -# https://github.com/sicklittlemonkey/cadius -# version 1.4.0 or later -CADIUS=cadius - -# https://bitbucket.org/magli143/exomizer/wiki/Home -EXOMIZER=exomizer mem -q -P23 -lnone - -dsk: asm - cp res/blank.hdv build/"$(DISK)" >>build/log - cp res/_FileInformation.txt build/ >>build/log - $(CADIUS) ADDFILE build/"$(DISK)" "/$(VOLUME)/" "build/LAUNCHER.SYSTEM" >>build/log - rsync -aP res/PREFS.CONF build/PREFS.CONF >> build/log - bin/padto.sh 512 build/PREFS.CONF >>build/log - for f in res/TITLE res/COVER res/HELP res/GAMES.CONF res/ATTRACT.CONF res/FX.CONF res/DFX.CONF build/PREFS.CONF res/CREDITS res/HELPTEXT res/DECRUNCH res/JOYSTICK res/Finder.Data res/Finder.Root; do $(CADIUS) ADDFILE build/"$(DISK)" "/$(VOLUME)/" "$$f" >>build/log; done - bin/buildfileinfo.sh res/TITLE.HGR "06" "4000" >>build/log - bin/buildfileinfo.sh res/TITLE.DHGR "06" "4000" >>build/log - bin/buildfileinfo.sh res/ACTION.HGR "06" "3FF8" >>build/log - bin/buildfileinfo.sh res/ACTION.DHGR "06" "3FF8" >>build/log - bin/buildfileinfo.sh res/ACTION.GR "06" "6000" >>build/log - bin/buildfileinfo.sh res/ARTWORK.SHR "06" "1FF8" >>build/log - bin/buildfileinfo.sh res/ATTRACT "04" "8000" >>build/log - bin/buildfileinfo.sh res/SS "04" "4000" >>build/log - bin/buildfileinfo.sh res/ICONS "CA" "0000" >>build/log - for f in res/TITLE.HGR res/TITLE.DHGR res/ACTION.HGR res/ACTION.DHGR res/ACTION.GR res/ARTWORK.SHR res/ATTRACT res/SS res/DEMO res/ICONS; do rm -f "$$f"/.DS_Store; $(CADIUS) ADDFOLDER build/"$(DISK)" "/$(VOLUME)/$$(basename $$f)" "$$f" >>build/log; done - $(CADIUS) ADDFOLDER build/"$(DISK)" "/$(VOLUME)/FX" "build/FX" >>build/log - for f in res/dsk/*.po; do $(CADIUS) EXTRACTVOLUME "$${f}" build/X/ >> build/log; done - rm -f build/X/**/.DS_Store build/X/**/PRODOS* build/X/**/LOADER.SYSTEM* - $(CADIUS) CREATEFOLDER build/"$(DISK)" "/$(VOLUME)/X/" >>build/log - for f in build/X/*; do $(CADIUS) ADDFOLDER build/"$(DISK)" "/$(VOLUME)/X/$$(basename $$f)" "$$f"; done >>build/log - bin/buildfileinfo.sh build/PRELAUNCH "06" "0106" >>build/log - $(CADIUS) ADDFOLDER build/"$(DISK)" "/$(VOLUME)/PRELAUNCH" "build/PRELAUNCH" >>build/log - rsync -aP --exclude=STANDARD res/GAMEHELP build/ >>build/log - for f in res/TITLE.HGR/* res/TITLE.DHGR/*; do rsync --ignore-existing res/GAMEHELP/STANDARD build/GAMEHELP/$$(basename $$f); done - bin/buildfileinfo.sh build/GAMEHELP "04" "8000" >>build/log - $(CADIUS) ADDFOLDER build/"$(DISK)" "/$(VOLUME)/GAMEHELP" "build/GAMEHELP" >>build/log - bin/changebootloader.sh build/"$(DISK)" build/proboothd - -asm: asmproboot asmlauncher asmfx asmprelaunch - -asmproboot: md - $(ACME) -r build/proboothd.lst src/proboothd/proboothd.a - -asmlauncher: md - $(ACME) -DBUILDNUMBER=`git rev-list --count HEAD` src/4sports.a 2>build/relbase.log - $(ACME) -r build/4sports.lst -DBUILDNUMBER=`git rev-list --count HEAD` -DRELBASE=`cat build/relbase.log | grep "RELBASE =" | cut -d"=" -f2 | cut -d"(" -f2 | cut -d")" -f1` src/4sports.a - -asmfx: md - for f in src/fx/*.a; do grep "^\!to" $${f} >/dev/null && $(ACME) $${f} >> build/log || true; done - bin/buildfileinfo.sh build/FX "06" "6000" >>build/log - -asmprelaunch: md - for f in src/prelaunch/*.a; do grep "^\!to" $${f} >/dev/null && $(ACME) $${f} >> build/log; done - for f in res/TITLE.HGR/* res/TITLE.DHGR/*; do rsync --ignore-existing build/PRELAUNCH/STANDARD build/PRELAUNCH/$$(basename $$f); done - -chd: dsk - chdman createhd -c none -i build/"$(DISK)" -o build/"$(DISK)".chd >>build/log - -compress: md - for f in res/ACTION.HGR.UNCOMPRESSED/*; do o=res/ACTION.HGR/$$(basename $$f); [ -f "$$o" ] || ${EXOMIZER} "$$f"@0x4000 -o "$$o" >>build/log; done - for f in res/ACTION.DHGR.UNCOMPRESSED/*; do o=res/ACTION.DHGR/$$(basename $$f); [ -f "$$o" ] || ${EXOMIZER} "$$f"@0x4000 -o "$$o" >>build/log; done - for f in res/ARTWORK.SHR.UNCOMPRESSED/*; do o=res/ARTWORK.SHR/$$(basename $$f); [ -f "$$o" ] || ${EXOMIZER} "$$f"@0x2000 -o "$$o" >>build/log; done - -attract: compress - bin/check-attract-mode.sh - bin/generate-mini-attract-mode.sh - -mount: dsk - osascript bin/V2Make.scpt "`pwd`" bin/4sports.vii build/"$(DISK)" - -md: - mkdir -p build/X build/FX build/PRELAUNCH build/GAMEHELP - touch build/log - -clean: - rm -rf build/ || rm -rf build - -all: clean dsk mount - -al: all +# +# 4cade Makefile +# assembles source code, optionally builds a disk image and mounts it +# note: Windows users should probably use winmake.bat instead +# +# original by Quinn Dunki on 2014-08-15 +# One Girl, One Laptop Productions +# http://www.quinndunki.com/blondihacks +# +# adapted by 4am on 2018-08-19 +# + +DISK=4sports.hdv +VOLUME=INSTANT.REPLAY + +# third-party tools required to build + +# https://sourceforge.net/projects/acme-crossass/ +# version 0.96.3 or later +ACME=acme + +# https://github.com/mach-kernel/cadius +# version 1.4.0 or later +CADIUS=cadius + +# https://www.gnu.org/software/parallel/ +PARALLEL=parallel + +# https://python.org/ +PYTHON=python3 + +# https://bitbucket.org/magli143/exomizer/wiki/Home +# version 3.1.0 or later +EXOMIZER=exomizer mem -q -P23 -lnone + +dsk: index asmproboot asmlauncher + cp res/blank.hdv build/"$(DISK)" + cp res/_FileInformation.txt build/ + $(CADIUS) ADDFILE build/"$(DISK)" "/$(VOLUME)/" build/LAUNCHER.SYSTEM -C >>build/log + cp res/PREFS.CONF build/PREFS.CONF + bin/padto.sh build/PREFS.CONF +# +# create _FileInformation.txt files for subdirectories +# + bin/buildfileinfo.sh res/ICONS "CA" "0000" + bin/buildfileinfo.sh build/FX "06" "6000" + cp src/prelaunch/_FileInformation.txt build/PRELAUNCH/ +# +# add everything to the disk +# + for f in \ + build/TOTAL.DATA \ + build/PREFS.CONF \ + res/Finder.Data \ + res/Finder.Root; do \ + $(CADIUS) ADDFILE build/"$(DISK)" "/$(VOLUME)/" "$$f" -C >>build/log; \ + done + for f in \ + res/DEMO \ + res/TITLE.ANIMATED \ + res/ICONS \ + build/FX \ + build/PRELAUNCH; do \ + rm -f "$$f"/.DS_Store; \ + $(CADIUS) ADDFOLDER build/"$(DISK)" "/$(VOLUME)/$$(basename $$f)" "$$f" -C >>build/log; \ + done + for i in 1 2 3 4 5 6; do \ + $(CADIUS) RENAMEFILE build/"$(DISK)" "/$(VOLUME)/DEMO/SPCARTOON.$${i}$${i}" "SPCARTOON.$${i}." >>build/log; \ + done + $(PARALLEL) '$(CADIUS) EXTRACTVOLUME {} build/X/ >>build/log' ::: res/dsk/*.po + rm -f build/X/**/.DS_Store build/X/**/PRODOS* build/X/**/LOADER.SYSTEM* + $(CADIUS) CREATEFOLDER build/"$(DISK)" "/$(VOLUME)/X/" -C >>build/log + for f in build/X/*; do \ + $(CADIUS) ADDFOLDER build/"$(DISK)" "/$(VOLUME)/X/$$(basename $$f)" "$$f" -C >>build/log; \ + done + bin/changebootloader.sh build/"$(DISK)" build/proboothd + +index: preconditions md asmfx asmprelaunch compress +# +# precompute binary data structure for mega-attract mode configuration file +# + [ -f build/index ] || (bin/buildokvs.sh < res/ATTRACT.CONF > build/ATTRACT.IDX) +# +# precompute binary data structure and substitute special characters +# in game help and other all-text pages +# + [ -f build/index ] || (bin/converthelp.sh res/HELPTEXT build/HELPTEXT) + [ -f build/index ] || (bin/converthelp.sh res/CREDITS build/CREDITS) + [ -f build/index ] || $(PARALLEL) 'bin/converthelp.sh "{}" "build/GAMEHELP/{/}"' ::: res/GAMEHELP/* +# +# create a version of GAMES.CONF without comments or blank lines +# + [ -f build/index ] || (awk '!/^$$|^#/' < res/GAMES.CONF > build/GAMES.CONF) +# +# create a list of all game filenames, without metadata or display names, sorted by game filename +# + [ -f build/index ] || (awk -F, '/,/ { print $$2 }' < build/GAMES.CONF | awk -F= '{ print $$1 }' | sort > build/GAMES.SORTED) +# +# precompute indexed files for prelaunch +# note: prelaunch must be first in TOTAL.DATA due to a hack in LoadStandardPrelaunch +# note 2: these can not be padded because they are loaded at $0106 and padding would clobber the stack +# + [ -f build/index ] || (bin/buildindexedfile.sh build/TOTAL.DATA build/PRELAUNCH.INDEXED < build/GAMES.SORTED > build/PRELAUNCH.IDX) +# +# precompute indexed files for HGR & DHGR titles +# note: these are not padded because they are all an exact block-multiple anyway +# + [ -f build/index ] || bin/padto.sh build/TOTAL.DATA + [ -f build/index ] || ((for f in res/TITLE.HGR/*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/TITLE.HGR build/HGR.TITLES.LOG > build/TITLE.IDX) + [ -f build/index ] || ((for f in res/TITLE.DHGR/*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/TITLE.DHGR build/DHGR.TITLES.LOG > build/DTITLE.IDX) + [ -f build/index ] || bin/addfile.sh res/COVER build/TOTAL.DATA > src/index/res.cover.idx.a + [ -f build/index ] || bin/addfile.sh res/TITLE build/TOTAL.DATA > src/index/res.title.idx.a + [ -f build/index ] || bin/addfile.sh res/HELP build/TOTAL.DATA > src/index/res.help.idx.a +# +# precompute indexed files for game help +# note: these can be padded because they're loaded into $800 at a time when $800..$1FFF is clobber-able +# + [ -f build/index ] || (bin/buildindexedfile.sh -p -a build/TOTAL.DATA build/GAMEHELP < build/GAMES.SORTED > build/GAMEHELP.IDX) +# +# precompute indexed files for slideshows +# note: these can be padded because they're loaded into $800 at a time when $800..$1FFF is clobber-able +# + [ -f build/index ] || $(PARALLEL) '[ $$(echo "{/}" | cut -c-3) = "ACT" ] && bin/buildslideshow.sh -d build/GAMES.CONF < "{}" > "build/SS/{/}" || bin/buildslideshow.sh build/GAMES.CONF < "{}" > "build/SS/{/}"' ::: res/SS/* + [ -f build/index ] || ((for f in build/SS/*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -p -a build/TOTAL.DATA build/SS > build/SLIDESHOW.IDX) + [ -f build/index ] || $(PARALLEL) 'bin/buildokvs.sh < "{}" > "build/ATTRACT/{/}"' ::: res/ATTRACT/* + [ -f build/index ] || ((for f in build/ATTRACT/[ABCDEFGHIJKLMNOP]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -p -a build/TOTAL.DATA build/ATTRACT > build/MINIATTRACT0.IDX) + [ -f build/index ] || ((for f in build/ATTRACT/[QRSTUVWXYZ]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -p -a build/TOTAL.DATA build/ATTRACT > build/MINIATTRACT1.IDX) +# +# precompute indexed files for graphic effects +# note: these can be padded because they're loaded into $6000 at a time when $6000..$BEFF is clobber-able +# + [ -f build/index ] || (bin/buildindexedfile.sh -p -a build/TOTAL.DATA build/FX.INDEXED < res/FX.CONF > build/FX.IDX) + [ -f build/index ] || (bin/buildindexedfile.sh -p -a build/TOTAL.DATA build/FX.INDEXED < res/DFX.CONF > build/DFX.IDX) + [ -f build/index ] || (bin/buildindexedfile.sh -p -a build/TOTAL.DATA build/FX.INDEXED < res/SFX.CONF > build/SFX.IDX) +# +# precompute indexed files for HGR & DHGR action screenshots +# note: these can not be padded because they are compressed and the decompressor needs the exact size +# + [ -f build/index ] || ((for f in res/ACTION.HGR/[ABCD]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.HGR > build/HGR0.IDX) + [ -f build/index ] || ((for f in res/ACTION.HGR/[EFGH]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.HGR > build/HGR1.IDX) + [ -f build/index ] || ((for f in res/ACTION.HGR/[IJKL]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.HGR > build/HGR2.IDX) + [ -f build/index ] || ((for f in res/ACTION.HGR/[MNOP]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.HGR > build/HGR3.IDX) + [ -f build/index ] || ((for f in res/ACTION.HGR/[QRST]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.HGR > build/HGR4.IDX) + [ -f build/index ] || ((for f in res/ACTION.HGR/[UVWX]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.HGR > build/HGR5.IDX) + [ -f build/index ] || ((for f in res/ACTION.HGR/[YZ]*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.HGR > build/HGR6.IDX) + [ -f build/index ] || ((for f in res/ACTION.DHGR/*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ACTION.DHGR > build/DHGR.IDX) +# +# precompute indexed files for GR and DGR action screenshots +# note: these can be padded because they are not compressed +# + [ -f build/index ] || ((for f in res/ACTION.GR/*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a -p build/TOTAL.DATA res/ACTION.GR > build/GR.IDX) + [ -f build/index ] || ((for f in res/ACTION.DGR/*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a -p build/TOTAL.DATA res/ACTION.DGR > build/DGR.IDX) +# +# precompute indexed files for SHR artwork +# note: these can not be padded because they are compressed and the decompressor needs the exact size +# + [ -f build/index ] || ((for f in res/ARTWORK.SHR/*; do echo "$$(basename $$f)"; done) | bin/buildindexedfile.sh -a build/TOTAL.DATA res/ARTWORK.SHR > build/ARTWORK.IDX) +# +# create search indexes for each variation of (game-requires-joystick) X (game-requires-128K) +# in the form of OKVS data structures, plus game counts in the form of source files +# + [ -f build/index ] || $(PARALLEL) ::: \ + '(grep "^00" < build/GAMES.CONF | bin/buildsearch.sh src/index/count00.a build/HGR.TITLES.LOG /dev/null > build/SEARCH00.IDX)' \ + '(grep "^0" < build/GAMES.CONF | bin/buildsearch.sh src/index/count01.a build/HGR.TITLES.LOG build/DHGR.TITLES.LOG > build/SEARCH01.IDX)' \ + '(grep "^.0" < build/GAMES.CONF | bin/buildsearch.sh src/index/count10.a build/HGR.TITLES.LOG /dev/null > build/SEARCH10.IDX)' \ + '(bin/buildsearch.sh src/index/count11.a build/HGR.TITLES.LOG build/DHGR.TITLES.LOG < build/GAMES.CONF > build/SEARCH11.IDX)' +# +# add IDX files to the combined index file and generate +# the index records that callers use to reference them +# + [ -f build/index ] || bin/addfile.sh build/SEARCH00.IDX build/TOTAL.DATA > src/index/search00.idx.a + [ -f build/index ] || bin/addfile.sh res/CACHE00.IDX build/TOTAL.DATA > src/index/cache00.idx.a + [ -f build/index ] || bin/addfile.sh build/SEARCH01.IDX build/TOTAL.DATA > src/index/search01.idx.a + [ -f build/index ] || bin/addfile.sh res/CACHE01.IDX build/TOTAL.DATA > src/index/cache01.idx.a + [ -f build/index ] || bin/addfile.sh build/SEARCH10.IDX build/TOTAL.DATA > src/index/search10.idx.a + [ -f build/index ] || bin/addfile.sh res/CACHE10.IDX build/TOTAL.DATA > src/index/cache10.idx.a + [ -f build/index ] || bin/addfile.sh build/SEARCH11.IDX build/TOTAL.DATA > src/index/search11.idx.a + [ -f build/index ] || bin/addfile.sh res/CACHE11.IDX build/TOTAL.DATA > src/index/cache11.idx.a + [ -f build/index ] || bin/addfile.sh build/PRELAUNCH.IDX build/TOTAL.DATA > src/index/prelaunch.idx.a + [ -f build/index ] || bin/addfile.sh build/ATTRACT.IDX build/TOTAL.DATA > src/index/attract.idx.a + [ -f build/index ] || bin/addfile.sh build/FX.IDX build/TOTAL.DATA > src/index/fx.idx.a + [ -f build/index ] || bin/addfile.sh build/DFX.IDX build/TOTAL.DATA > src/index/dfx.idx.a + [ -f build/index ] || bin/addfile.sh build/SFX.IDX build/TOTAL.DATA > src/index/sfx.idx.a + [ -f build/index ] || bin/addfile.sh build/GAMEHELP.IDX build/TOTAL.DATA > src/index/gamehelp.idx.a + [ -f build/index ] || bin/addfile.sh build/SLIDESHOW.IDX build/TOTAL.DATA > src/index/slideshow.idx.a + [ -f build/index ] || bin/addfile.sh build/MINIATTRACT0.IDX build/TOTAL.DATA > src/index/miniattract0.idx.a + [ -f build/index ] || bin/addfile.sh build/MINIATTRACT1.IDX build/TOTAL.DATA > src/index/miniattract1.idx.a + [ -f build/index ] || bin/addfile.sh build/TITLE.IDX build/TOTAL.DATA > src/index/title.idx.a + [ -f build/index ] || bin/addfile.sh build/DTITLE.IDX build/TOTAL.DATA > src/index/dtitle.idx.a + [ -f build/index ] || bin/addfile.sh build/HGR0.IDX build/TOTAL.DATA > src/index/hgr0.idx.a + [ -f build/index ] || bin/addfile.sh build/HGR1.IDX build/TOTAL.DATA > src/index/hgr1.idx.a + [ -f build/index ] || bin/addfile.sh build/HGR2.IDX build/TOTAL.DATA > src/index/hgr2.idx.a + [ -f build/index ] || bin/addfile.sh build/HGR3.IDX build/TOTAL.DATA > src/index/hgr3.idx.a + [ -f build/index ] || bin/addfile.sh build/HGR4.IDX build/TOTAL.DATA > src/index/hgr4.idx.a + [ -f build/index ] || bin/addfile.sh build/HGR5.IDX build/TOTAL.DATA > src/index/hgr5.idx.a + [ -f build/index ] || bin/addfile.sh build/HGR6.IDX build/TOTAL.DATA > src/index/hgr6.idx.a + [ -f build/index ] || bin/addfile.sh build/DHGR.IDX build/TOTAL.DATA > src/index/dhgr.idx.a + [ -f build/index ] || bin/addfile.sh build/GR.IDX build/TOTAL.DATA > src/index/gr.idx.a + [ -f build/index ] || bin/addfile.sh build/DGR.IDX build/TOTAL.DATA > src/index/dgr.idx.a + [ -f build/index ] || bin/addfile.sh build/ARTWORK.IDX build/TOTAL.DATA > src/index/artwork.idx.a +# +# add additional miscellaneous files +# + [ -f build/index ] || bin/addfile.sh build/COVERFADE build/TOTAL.DATA > src/index/coverfade.idx.a + [ -f build/index ] || bin/addfile.sh build/GR.FIZZLE build/TOTAL.DATA > src/index/gr.fizzle.idx.a + [ -f build/index ] || bin/addfile.sh build/DGR.FIZZLE build/TOTAL.DATA > src/index/dgr.fizzle.idx.a + [ -f build/index ] || bin/addfile.sh build/HELPTEXT build/TOTAL.DATA > src/index/helptext.idx.a + [ -f build/index ] || bin/addfile.sh build/CREDITS build/TOTAL.DATA > src/index/credits.idx.a + [ -f build/index ] || bin/addfile.sh res/DECRUNCH build/TOTAL.DATA > src/index/decrunch.idx.a + [ -f build/index ] || bin/addfile.sh res/JOYSTICK build/TOTAL.DATA > src/index/joystick.idx.a + touch build/index + +asmlauncher: md + $(ACME) -DBUILDNUMBER=`git rev-list --count HEAD` src/4cade.a 2>build/relbase.log + $(ACME) -r build/4cade.lst -DBUILDNUMBER=`git rev-list --count HEAD` -DRELBASE=`cat build/relbase.log | grep "RELBASE =" | cut -d"=" -f2 | cut -d"(" -f2 | cut -d")" -f1` src/4cade.a + +asmfx: preconditions md + $(PARALLEL) 'if grep -q "^!to" "{}"; then $(ACME) "{}"; fi' ::: src/fx/*.a + +asmprelaunch: preconditions md + $(PARALLEL) 'if grep -q "^!to" "{}"; then $(ACME) "{}"; fi' ::: src/prelaunch/*.a + +asmproboot: md + $(ACME) -r build/proboothd.lst src/proboothd/proboothd.a + +compress: preconditions md + $(PARALLEL) '[ -f "res/ACTION.HGR/{/}" ] || ${EXOMIZER} "{}"@0x4000 -o "res/ACTION.HGR/{/}"' ::: res/ACTION.HGR.UNCOMPRESSED/* + $(PARALLEL) '[ -f "res/ACTION.DHGR/{/}" ] || ${EXOMIZER} "{}"@0x4000 -o "res/ACTION.DHGR/{/}"' ::: res/ACTION.DHGR.UNCOMPRESSED/* + $(PARALLEL) '[ -f "res/ARTWORK.SHR/{/}" ] || ${EXOMIZER} "{}"@0x2000 -o "res/ARTWORK.SHR/{/}"' ::: res/ARTWORK.SHR.UNCOMPRESSED/* + $(PARALLEL) '[ -f "res/TITLE.HGR/{/}" ] || bin/packhgrfile.py "{}" "res/TITLE.HGR/{/}"' ::: res/TITLE.HGR.UNPACKED/* + +# +# |attract| must be called separately because it is slow and +# only needs to be run when a new game or demo is added. +# It create files in the repository which can then be checked in. +# +attract: compress + bin/check-attract-mode.sh + bin/generate-mini-attract-mode.sh + +cache: preconditions md + $(PARALLEL) ::: \ + 'awk -F= '"'"'/^00/ { print $$2 }'"'"' < res/GAMES.CONF | bin/buildcache.py > build/cache00.a' \ + 'awk -F= '"'"'/^0/ { print $$2 }'"'"' < res/GAMES.CONF | bin/buildcache.py > build/cache01.a' \ + 'awk -F= '"'"'/^.0/ { print $$2 }'"'"' < res/GAMES.CONF | bin/buildcache.py > build/cache10.a' \ + 'awk -F= '"'"'!/^$$|^#|^\[/ { print $$2 }'"'"' < res/GAMES.CONF | bin/buildcache.py > build/cache11.a' + $(PARALLEL) ::: \ + '$(ACME) -o res/CACHE00.IDX build/cache00.a' \ + '$(ACME) -o res/CACHE01.IDX build/cache01.a' \ + '$(ACME) -o res/CACHE10.IDX build/cache10.a' \ + '$(ACME) -o res/CACHE11.IDX build/cache11.a' + +mount: dsk + osascript bin/V2Make.scpt "`pwd`" bin/4cade.vii build/"$(DISK)" + +md: + mkdir -p build/X build/FX.INDEXED build/FX build/PRELAUNCH.INDEXED build/PRELAUNCH build/ATTRACT build/SS build/GAMEHELP + touch build/log + +clean: + rm -rf build/ || rm -rf build + +preconditions: + @$(ACME) --version | grep -q "ACME, release" || (echo "ACME is not installed" && exit 1) + @$(CADIUS) | grep -q "cadius v" || (echo "Cadius is not installed" && exit 1) + @$(PARALLEL) --version | grep -q "GNU" || (echo "GNU Parallel is not installed" && exit 1) + @$(PYTHON) --version | grep -q "Python 3" || (echo "Python 3 is not installed" && exit 1) + +all: clean dsk mount + +al: all diff --git a/bin/4sports.vii b/bin/4cade.vii similarity index 100% rename from bin/4sports.vii rename to bin/4cade.vii diff --git a/bin/addfile.js b/bin/addfile.js new file mode 100644 index 0000000..42ef5b5 --- /dev/null +++ b/bin/addfile.js @@ -0,0 +1,5 @@ +a=new ActiveXObject("scripting.filesystemobject") +offset=a.getfile("BUILD\\TOTAL.DATA").size +new ActiveXObject("wscript.shell").run('cmd /c copy /b /y BUILD\\TOTAL.DATA + ' + WScript.Arguments(0) + ' BUILD\\TOTAL.DATA', 0, 1) +size=a.getfile(WScript.Arguments(0)).size +a.createtextfile(WScript.Arguments(1)).write(";\r\n; Index record for " + WScript.Arguments(0).replace(/\\/, "/") + "\r\n;\r\n; This file is automatically generated\r\n;\r\n !byte 0\r\n !be24 " + offset + "\r\n !le16 " + " ".substr(0, 8 - size.toString().length) + size + "\r\n") diff --git a/bin/addfile.sh b/bin/addfile.sh new file mode 100755 index 0000000..3b70c79 --- /dev/null +++ b/bin/addfile.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# parameters +# 1 - input file +# 2 - output filename for data file +# stdout - source code of index record + +touch "$2" +size=$(wc -c < "$1") +offset=$(wc -c < "$2") +cat "$1" >> "$2" +echo ";" +echo "; Index record for $1" +echo ";" +echo "; This file is automatically generated" +echo ";" +echo " !byte 0" +echo " !be24 $offset" +echo " !le16 $size" diff --git a/bin/buildcache.js b/bin/buildcache.js new file mode 100644 index 0000000..37df818 --- /dev/null +++ b/bin/buildcache.js @@ -0,0 +1,60 @@ +a = new ActiveXObject("scripting.filesystemobject") +b = a.opentextfile("res\\GAMES.CONF") +f00 = a.createtextfile("build\\filter00.txt") +f01 = a.createtextfile("build\\filter01.txt") +f10 = a.createtextfile("build\\filter10.txt") +f11 = a.createtextfile("build\\filter11.txt") + +while (!b.atendofstream) +{ + c = b.readline() + + d = c.indexOf("#") + + if (d >= 0) + { + c = c.substr(0, d) + } + + if (c.indexOf("[eof]") >= 0) + { + break + } + + if (c.length == 0) + { + continue + } + + if (c.substr(0, 2) == "00") + { + f00.writeline(c.substr(c.indexOf("=") + 1)) + } + + if (c.substr(0, 1) == "0") + { + f01.writeline(c.substr(c.indexOf("=") + 1)) + } + + if (c.substr(1, 1) == "0") + { + f10.writeline(c.substr(c.indexOf("=") + 1)) + } + + f11.writeline(c.substr(c.indexOf("=") + 1)) +} + +f11.close() +f10.close() +f01.close() +f00.close() + +x = new ActiveXObject("wscript.shell") +x.run('cmd /c %python% bin\\buildcache.py < build\\filter00.txt > build\\cache00.a', 0, 1) +x.run('cmd /c %python% bin\\buildcache.py < build\\filter01.txt > build\\cache01.a', 0, 1) +x.run('cmd /c %python% bin\\buildcache.py < build\\filter10.txt > build\\cache10.a', 0, 1) +x.run('cmd /c %python% bin\\buildcache.py < build\\filter11.txt > build\\cache11.a', 0, 1) +x.run('cmd /c %acme% -o res\\CACHE00.IDX build\\cache00.a', 0, 1) +x.run('cmd /c %acme% -o res\\CACHE01.IDX build\\cache01.a', 0, 1) +x.run('cmd /c %acme% -o res\\CACHE10.IDX build\\cache10.a', 0, 1) +x.run('cmd /c %acme% -o res\\CACHE11.IDX build\\cache11.a', 0, 1) diff --git a/bin/buildcache.py b/bin/buildcache.py new file mode 100755 index 0000000..776e8e8 --- /dev/null +++ b/bin/buildcache.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 + +from collections import OrderedDict +from pprint import pprint +from string import ascii_lowercase +from sys import stdin + +def score(inputbuffer, displayname): + if len(inputbuffer) > len(displayname): + return 0, False + likely = True + startat = 0 + score = 0 + for c in inputbuffer: + x = 10 + y = displayname[startat:].find(c) + if y < 0: + return 0, False + if y == 0: + x = 80 + elif (startat > 0) and (displayname[startat+y-1] == " "): + x = 90 + else: + likely = False + score += x + startat += y + 1 + score = int(score/len(displayname) + (score/len(inputbuffer)) + 0.99)/2 + if (inputbuffer[0] == displayname[0]) and (score < 85): + score += 15 + return score, likely + +def best(keys, games): + gameindex = 0 + bestscore = -1 + bestindex = -1 + bestlikely = False + for game in games: + gamescore, likely = score(keys, game) + if (gamescore > bestscore): + bestscore = gamescore + bestindex = gameindex + bestlikely = likely + gameindex += 1 + if not bestlikely: + return 0 + return bestindex + +def main(): + games = [line.strip().lower() for line in stdin] + cache = OrderedDict() + for a in ascii_lowercase: + index1 = best(a, games) + if not index1: continue + cache[a] = OrderedDict() + cache[a][" "] = index1 + for b in ascii_lowercase: + index2 = best(a+b, games) + if not index2: continue + cache[a][b] = OrderedDict() + if index2 != index1: + cache[a][b][" "] = index2 + for c in ascii_lowercase: + index3 = best(a+b+c, games) + if not index3: continue + cache[a][b][c] = OrderedDict() + if index3 != index2: + cache[a][b][c][" "] = index3 + for d in ascii_lowercase: + index4 = best(a+b+c+d, games) + if not index4: continue + if index4 != index3: + cache[a][b][c][d] = index4 + if not cache[a][b][c]: + del cache[a][b][c] + if not cache[a][b]: + del cache[a][b] + if not cache[a]: + del cache[a] + + print('*=$A000') + for a in cache: + print(f' !text "{a}"') + if type(cache[a]) == int: + print(f' !word {cache[a]}') + else: + print(f' !word _{a}') + print(' !byte 0') + + for a in cache: + if type(cache[a]) == int: continue + print(f'_{a}') + for b in cache[a]: + print(f' !text "{b}"') + if type(cache[a][b]) == int: + print(f' !word {cache[a][b]}') + else: + print(f' !word _{a}{b}') + print(' !byte 0') + + for a in cache: + if type(cache[a]) == int: continue + for b in cache[a]: + if type(cache[a][b]) == int: continue + print(f'_{a}{b}') + for c in cache[a][b]: + print(f' !text "{c}"') + if type(cache[a][b][c]) == int: + print(f' !word {cache[a][b][c]}') + else: + print(f' !word _{a}{b}{c}') + print(' !byte 0') + + for a in cache: + if type(cache[a]) == int: continue + for b in cache[a]: + if type(cache[a][b]) == int: continue + for c in cache[a][b]: + if type(cache[a][b][c]) == int: continue + print(f'_{a}{b}{c}') + for d in cache[a][b][c]: + print(f' !text "{d}"') + print(f' !word {cache[a][b][c][d]}') + print(' !byte 0') + +if __name__ == '__main__': + main() diff --git a/bin/builddisplaynames.js b/bin/builddisplaynames.js new file mode 100644 index 0000000..7d6eba9 --- /dev/null +++ b/bin/builddisplaynames.js @@ -0,0 +1,28 @@ +a = new ActiveXObject("scripting.filesystemobject") +b = a.opentextfile("build\\GAMES.CONF") +c = a.createtextfile("build\\DISPLAY.CONF") + +while (!b.atendofstream) +{ + d = b.readline() + + if (d.indexOf("[eof]") >= 0) + { + break + } + + if (d.indexOf("=") == -1) + { + e = d.indexOf(",") + 1 + f = d.substr(e).split(".") + + for (g = 0; g < f.length; g++) + { + f[g] = f[g].charAt(0) + f[g].substr(1).toLowerCase() + } + + d += "=" + f.join(" ").replace(" Ii", " II") + } + + c.writeline(d) +} diff --git a/bin/buildfileinfo.js b/bin/buildfileinfo.js index 4ca6bc1..27ad8de 100644 --- a/bin/buildfileinfo.js +++ b/bin/buildfileinfo.js @@ -9,4 +9,4 @@ for (b = new Enumerator(a.GetFolder(WScript.Arguments(0)).files); !b.atEnd(); b. } } fileinfo += "\r\n" + "_FileInformation.txt=Type(" + WScript.Arguments(1) + "),AuxType(" + WScript.Arguments(2) + "),Access(C3)\r\n" -a.createtextfile(WScript.Arguments(0)+"\\_FILEINFORMATION.TXT", 1).write(fileinfo) +a.createtextfile(WScript.Arguments(0)+"\\_FileInformation.txt", 1).write(fileinfo) diff --git a/bin/buildfx.js b/bin/buildfx.js new file mode 100644 index 0000000..066e9af --- /dev/null +++ b/bin/buildfx.js @@ -0,0 +1,53 @@ +a = new ActiveXObject("scripting.filesystemobject") +x = new ActiveXObject("wscript.shell") +fx_off = a.fileexists(WScript.Arguments(2)) ? a.getFile(WScript.Arguments(2)).size : 0 +x.run('cmd /c bin\\buildfxful.bat ' + WScript.Arguments(0) + ' ' + WScript.Arguments(2) + ' ' + WScript.Arguments(3), 0, 1) + +b = a.opentextfile(WScript.Arguments(0)) + +entries = [] + +while (!b.atendofstream) +{ + c = b.readline() + d = c.indexOf("#") + + if (d >= 0) + { + c = c.substr(0, d) + } + + d = c.indexOf("=") + + if (d >= 0) + { + c = c.substr(0, d) + } + + if (c.indexOf("[eof]") >= 0) + { + break + } + + if (c.length > 0) + { + entries.push(c) + } +} + +groups = "*=0\n" + "!le16 " + entries.length.toString() + ", 0\n" + +for (i = 0; i < entries.length; i++) +{ + groups += "!byte " + (1 + 1 + entries[i].length + 5).toString() + "\n" + "!byte " + entries[i].length.toString() + "\n" + "!text \"" + entries[i] + "\"\n" + "!be24 " + fx_off.toString() + "\n" + size = a.getfile(WScript.Arguments(3) + "\\" + entries[i]).size + // if offset+size does not cross a block boundary, use the size + // otherwise adjust size until it ends at the next block boundary to avoid a partial copy on the last block + groups += "!le16 " + ((Math.floor(fx_off / 512) == Math.floor((fx_off + size) / 512)) ? size : (((fx_off + size + 511) & -512) - fx_off)).toString() + "\n" + fx_off += size +} + +f = a.createtextfile("build\\fx.tmp") +f.write(groups) +f.close() +x.run('cmd /c %acme% -o ' + WScript.Arguments(1) + ' build\\fx.tmp', 0, 1) diff --git a/bin/buildfxful.bat b/bin/buildfxful.bat new file mode 100644 index 0000000..34db8cc --- /dev/null +++ b/bin/buildfxful.bat @@ -0,0 +1,14 @@ +@echo off +setlocal enabledelayedexpansion +for /f "tokens=*" %%a in (%1) do ( +set f=0 +call :x %%a +if !f!==2 goto:eof +if !f!==0 1>nul copy /b /y %2+%3\%%a %2 +) +goto:eof + +:x +set a=%1 +if not x%a:#=%==x%a% set/a f=1 +if not x%a:[=%==x%a% set/a f=2 diff --git a/bin/buildindexedfile.sh b/bin/buildindexedfile.sh new file mode 100755 index 0000000..bb82191 --- /dev/null +++ b/bin/buildindexedfile.sh @@ -0,0 +1,88 @@ +#!/bin/bash + +# flags +# -a append to data file (default off = truncate) +# -p pad sizes within data file to next block size (default off) + +# parameters +# stdin - input containing list of effects (probably FX.CONF or DFX.CONF) +# stdout - binary OKVS data structure +# 1 - output filename for data file +# 2 - input directory of files to merge into data file +# 3 - (optional) output filename for log of key,offset,size + +pad=false +append=false +standardoffset=0 +standardsize=0 +while getopts ":ap" opt; do + case $opt in + a) append=true + ;; + p) pad=true + ;; + esac +done +shift $((OPTIND-1)) + +if [ "$append" = false ]; then + rm -f "$1" +fi +touch "$1" + +if [ "${#3}" -ne "0" ]; then + rm -f "$3" + touch "$3" +fi + +# if there is a file called "STANDARD" in the input directory, add it now +# because we will reuse it for any files that don't exist +if [ -f "$2"/STANDARD ]; then + standardoffset=$(wc -c < "$1") + standardsize=$(wc -c < "$2/STANDARD") + cat "$2"/STANDARD >> "$1" +fi + +# make temp file with list of lines that contain keys +records=$(mktemp) +tr -d "\r" | awk '!/^$|^#|^\[/' > "$records" + +# make temp assembly source file that represents the binary OKVS data structure +source=$(mktemp) +(echo "*=0" # dummy program counter for assembler + echo "!le16 $(wc -l <"$records"), 0" # OKVS header + while IFS="=" read -r key value; do + echo "!byte ${#key}+7" # OKVS record length + echo "!byte ${#key}" # OKVS key length + echo "!text \"$key\"" # OKVS key + if [ ! -e "$2/$key" ]; then # if file does not exist, use standard offset and size + offset="$standardoffset" + size="$standardsize" + else # otherwise calculate offset and size from file and options + offset=$(wc -c < "$1") + size=$(wc -c < "$2/$key") + if [ "$pad" = true ]; then + # If offset+size does not cross a block boundary, use file's true size. + # Otherwise, round up size to the next block boundary. + # This padding does not get added to the file; it is just an + # optimization to avoid a partial copy on the last block read. + if [ $(($offset / 512)) -ne $((($offset + $size) / 512)) ]; then + size=$(((($offset + $size + 511) & -512) - $offset)) + fi + fi + cat "$2/$key" >> "$1" # append this file to the end of the merged data file + fi + echo "!be24 $offset" + echo "!le16 $size" + [ "${#3}" -ne "0" ] && echo "$key,$offset,$size" >> "$3" + done < "$records") > "$source" + +# assemble temp source file into binary OKVS data structure, then output that +out=$(mktemp) +acme -o "$out" "$source" +cat "$out" + +# clean up +rm "$out" +rm "$source" +rm "$records" diff --git a/bin/buildokvs.js b/bin/buildokvs.js new file mode 100644 index 0000000..2b3105a --- /dev/null +++ b/bin/buildokvs.js @@ -0,0 +1,46 @@ +a = new ActiveXObject("scripting.filesystemobject") + +if (!a.fileexists(WScript.Arguments(1)) || a.getfile(WScript.Arguments(1)).datelastmodified < a.getFile(WScript.Arguments(0)).datelastmodified) +{ + b = a.opentextfile(WScript.Arguments(0)) + + entries = [] + + while (!b.atendofstream) + { + c = b.readline() + d = c.indexOf("#") + + if (d >= 0) + { + c = c.substr(0, d) + } + + if (c.indexOf("[eof]") >= 0) + { + break + } + + if (c.length > 0) + { + entries.push(c) + } + } + + source = a.createtextfile("build\\okvs.tmp") + source.writeline("*=0") + source.writeline("!le16 " + entries.length + ", 0") + + for (i = 0; i < entries.length; i++) + { + val = entries[i].indexOf("=") + source.writeline("!byte " + (entries[i].length - ((val >= 0) ? 1 : 0) + 3).toString()) + source.writeline("!byte " + ((val >= 0) ? val : entries[i].length).toString()) + source.writeline("!text \"" + ((val >= 0) ? entries[i].substr(0, val) : entries[i]) + "\"") + source.writeline("!byte " + ((val >= 0) ? (entries[i].length - (val + 1)) : 0).toString()) + source.writeline("!text \"" + ((val >= 0) ? (entries[i].substr(val + 1)) : "") + "\"") + } + + source.close() + new ActiveXObject("wscript.shell").run('cmd /c %acme% -o ' + WScript.Arguments(1) + ' build\\okvs.tmp', 0, 1) +} diff --git a/bin/buildokvs.sh b/bin/buildokvs.sh new file mode 100755 index 0000000..08d768e --- /dev/null +++ b/bin/buildokvs.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# make temp file with just the key/value pairs (strip blank lines, comments, eof marker) +records=$(mktemp) +tr -d "\r" | awk '!/^$|^#|^\[/' > "$records" + +# make temp assembly source file that represents the binary OKVS data structure +source=$(mktemp) +(echo "*=0" # dummy program counter for assembler + echo "!le16 $(wc -l <"$records"), 0" # OKVS header + while IFS="=" read -r key value; do + echo "!byte ${#key}+${#value}+3" # OKVS record length + echo "!byte ${#key}" # OKVS key length + echo "!text \"$key\"" # OKVS key + echo "!byte ${#value}" # OKVS value length + echo "!text \"$value\"" # OKVS value + done < "$records") > "$source" + +# assemble temp source file into binary OKVS data structure, then output that +out=$(mktemp) +acme -o "$out" "$source" +cat "$out" + +# clean up +rm "$out" +rm "$source" +rm "$records" diff --git a/bin/buildpre.js b/bin/buildpre.js new file mode 100644 index 0000000..94627a4 --- /dev/null +++ b/bin/buildpre.js @@ -0,0 +1,43 @@ +a = new ActiveXObject("scripting.filesystemobject") +b = a.opentextfile("build\\GAMES.SORTED") + +entries = [] + +while (!b.atendofstream) +{ + entries.push(b.readline()) +} + +osize = a.getfile(WScript.Arguments(0) + "\\STANDARD").size +pre_off = a.getfile(WScript.Arguments(2)).size + osize + +groups = "*=0\n" + "!le16 " + entries.length + ", 0\n" + +for (i = 0; i < entries.length; i++) +{ + c = a.getfile(WScript.Arguments(2)).size + size = osize + + if (a.fileexists(WScript.Arguments(0) + "\\" + entries[i])) + { + c = pre_off + size = a.getfile(WScript.Arguments(0) + "\\" + entries[i]).size + pre_off += size + } + + if (WScript.Arguments.length == 4) + { + // if offset+size does not cross a block boundary, use the size + // otherwise adjust size until it ends at the next block boundary to avoid a partial copy on the last block + size = ((Math.floor(c / 512) == Math.floor((c + size) / 512)) ? size : (((c + size + 511) & -512) - c)) + } + + groups += "!byte " + (1 + 1 + entries[i].length + 5) + "\n" + "!byte " + entries[i].length + "\n" + "!text \"" + entries[i] + "\"\n" + "!be24 " + c + "\n" + "!le16 " + size + "\n" +} + +f = a.createtextfile("build\\pre.tmp") +f.write(groups) +f.close() +x = new ActiveXObject("wscript.shell") +x.run('cmd /c %acme% -o ' + WScript.Arguments(1) + ' build\\pre.tmp', 0, 1) +x.run('cmd /c bin\\buildpreall.bat ' + WScript.Arguments(0) + ' ' + WScript.Arguments(2) + ' ' + WScript.Arguments(0) + '\\STANDARD', 0, 1) diff --git a/bin/buildpreall.bat b/bin/buildpreall.bat new file mode 100644 index 0000000..3f7b8ea --- /dev/null +++ b/bin/buildpreall.bat @@ -0,0 +1,3 @@ +@echo off +1>nul copy /y /b %2+%3 %2 +for /f "tokens=*" %%a in (build\GAMES.SORTED) do 1>nul copy /b /y %2+%1\%%a %2 diff --git a/bin/buildsearch.js b/bin/buildsearch.js new file mode 100644 index 0000000..ea092b3 --- /dev/null +++ b/bin/buildsearch.js @@ -0,0 +1,90 @@ +a = new ActiveXObject("scripting.filesystemobject") +x = new ActiveXObject("wscript.shell") +b = x.exec('findstr /b \"' + WScript.Arguments(0) + '\" build\\DISPLAY.CONF') + +entries = [] + +while (!b.stdout.atendofstream) +{ + c = b.stdout.readline() + d = c.indexOf("#") + + if (d >= 0) + { + c = c.substr(0, d) + } + + if (c.indexOf("[eof]") >= 0) + { + break + } + + if (c.length > 0) + { + entries.push(c) + } +} + +a.createtextfile(WScript.Arguments(1)).write(";\r\n; Game count\r\n;\r\n; This file is automatically generated\r\n;\r\n" + "!word " + " ".substr(0, 8 - entries.length.toString().length) + entries.length + "\r\n") + +source = a.createtextfile("build\\search.a") +source.writeline("*=$6000") +source.writeline("!le16 " + entries.length) +source.writeline("!word KeyLookup") + +hgrlog = a.opentextfile("build\\HGR.TITLES.LOG").readall().replace(/\r\n/, "\n") +dhgrlog = a.opentextfile("build\\DHGR.TITLES.LOG").readall().replace(/\r\n/, "\n") + +for (i = 0; i < entries.length; i++) +{ + bits = entries[i].indexOf(",") + dhgr = entries[i].substr(bits - 2, 1) + + if (WScript.Arguments(1).substr(WScript.Arguments(1).length - 3, 1) == "0") + { + dhgr = "0" + } + + cheat = entries[i].substr(bits - 1, 1) + eq = entries[i].indexOf("=") + key = ((eq >= 0) ? entries[i].substr(bits + 1, eq - bits - 1) : entries[i]) + value = ((eq >= 0) ? entries[i].substr(eq + 1) : "") + source.writeline("!byte " + (key.length + value.length + 10).toString()) + source.writeline("Key" + (i + 1).toString()) + source.writeline("!byte " + key.length) + source.writeline("!text \"" + key + "\"") + source.writeline("!byte " + value.length) + source.writeline("!text \"" + value + "\"") + source.writeline("!byte 1") + source.writeline("!byte " + ((dhgr * 128) + Number(cheat))) + + if (dhgr != 0) + { + dname = dhgrlog.indexOf("\n" + key + ",") + key.length + 2 + dpos = dhgrlog.substr(dname).indexOf(",") + dsize = dhgrlog.substr(dname + dpos + 1).indexOf("\n") + dsize = dhgrlog.substr(dname + dpos + 1, dsize) + dpos = dhgrlog.substr(dname, dpos) + } + else + { + dname = hgrlog.indexOf("\n" + key + ",") + key.length + 2 + dpos = hgrlog.substr(dname).indexOf(",") + dsize = hgrlog.substr(dname + dpos + 1).indexOf("\n") + dsize = hgrlog.substr(dname + dpos + 1, dsize) + dpos = hgrlog.substr(dname, dpos) + } + + source.writeline("!be24 " + dpos) + source.writeline("!le16 " + dsize) +} + +source.writeline("KeyLookup") + +for (i = 0; i < entries.length; i++) +{ + source.writeline("!word Key" + (i + 1)) +} + +source.close() +new ActiveXObject("wscript.shell").run('cmd /c %acme% -o ' + WScript.Arguments(2) + ' build\\search.a', 0, 1) diff --git a/bin/buildsearch.sh b/bin/buildsearch.sh new file mode 100755 index 0000000..9a651b2 --- /dev/null +++ b/bin/buildsearch.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +# parameters +# stdin - input containing list of game metadata, filename, display name (e.g. GAMES.CONF or some subset of it) +# stdout - binary OKVS data structure +# 1 - output filename for game count in assembler code format +# 2 - input filename of HGR titles, offsets, and sizes +# 3 - input filename of DHGR titles, offsets, and sizes + +# make temp file with just the key/value pairs (strip blank lines, comments, eof marker) +records=$(mktemp) +tr -d "\r" | awk '!/^$|^#|^\[/' > "$records" + +# read logs of offsets & sizes for HGR and DHGR titles +# that were generated by an earlier script +hgrlog=$(< "$2") +dhgrlog=$(< "$3") + +# generate source file with game count +(echo ";" + echo "; Game count" + echo ";" + echo "; This file is automatically generated" + echo ";" + echo "!word $(wc -l < "$records")") > "$1" + +# make temp assembly source file that represents the binary OKVS data structure +source=$(mktemp) +(echo '*=$6000' + echo "!le16 $(wc -l <"$records")" # OKVS header + echo "!word KeyLookup" + count=0 + while IFS="=" read -r key value; do + count=$((count+1)) + if [ -z "$dhgrlog" ]; then + dhgr="0" + else + dhgr=$(echo "$key" | cut -c3) # 'has DHGR title screen' flag (0 or 1) + fi + cheat=$(echo "$key" | cut -c4) # 'cheat category' (0..5) + key=$(echo "$key" | cut -d"," -f2) + if [ "$dhgr" -eq "0" ]; then + offset=$hgrlog + size=$hgrlog + else + offset=$dhgrlog + size=$dhgrlog + fi + offset=$(echo "$offset" | awk -F, '/^'"$key"',/ { print $2 }') + size=$(echo "$size" | awk -F, '/^'"$key"',/ { print $3 }') + echo "!byte ${#key}+${#value}+10" # OKVS record length + echo "Key${count}" + echo "!byte ${#key}" # OKVS key length + echo "!text \"$key\"" # OKVS key (filename) + echo "!byte ${#value}" # OKVS value length + echo "!text \"$value\"" # OKVS value (display name) + echo "!byte 1" + echo "!byte $((dhgr*128))+$cheat" + echo "!be24 $offset" + echo "!le16 $size" + done < "$records" + echo "KeyLookup" + for i in $(seq $count); do + echo "!word Key$i" + done +) > "$source" + +# assemble temp source file into binary OKVS data structure, then output that +out=$(mktemp) +acme -o "$out" "$source" +cat "$out" + +# clean up +rm "$out" +rm "$source" +rm "$records" diff --git a/bin/buildslideshow.js b/bin/buildslideshow.js new file mode 100644 index 0000000..8ecd9b0 --- /dev/null +++ b/bin/buildslideshow.js @@ -0,0 +1,57 @@ +a = new ActiveXObject("scripting.filesystemobject") + +if (!a.fileexists(WScript.Arguments(1)) || a.getfile(WScript.Arguments(1)).datelastmodified < a.getFile(WScript.Arguments(0)).datelastmodified) +{ + b = a.opentextfile(WScript.Arguments(0)) + + entries = [] + + while (!b.atendofstream) + { + c = b.readline() + d = c.indexOf("#") + + if (d >= 0) + { + c = c.substr(0, d) + } + + if (c.indexOf("[eof]") >= 0) + { + break + } + + if (c.length > 0) + { + entries.push(c) + } + } + + source = a.createtextfile("build\\okvs.tmp") + source.writeline("*=0") + source.writeline("!le16 " + entries.length + ", 0") + q = a.opentextfile("build\\DISPLAY.CONF").readall().replace(/\r\n/g, "\n") + + for (i = 0; i < entries.length; i++) + { + val = entries[i].indexOf("=") + name = ((val >= 0) ? entries[i].substr(val + 1) : entries[i]) + bits = q.indexOf("," + name + "=") + 1 + name = q.substr(bits + name.length + 1) + name = name.substr(0, name.indexOf("\n")) + needsjoystick = q.substr(bits - 5, 1) + needs128k = q.substr(bits - 4, 1) + displayname = ((WScript.Arguments.length == 3) ? name : "") + source.writeline("!byte " + (entries[i].length - ((val >= 0) ? 1 : 0) + displayname.length + 5)) + source.writeline("!byte " + ((val >= 0) ? val : entries[i].length)) + source.writeline("!text \"" + ((val >= 0) ? entries[i].substr(0, val) : entries[i]) + "\"") + source.writeline("!byte " + ((val >= 0) ? (entries[i].length - (val + 1)) : 0)) + source.writeline("!text \"" + ((val >= 0) ? (entries[i].substr(val + 1)) : "") + "\"") + source.writeline("!byte " + displayname.length) + source.writeline("!text \"" + displayname + "\"") + source.writeline("!byte " + ((needsjoystick * 128) + (Number(needs128k) * 64))) + } + + source.close() + new ActiveXObject("wscript.shell").run('cmd /c %acme% -o ' + WScript.Arguments(1) + ' build\\okvs.tmp', 0, 1) +} diff --git a/bin/buildslideshow.sh b/bin/buildslideshow.sh new file mode 100755 index 0000000..b67c194 --- /dev/null +++ b/bin/buildslideshow.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +# flags +# -d include game display name (default off = display name will be 0-length string) + +# parameters +# stdin - input containing slideshow (e.g. some file in res/SS/) +# stdout - binary OKVS data structure +# 1 - list of games with metadata (e.g. build/GAMES.CONF) + +include_displayname=false +while getopts ":d" opt; do + case $opt in + d) include_displayname=true + ;; + esac +done +shift $((OPTIND-1)) + +games=$(cat "$1") + +# make temp file with just the key/value pairs (strip blank lines, comments, eof marker) +records=$(mktemp) +tr -d "\r" | awk '!/^$|^#|^\[/' > "$records" + +# make temp assembly source file that represents the binary OKVS data structure +source=$(mktemp) +(echo "*=0" # dummy program counter for assembler + echo "!le16 $(wc -l <"$records"), 0" # OKVS header + while IFS="=" read -r key value; do + [ -n "$value" ] && filename="$value" || filename="$key" + line=$(echo "$games" | awk '/,'"$filename"'=/') + needsjoystick=$(echo "$line" | cut -c1) # 'requires joystick' flag (0 or 1) + needs128k=$(echo "$line" | cut -c2) # 'requires 128K' flag (0 or 1) + if [ "$include_displayname" = false ]; then + displayname="" + else + displayname=$(echo "$line" | tr -d "\r" | awk -F= '{ print $2 }') + fi + echo "!byte ${#key}+${#value}+${#displayname}+5" # OKVS record length + echo "!byte ${#key}" # OKVS key length + echo "!text \"$key\"" # OKVS key + echo "!byte ${#value}" # OKVS value length + echo "!text \"$value\"" # OKVS value + echo "!byte ${#displayname}" + echo "!text \"$displayname\"" + echo "!byte $((needsjoystick*128))+$((needs128k*64))" + done < "$records") > "$source" + +# assemble temp source file into binary OKVS data structure, then output that +out=$(mktemp) +acme -o "$out" "$source" +cat "$out" + +# clean up +rm "$out" +rm "$source" +rm "$records" diff --git a/bin/buildss.js b/bin/buildss.js new file mode 100644 index 0000000..2b770aa --- /dev/null +++ b/bin/buildss.js @@ -0,0 +1,73 @@ +a = new ActiveXObject("scripting.filesystemobject") + +entries = [] +p = WScript.Arguments(0) + +if (p.charAt(p.length - 1) == "*") +{ + b = a.opentextfile(p.substr(0, p.length - 1)) + + while (!b.atendofstream) + { + c = b.readline() + entries.push(c.substr(c.lastIndexOf("\\") + 1)) + } + + p = c.substr(0, c.lastIndexOf("\\")) +} +else +{ + for (b = new Enumerator(a.GetFolder(p).files); !b.atEnd(); b.moveNext()) + { + entries.push(b.item().name) + } +} + +entries.sort() + +f = a.createtextfile("build\\GAMES.SORTED") +f.write(entries.toString().replace(/,/g, "\n")) +f.close() +ss_off = a.fileexists(WScript.Arguments(3)) ? a.getFile(WScript.Arguments(3)).size : 0 +groups = "*=0\n" + "!le16 " + entries.length + ", 0\n" + +q = 0 + +if (WScript.Arguments(2) != "nul") +{ + q = a.createtextfile(WScript.Arguments(2)) + q.writeline() +} + +for (i = 0; i < entries.length; i++) +{ + size = a.getfile(p + "\\" + entries[i]).size + c = ss_off + ss_off += size + + if (WScript.Arguments.length == 6) + { + // if offset+size does not cross a block boundary, use the size + // otherwise adjust size until it ends at the next block boundary to avoid a partial copy on the last block + size = ((Math.floor(c / 512) == Math.floor((c + size) / 512)) ? size : (((c + size + 511) & -512) - c)) + } + + groups += "!byte " + (entries[i].length + 7) + "\n" + "!byte " + entries[i].length + "\n" + "!text \"" + entries[i] + "\"\n" + "!be24 " + c + "\n" + "!le16 " + size + "\n" + + if (typeof(q) == "object") + { + q.writeline(entries[i] + "," + c + "," + size) + } +} + +if (typeof(q) == "object") +{ + q.close() +} + +f = a.createtextfile("build\\ss.tmp") +f.write(groups) +f.close() +x = new ActiveXObject("wscript.shell") +x.run('cmd /c %acme% -o ' + WScript.Arguments(1) + ' build\\ss.tmp', 0, 1) +x.run('cmd /c bin\\buildpreall.bat ' + p + ' ' + WScript.Arguments(3) + ' ' + WScript.Arguments(4), 0, 1) diff --git a/bin/changebootloader.sh b/bin/changebootloader.sh index bb0417d..851d2d3 100755 --- a/bin/changebootloader.sh +++ b/bin/changebootloader.sh @@ -1,3 +1,3 @@ #!/bin/sh -dd of="$1" bs=1 count=512 conv=notrunc < "$2" +dd of="$1" bs=1 count=512 conv=notrunc < "$2" 2>/dev/null diff --git a/bin/check-attract-mode.sh b/bin/check-attract-mode.sh index bc9bab1..f0d9a90 100755 --- a/bin/check-attract-mode.sh +++ b/bin/check-attract-mode.sh @@ -7,23 +7,11 @@ fatal_error() { exit 1 } -check_title_slideshow() { +check_slideshow() { [ -f "$1" ] || - fatal_error "Can't find HGR title slideshow" "$1" - cat "$1" | - grep -v "^#" | - grep -v "^\[" | - grep -v "^$" | - while read ssline; do - [ -f "$2"/"$ssline" ] || - fatal_error "Can't find title screenshot" "$ssline" - done -} - -check_action_slideshow() { - [ -f "$1" ] || - fatal_error "Can't find HGR action slideshow" "$1" + fatal_error "Can't find slideshow" "$1" cat "$1" | + tr -d "\r" | grep -v "^#" | grep -v "^\[" | grep -v "^$" | @@ -33,20 +21,50 @@ check_action_slideshow() { gamename=$filename fi [ -f "$2"/"$filename" ] || - fatal_error "Can't find action screenshot" "$filename" + fatal_error "Can't find screenshot" "$filename" grep "^$gamename$" /tmp/games >/dev/null || - fatal_error "Action screenshot links to non-existent game" "$gamename" + fatal_error "Screenshot links to non-existent game" "$gamename" done } +# fatal error if an attract mode module is listed more than once +dupes=$(cat res/ATTRACT.CONF | + tr -d "\r" | + grep -v "^#" | + grep -v "^$" | + sort | + uniq -d) +if [[ $dupes ]]; then + fatal_error "Duplicate ATTRACT.CONF module:" "$dupes" +fi + cat res/GAMES.CONF | + tr -d "\r" | grep -v "^#" | grep -v "^\[" | grep -v "^$" | cut -d"," -f2 | cut -d"=" -f1 > /tmp/games +# warn about unused self-running demos +cat res/DEMO/_FileInformation.txt | + tr -d "\r" | + grep "Type(06)" | + grep -v "SPCARTOON" | + cut -d"=" -f1 | + while read f; do + grep "$f=0" res/ATTRACT.CONF >/dev/null || echo "unused demo: $f"; + done + +# warn about unused slideshows +cd res/SS +for f in *.CONF; do + grep "$f" ../ATTRACT.CONF >/dev/null || echo "unused slideshow: $f"; +done +cd ../.. + cat res/ATTRACT.CONF | + tr -d "\r" | grep "=" | grep -v "^#" | while read line; do @@ -57,17 +75,19 @@ cat res/ATTRACT.CONF | [ "${module_name%???}" = "SPCARTOON" ] || fatal_error "Can't find demo" $module_name elif [ "$module_type" = "1" ]; then - check_title_slideshow res/SS/"$module_name" res/TITLE.HGR/ + check_slideshow res/SS/"$module_name" res/TITLE.HGR/ elif [ "$module_type" = "2" ]; then - check_action_slideshow res/SS/"$module_name" res/ACTION.HGR/ + check_slideshow res/SS/"$module_name" res/ACTION.HGR/ elif [ "$module_type" = "3" ]; then - check_title_slideshow res/SS/"$module_name" res/TITLE.DHGR/ + check_slideshow res/SS/"$module_name" res/TITLE.DHGR/ elif [ "$module_type" = "4" ]; then - check_action_slideshow res/SS/"$module_name" res/ACTION.DHGR/ + check_slideshow res/SS/"$module_name" res/ACTION.DHGR/ elif [ "$module_type" = "5" ]; then - check_title_slideshow res/SS/"$module_name" res/ARTWORK.SHR/ + check_slideshow res/SS/"$module_name" res/ARTWORK.SHR/ elif [ "$module_type" = "6" ]; then - check_action_slideshow res/SS/"$module_name" res/ACTION.GR/ + check_slideshow res/SS/"$module_name" res/ACTION.GR/ + elif [ "$module_type" = "7" ]; then + check_slideshow res/SS/"$module_name" res/ACTION.DGR/ else fatal_error "Unknown module type" $module_type fi diff --git a/bin/checkdate.js b/bin/checkdate.js new file mode 100644 index 0000000..4e85417 --- /dev/null +++ b/bin/checkdate.js @@ -0,0 +1,2 @@ +a = new ActiveXObject("scripting.filesystemobject") +WScript.quit(Math.abs(!a.fileexists(WScript.Arguments(0)) || a.getfile(WScript.Arguments(0)).datelastmodified < a.getFile(WScript.Arguments(1)).datelastmodified)) diff --git a/bin/converthelp.js b/bin/converthelp.js new file mode 100644 index 0000000..aebff7b --- /dev/null +++ b/bin/converthelp.js @@ -0,0 +1,63 @@ +a = new ActiveXObject("scripting.filesystemobject") + +if (!a.fileexists(WScript.Arguments(1)) || a.getfile(WScript.Arguments(1)).datelastmodified < a.getFile(WScript.Arguments(0)).datelastmodified) +{ + z = a.opentextfile(WScript.Arguments(0)) + d = a.createtextfile(WScript.Arguments(1)) + + String.prototype.replaceWith = function(q) + { + return this.substr(0, c) + String.fromCharCode(q) + this.substr(c + 1) + } + + while (!z.atendofstream) + { + b = z.readline() + + c = b.search(/\[eof\]/) + + if (c > -1) + { + break + } + + c = b.search(/\r\n/) + + if (c > -1) + { + b = b.substr(0, c) + } + + for (c = 0; c < b.length; c++) + { + if (b.charAt(c) == '*') + { + b = b.replaceWith(16) + } + else if (b.charAt(c) == '~') + { + b = b.replaceWith(17) + } + else if (b.charAt(c) == '<') + { + b = b.replaceWith(8) + } + else if (b.charAt(c) == '>') + { + b = b.replaceWith(21) + } + else if (b.charAt(c) == '$') + { + b = b.replaceWith(14) + } + else if (b.charAt(c) == '%') + { + b = b.replaceWith(15) + } + } + + d.write(String.fromCharCode(b.length) + b) + } + + d.write(String.fromCharCode(255)) +} diff --git a/bin/converthelp.sh b/bin/converthelp.sh new file mode 100755 index 0000000..2bdf999 --- /dev/null +++ b/bin/converthelp.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +tr "\*\~\<\>\$\%" "\020\021\010\025\016\017" < "$1" | \ + tr -d "\r" | awk '!/^\[/ { printf "%c%s", length, $0 } END { printf "\xFF" }' > "$2" diff --git a/bin/forevershr.sh b/bin/forevershr.sh index b2bb508..08673f0 100755 --- a/bin/forevershr.sh +++ b/bin/forevershr.sh @@ -1,7 +1,7 @@ #!/bin/bash # directory of PNG files (assume they are properly sized and named) -PNGS="$HOME/Dropbox/a2/4cade/artwork/cropped-and-named-320x200/_4sports" +PNGS="$HOME/Dropbox/a2/4cade/artwork/cropped-and-named-320x200" # Python 3 export PYTHON="python" diff --git a/bin/makesorted.js b/bin/makesorted.js new file mode 100644 index 0000000..34d3f70 --- /dev/null +++ b/bin/makesorted.js @@ -0,0 +1,39 @@ +a = new ActiveXObject("scripting.filesystemobject") +b = a.opentextfile("res\\GAMES.CONF") +c = [] +q = a.createtextfile("build\\GAMES.CONF") + +while (!b.atendofstream) +{ + d = b.readline() + e = d.indexOf("#") + + if (e >= 0) + { + d = d.substr(0, e) + } + + e = d.indexOf("[eof]") + + if (e > -1) + { + break + } + + e = d.indexOf("=") + + if (e == -1) + { + e = d.length + } + + if (d.length > 0) + { + q.write(d + "\n") + f = d.indexOf(",") + 1 + c.push(d.substr(f, e - f)) + } +} + +q.write(d + "\n") +a.createtextfile("build\\GAMES.SORTED").write(c.sort().toString().replace(/,/g, "\n")) diff --git a/bin/packhgrfile.py b/bin/packhgrfile.py new file mode 100755 index 0000000..5948009 --- /dev/null +++ b/bin/packhgrfile.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +import sys + +infile = sys.argv[1] +outfile = sys.argv[2] + +i = open(infile,"rb") +filedata = i.read() +i.close + +# If the file has a JMP in the last screen hole, the +# game has an animated title, skip packing and copy +# the file as is instead. +if(len(filedata) >= 8192 and filedata[8189] == 0x4c): + print (infile, "has animation, not packing") + outdata = bytearray(filedata[0:8192]) +else: + outdata = bytearray(filedata[0:7680]) + + for h in range(60): + oh = h*128+120 + ih = h*8+7680+(int(h/15)*8) + outdata[oh:oh+8] = filedata[ih:ih+8] + +o = open(outfile,"wb") +o.write(outdata) +o.close + diff --git a/bin/padto.js b/bin/padto.js index a191dc7..233549c 100644 --- a/bin/padto.js +++ b/bin/padto.js @@ -1,5 +1,14 @@ a = new ActiveXObject("scripting.filesystemobject") -b = a.opentextfile(WScript.Arguments(1)) -c = b.readall() -b.close() -a.createtextfile(WScript.Arguments(1)).write(String(c + Array(512).join(" ")).substr(0, 512)) + +if (WScript.Arguments(1) == "build\\PREFS.CONF") +{ + b = a.opentextfile(WScript.Arguments(1)) + c = b.readall().replace(/\r\n/g, "\n") + b.close() + b = a.createtextfile(WScript.Arguments(1)) + b.write(c) + b.close() +} + +c = a.getfile(WScript.Arguments(1)).size +b = a.opentextfile(WScript.Arguments(1), 8).write(Array((Math.floor((c + 511) / 512) * 512) - c + 1).join(String.fromCharCode(0))) diff --git a/bin/padto.sh b/bin/padto.sh index eb4deb7..273ec6d 100755 --- a/bin/padto.sh +++ b/bin/padto.sh @@ -1,11 +1,5 @@ #!/bin/bash -totalsize=$1 -outfile=$2 +# zero-pads $1 to a multiple of 512 bytes, in place -[[ "$OSTYPE" == "linux-gnu" ]] \ - && filesize=$(stat -c "%s" "$outfile") \ - || filesize=$(stat -f "%z" "$outfile") - -padsize=$((512-$filesize)) -dd if=/dev/zero bs=1 count=$padsize >> "$outfile" +dd if=/dev/null of="$1" bs=1 count=1 seek="$((($(wc -c < "$1") + 511) & -512))" 2>/dev/null diff --git a/bin/rename.py b/bin/rename.py new file mode 100755 index 0000000..45b1842 --- /dev/null +++ b/bin/rename.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python3 + +import fileinput +import glob +import subprocess +import sys +import tempfile + +def replace_string_in_file(filename, old_string, new_string): + for line in fileinput.input(glob.glob(filename), inplace=True): + print(line.replace(old_string, new_string), end='') + +def rename_files_in_directory(dirname, old_filename, new_filename): + for filename in glob.glob(f'{dirname}/{old_filename}*'): + subprocess.run(['git', 'mv', filename, filename.replace(old_filename, new_filename)]) + +def rename_one_file_in_directory(dirname, old_filename, new_filename): + for filename in glob.glob(f'{dirname}/{old_filename}'): + subprocess.run(['git', 'mv', f'{dirname}/{old_filename}', f'{dirname}/{new_filename}']) + +def rename_inside_disk_image(filename, old_name, new_name): + rt = subprocess.run(['cadius', 'CATALOG', filename], stdout=subprocess.PIPE, text=True) + if not rt: + print('cadius CATALOG command failed') + if not [line for line in rt.stdout.split('\n') if line == f'/{old_name}/']: + return + rt = subprocess.run(['cadius', 'RENAMEFILE', filename, f'/{old_name}/{old_name}', new_name], stdout=subprocess.PIPE, text=True) + if not rt: + print('cadius RENAMEFILE command failed') + rt = subprocess.run(['cadius', 'RENAMEVOLUME', filename, new_name], stdout=subprocess.PIPE, text=True) + if not rt: + print('cadius RENAMEVOLUME command failed') + with tempfile.TemporaryDirectory() as tmpdir: + rt = subprocess.run(['cadius', 'EXTRACTFILE', filename, f'/{new_name}/LOADER.SYSTEM', tmpdir], stdout=subprocess.PIPE, text=True) + if not rt: + print('cadius EXTRACTFILE command failed') + try: + loader_file = glob.glob(tmpdir + "/LOADER.SYSTEM*").pop() + except IndexError: + return + with open(loader_file, 'rb') as f: + loader = f.read() + loader_as_list = list(loader) + while loader_as_list.pop() >= 0x10: + pass + loader_as_list.append(len(new_name)) + loader_as_list.extend([ord(x) for x in new_name]) + new_loader = bytes(loader_as_list) + with open(loader_file, 'wb') as f: + f.write(new_loader) + rt = subprocess.run(['cadius', 'REPLACEFILE', filename, f'/{new_name}/', loader_file], stdout=subprocess.PIPE, text=True) + if not rt: + print('cadius REPLACEFILE command failed') + +def rename(old_game_name, new_game_name): + print(old_game_name) + for filename in glob.glob('res/dsk/*'): + rename_inside_disk_image(filename, old_game_name, new_game_name) + + for filename in ('res/GAMES.CONF', + f'res/ATTRACT/{old_game_name}', + 'res/SS/*'): + replace_string_in_file(filename, old_game_name, new_game_name) + + for dirname in ('res/DEMO',): + rename_one_file_in_directory(dirname, old_game_name, new_game_name) + + replace_string_in_file('res/DEMO/_FileInformation.txt', f'{old_game_name}=', f'{new_game_name}=') + + for filename in ('res/ATTRACT.CONF',): + replace_string_in_file(filename, f'{old_game_name}=0', f'{new_game_name}=0') + + replace_string_in_file('src/prelaunch/*', f'build/PRELAUNCH/{old_game_name}', f'build/PRELAUNCH/{new_game_name}') + + for dirname in ('res/ACTION.DHGR', + 'res/ACTION.DHGR.UNCOMPRESSED', + 'res/ACTION.GR', + 'res/ACTION.HGR', + 'res/ACTION.HGR.UNCOMPRESSED', + 'res/ARTWORK.SHR', + 'res/ARTWORK.SHR.UNCOMPRESSED', + 'res/ATTRACT', + 'res/GAMEHELP', + 'res/TITLE.ANIMATED', + 'res/TITLE.DHGR', + 'res/TITLE.HGR'): + rename_files_in_directory(dirname, old_game_name, new_game_name) + +def driver(): + #rename("SLICKS", "S8") + rename("CIDER.SPIDER", "AC") + rename("ARCADE.BT.CAMP", "AB") + rename("ARDY.AARDVARK", "AA") + rename("ASTEROID.BLASTR", "AS") + rename("BCS.QUEST", "BQ") + rename("BEACH.HEAD.II", "B2") + rename("BEACH.HEAD", "B1") + rename("BEYOND.WOLFEN", "BW") + rename("BUDGETRILOGY", "BT") + rename("BLOCKCHAIN", "BC") + rename("BOUNCING.KMNGAS", "BK") + rename("BRAINTEASERBLVD", "BB") + rename("BUCK.ROGERS", "BR") + rename("BURGERTIME", "BU") + rename("CANNONBALL.BLTZ", "CB") + rename("CAPTN.GOODNIGHT", "CG") + rename("SMURFEN", "CS") + rename("WOLFEN84", "CW") + rename("CAVRNS.CALLISTO", "CC") + rename("CHAMP.LODERUN", "CL") + rename("COPTS.ROBBERS", "CR") + rename("D.GENERATION", "DG") + rename("DARKSTAR.UNHNGD", "DU") + rename("DAVIDS.MAGIC", "DM") + rename("EGGS.IT", "EI") + rename("IMPOSSIBLE.MISS", "I1") + rename("IMPOSSIBLE.M.II", "I2") + rename("EAGLES.NEST", "IE") + rename("I.O.SILVER", "IO") + rename("LITTLE.COMP.PPL", "LP") + rename("LOCK.N.CHASE", "LC") + rename("MARIO.BROS", "MB") + #rename("MATTERHORN", "MS") + rename("MINGS.CHALLENGE", "MI") + rename("THUNDERHEAD", "MT") + rename("MONTEZUMA", "MZ") + rename("MR.COOL", "MC") + rename("MR.DO", "MD") + rename("MR.ROBOT", "MR") + rename("MS.PACMAN", "MP") + rename("NIGHT.MISSION", "NM") + rename("NIGHTMARE", "NI") + rename("ORILEYS.MINE", "OM") + rename("OOTW", "OW") + rename("PANDORAS.BOX", "PB") + rename("PHARAOHS.REVNG", "PR") + rename("PIEMAN", "PM") + rename("PRINCEUNP", "PP") + rename("RAID.OVR.MOSCOW", "RM") + rename("REALM.IMPOSS", "RI") + rename("SITUATION.CRTCL", "SC") + rename("SOKO.BAN", "SO") + rename("SPYS.DEMISE", "SD") + rename("SUICIDE", "SU") + rename("TECHNOCOP", "TC") + rename("THAROLIAN.TUNLS", "TU") + rename("ASTEROID.FIELD", "AF") + rename("LAST.GLADIATOR", "LG") + rename("SPY.STRIKES.BAK", "S2") + rename("TUBEWAY", "TB") + rename("UP.N.DOWN", "UD") + rename("ROGER.RABBIT", "RR") + rename("WINGS.OF.FURY", "WF") + +def driver_phase_2(): + rename("CEST.LA.VIE", "CV") + rename("DEFEND.JH", "DJ") + rename("ESCAPE", "ES") + rename("ITS.THE.PITS", "IP") + rename("LAMB.CHOPS", "LA") + rename("MIRV", "M.I.R.V") + rename("NEUT.TOWER", "NT") + rename("SHUTTLE.INTRCPT", "SI") + rename("CAVERNS.FREITAG", "CF") + rename("MOVIE.MONSTER", "MM") + +def driver_phase_3(): + rename("CP", "CAPTAIN.POWER") + +def driver_phase_4(): + rename("MATTERHORN", "MS") + +if __name__ == '__main__': + #rename("MR.DO", "MD") + #driver() + driver_phase_4() diff --git a/res/CACHE00.IDX b/res/CACHE00.IDX new file mode 100644 index 0000000..0a72362 Binary files /dev/null and b/res/CACHE00.IDX differ diff --git a/res/CACHE01.IDX b/res/CACHE01.IDX new file mode 100644 index 0000000..9488485 Binary files /dev/null and b/res/CACHE01.IDX differ diff --git a/res/CACHE10.IDX b/res/CACHE10.IDX new file mode 100644 index 0000000..c2f1aec Binary files /dev/null and b/res/CACHE10.IDX differ diff --git a/res/CACHE11.IDX b/res/CACHE11.IDX new file mode 100644 index 0000000..c19d213 Binary files /dev/null and b/res/CACHE11.IDX differ diff --git a/res/DFX.CONF b/res/DFX.CONF index f8bc6c3..70828af 100644 --- a/res/DFX.CONF +++ b/res/DFX.CONF @@ -1,3 +1,30 @@ +# +# Transition effects for DHGR slideshows +# +# Each Mega-Attract Module that is a DHGR slideshow (see ATTRACT.CONF) +# will use a single transition effect for the length of the module. +# Transition effects are loaded in the order listed in this file. Each line +# of this file is a filename (not including comments, like this one). The +# name of the next transition effect is stored in the global prefs, so this +# file should not contain duplicates. +# +# Transition effects are binary files loaded at $6000 and called with main +# memory banked in, DHGR page 1 showing, and the next DHGR graphic already +# loaded at $4000/main and $4000/aux. A transition effect has full use of +# zero pages (both), $0200-$07FF (both), $6000-$BEFF/main, $800-$1FFF/aux, +# and $6000-$BFFF/aux. $800-$1FFF/main is reserved for the slideshow data. +# $BF00-$BFFF/main is reserved for the ProDOS shim. LC RAM banks 1 and 2 are +# reserved for the launcher. +# +# Important: LC RAM bank 1 will be read/write on entry and must be read/write +# on exit. If you need ROM routines, you are responsible for switching to ROM +# then switching back to RAM bank 1 (read/write) before returning. However, +# you can leave WRITEAUXMEM active. The calling code will unconditionally +# switch back to WRITEMAINMEM. +# +# This file is converted to a binary data structure (DFX.IDX) during build +# then added to TOTAL.DATA on the final disk image. +# DHGR.FIZZLE2BIT DHGR.RIPPLE DHGR.SOFT.DIAG @@ -45,6 +72,7 @@ DHGR.SLOWST.RIP DHGR.48.SPIRAL DHGR.RADIAL5 DHGR.FIZZLE +DHGR.48.PAGEC DHGR.BFLY.RIP DHGR.IRIS.IN DHGR.SWIRL @@ -59,27 +87,4 @@ DHGR.WAVY.IRIS DHGR.BLOOM.RIP DHGR.48.SYNC DHGR.FLICK - [eof] - -# -# transition effects for DHGR slideshows -# -# Each Mega-Attract Module that is a DHGR slideshow (see attract.conf) -# will use a single transition effect for the length of the module. -# Transition effects are loaded in the order listed in this file. Each line -# of this file is a filename (not including comments, like this one). The -# name of the next transition effect is stored in the global prefs, so this -# file should not contain duplicates. -# -# Transition effects are binary files loaded at $6000 and called with main -# memory banked in, DHGR page 1 showing, and the next DHGR graphic already -# loaded at $4000/main and $4000/aux. A transition effect has full use of -# auxiliary memory, zero pages (both), text pages (both, but preserve screen -# holes), and main memory $6000-$BEFF. $BF00-$BFFF/main is reserved for the -# ProDOS shim. LC RAM banks 1 and 2 are reserved for the launcher. -# -# Important: LC RAM bank 1 will be read/write on entry and must be read/write -# on exit. If you need ROM routines, you are responsible for switching to ROM -# then switching back to RAM bank 1 (read/write) before returning. -# diff --git a/res/FX.CONF b/res/FX.CONF index 7b8ed75..756de41 100644 --- a/res/FX.CONF +++ b/res/FX.CONF @@ -1,3 +1,26 @@ +# +# Transition effects for HGR slideshows +# +# Each Mega-Attract Module that is an HGR slideshow (see ATTRACT.CONF) +# will use a single transition effect for the length of the module. +# Transition effects are loaded in the order listed in this file. Each line +# of this file is a filename (not including comments, like this one). The +# name of the next transition effect is stored in the global prefs, so this +# file should not contain duplicates. +# +# Transition effects are binary files loaded at $6000 and called with +# hi-res page 1 showing and the next HGR graphic already loaded at $4000. +# A transition effect can use $6000-$BEFF, zero page, and $0200-$07FF. +# $800-$1FFF is reserved for the slideshow data. $BF00-$BFFF is reserved for +# the ProDOS shim. LC RAM banks 1 and 2 are reserved for the launcher. +# +# Important: LC RAM bank 1 will be read/write on entry and must be read/write +# on exit. If you need ROM routines, you are responsible for switching to ROM +# then switching back to RAM bank 1 (read/write) before returning. +# +# This file is converted to a binary data structure (FX.IDX) during build +# then added to TOTAL.DATA on the final disk image. +# BOXES48.SNAKE RIPPLE SOFT.DIAGONAL @@ -28,6 +51,8 @@ R.BY.PIXEL WAVY.IRIS BIT.FIZZLE STAR.IN +BOXES48.PAGEC +DIAG.STRIPES APPLE MANDELBROT.RIP SOFT.L @@ -45,6 +70,7 @@ FLOWER APPLE.RIPPLE DIAGONAL2 STAR.BLOOM +DIAMOND.STRIPES BOXES48.SYNC PALETTE.FIZZLE BUTTERFLY @@ -81,6 +107,7 @@ BUTTERFLY.IN LR.BY.PIXEL CHECKERB.FIZZLE BOXES48.SIDES +CIRCLE.STRIPES STAGGERWHITE.LR SOFT.UD.OUT ONESQUARE @@ -119,25 +146,3 @@ BOXES48.ARROW REDLINES FLICK [eof] - -# -# transition effects for HGR slideshows -# -# Each Mega-Attract Module that is an HGR slideshow (see attract.conf) -# will use a single transition effect for the length of the module. -# Transition effects are loaded in the order listed in this file. Each line -# of this file is a filename (not including comments, like this one). The -# name of the next transition effect is stored in the global prefs, so this -# file should not contain duplicates. -# -# Transition effects are binary files loaded at $6000 and called with -# hi-res page 1 showing and the next HGR graphic already loaded at $4000. -# A transition effect can use $6000-$BEFF in main memory, zero page, and -# text page if needed (but preserve the screen holes). $800-$1FFF is reserved -# for the slideshow data. $BF00-$BFFF is reserved for the ProDOS shim. -# LC RAM banks 1 and 2 are reserved for the launcher. -# -# Important: LC RAM bank 1 will be read/write on entry and must be read/write -# on exit. If you need ROM routines, you are responsible for switching to ROM -# then switching back to RAM bank 1 (read/write) before returning. -# diff --git a/res/SFX.CONF b/res/SFX.CONF new file mode 100644 index 0000000..b8a3cf8 --- /dev/null +++ b/res/SFX.CONF @@ -0,0 +1,65 @@ +# +# Transition effects for SHR slideshows +# +# Each Mega-Attract Module that is an SHR slideshow (see ATTRACT.CONF) +# will use a single transition effect for the length of the module. +# Transition effects are loaded in the order listed in this file. Each line +# of this file is a filename (not including comments, like this one). The +# name of the next transition effect is stored in the global prefs, so this +# file should not contain duplicates. +# +# Transition effects are binary files loaded at $A000 and called with main +# memory banked in (read/write) and the next SHR graphic already loaded at +# $2000/main. A transition effect has full use of zero page (main), +# $0200-$07FF (main), and $A000-$BEFF/main. $BF00-$BFFF/main is reserved for +# the ProDOS shim. LC RAM banks 1 and 2 are reserved for the launcher. +# +# /!\ You can not assume auxiliary memory exists! No, really. +# +# Consider this (supported) configuration: Apple ][+, 64K, VidHD card. +# This machine is capable of displaying SHR graphics by copying pixel and +# palette data from $2000-$9FFF/main to $2000-$9FFF/aux, despite the fact +# that auxiliary memory does not exist and the writes will actually go to +# main memory. However, the VidHD card notices and respects the WRITEAUXMEM +# softswitch and will cache the data in its internal cache and ultimately +# display it. +# +# Even worse, this means that SHR transitions must be careful about writing +# to aux anything other than the current value of that address in main, +# because in some (supported) configurations, those writes will actually +# be altering main memory. Example: you want to clear the palettes space +# before progressively fading them in. Writing all zeros to the palettes +# in "auxiliary" memory will actually overwrite the original palettes in +# main memory. +# +# Important: LC RAM bank 1 will be read/write on entry and must be read/write +# on exit. If you need ROM routines, you are responsible for switching to ROM +# then switching back to RAM bank 1 (read/write) before returning. However, +# you can leave WRITEAUXMEM active; the calling code unconditionally switches +# back to WRITEMAINMEM after the transition code returns. +# +# This file is converted to a binary data structure (SFX.IDX) during build +# then added to TOTAL.DATA on the final disk image. +# +SHR.80BOXES +SHR.FIZZLE +SHR.RIPPLE +SHR.TWOPASS.LR +SHR.RADIAL +SHR.80.SNAKE +SHR.SOFT.IRIS +SHR.DIAGONAL +SHR.80.DOWN +SHR.IRIS.IN +SHR.LR +SHR.RADIAL2 +SHR.80.SPIRAL +SHR.FADEIN +SHR.SOFTIRIS.IN +SHR.80.SIDE2 +SHR.LR2 +SHR.80.ARROW +SHR.IRIS +SHR.UD + +[eof] diff --git a/res/TITLE.HGR.UNPACKED/AMER.CHALLENGE b/res/TITLE.HGR.UNPACKED/AMER.CHALLENGE new file mode 100644 index 0000000..01bfe55 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/AMER.CHALLENGE differ diff --git a/res/TITLE.HGR.UNPACKED/AUTOBAHN b/res/TITLE.HGR.UNPACKED/AUTOBAHN new file mode 100644 index 0000000..89bd2e6 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/AUTOBAHN differ diff --git a/res/TITLE.HGR.UNPACKED/BASEBALL b/res/TITLE.HGR.UNPACKED/BASEBALL new file mode 100644 index 0000000..4560b70 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/BASEBALL differ diff --git a/res/TITLE.HGR.UNPACKED/BLACK.BELT b/res/TITLE.HGR.UNPACKED/BLACK.BELT new file mode 100644 index 0000000..539c20b Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/BLACK.BELT differ diff --git a/res/TITLE.HGR.UNPACKED/BOP.N.WRESTLE b/res/TITLE.HGR.UNPACKED/BOP.N.WRESTLE new file mode 100644 index 0000000..4154365 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/BOP.N.WRESTLE differ diff --git a/res/TITLE.HGR.UNPACKED/CHAMP.BSKETBALL b/res/TITLE.HGR.UNPACKED/CHAMP.BSKETBALL new file mode 100644 index 0000000..c7fd83a Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/CHAMP.BSKETBALL differ diff --git a/res/TITLE.HGR.UNPACKED/CHAMP.WRESTLE b/res/TITLE.HGR.UNPACKED/CHAMP.WRESTLE new file mode 100644 index 0000000..18ff44b Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/CHAMP.WRESTLE differ diff --git a/res/TITLE.HGR.UNPACKED/CMPTR.FOOSBALL b/res/TITLE.HGR.UNPACKED/CMPTR.FOOSBALL new file mode 100644 index 0000000..2433cb5 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/CMPTR.FOOSBALL differ diff --git a/res/TITLE.HGR.UNPACKED/DIVE.BOMBER b/res/TITLE.HGR.UNPACKED/DIVE.BOMBER new file mode 100644 index 0000000..f74c00b --- /dev/null +++ b/res/TITLE.HGR.UNPACKED/DIVE.BOMBER @@ -0,0 +1 @@ +€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÁªÅŠºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€ÐŽ€€ô€€Ðþÿ¿×ÄȪ«×ªÕªÖªõ«ÕêýÿÿŸ°æŒž¼¾æ™¿üÀ׫ժݪվժÕüÿÿÿ€€€€€€€€€€€€ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€ŠÕŠºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€Ô¢ÕݪýŸºøÿð¿®ÕûÿÿÇøÿÿÿÿÿÿÿÿ¿õªÁúѪզթ×ÔªÕª€€€€€€€€€€€€º«Õ¡ÿÿÿÿ¿€€€ºÀ†Ðÿƒ €€€úÿÿÿÿÿÿÿ¿×€€€€ Õª•ºÿÿŸ€€ €€¨ƒàÿ‹ÀŽ€€ÐŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕÕŠÕˆªÕªÕªÔª€€€€‚ŠÕªÕªÕªÕªÏê󪵪ϪժÕÔªÕª€€€€€€€€€€€€ºÿ¯ Ò¢ÿÿ¿À¾€ºÀžÀþ€¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€ÿôß›ºÿÿÿÿÿÿÿÿÿ³þ̉ü™³æ¼æ³žÿÿÿÿÿÿÿÿ¿×誩ÕÕªõ·ÕŽƒ†¶ª…€€©Åª‰‚‚ùÿ¿ÿ¿ÕЪùïîÛõ¨½¨íÔÿÿÿ€€€€€€€€ Õª•ºÿÿÿ¯ •ÿ¿À¾€ºÀþ€ˆ€º€úÿÿÿÿÿÿÿÿÿ¿×€€ÐªÿÿÓšºÿÿÿÿÿÿÿÿÿÿÿÿ¯ßªõëÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿç¡Á£…ˆ€Š€Ž˜€€€€€À€ µÿ€€úÿÿÿóϪíÿÿÿÿÿÿýÿ€€€€€€€€ª…ª•ºÿÓÿÿÿÿ¯µ€€€ºÀþƒ€À¾€€€úÿÿÿÿÿÿÿ¿×€¢‘‚ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßêÿºý¯õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÕÿ•€Ð€ÐªÕªÕªÕ€€€€€€€€€€€€¨ÕªÕªÕîÕª€€€€€øÿ€€€€€€€€¨ŠºÿÿŸ€€€€€ ƒ€ýƒÀŽ€€ÀŽ€€ÀŽ€€ÀΙ³×€ªÕªÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿª½úªýÿÿÿÿÇþÕªýÿÿ¿×üÿÿÿ½†Õþ¨ÕÔ̪ÕúŸÔþ…Õ¨õÿÔÿÿŸõ‡õÿÿÿŸõÿÿÿÿ¯Õª€€€€€€€€…ÕŠºÿÿŸ€€ ‡ ƒ€ô€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ôª©©ßþÿŸºÿÿÿÿÿÿÿÿÿÿÿÿÿÕªÕþÿÿÿÿºÕªÕªÕªÑ¾×üÿÿÿÔ‚”‚„ˆÐ Á€”¨Ð ‘€…Š‚„ª„ŠÔŠªÕê§ÕªÕªÕ¨ÕªÕª€€€€€€€€€€€ÔªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕª€€€ÕªÕŠºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€Ð€€ô€€Ðÿÿ¿×êÔ¢ÕÕªÕŠÙªŸÊÕºÕþÿŸ³æÌ™Ïùà™ÿùÌתիݪժժ×ü®Õª€€€€€€€€€€€€ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€•Ô”ºÿÿŸ€€ ‡ ƒ ŠÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€ÕªÕߪ՚Šÿß¿úÝúÿÿÇøÿÿÿÿÿÿÿÿ¿õªõêժݟõºÓÔªÕª€€€€€€€€€€€€º¯Õ¢ÿÿÿÿ¿€€€ºÀ†Ðÿƒ¨€€€úÿÿÿÿÿÿÿ¿×€€€€ Õª…ºÿÿߪժߪÕê×êÿ¯Õ®ÕªÕ¯ÕªÕ®Õ®Õþÿ¿×¨ÕªÕý§ŠªÕ¨ÕªÔŠ€ ”ÒŠŠÕªÕªÕªÕª±êö«Õ©ÍªÕªÕÔªÕª€€€€€€€€€€€€ºÿŸ¨Òªÿÿ¿À¾€ºÀžÀþ€º€€ðÿÿÿÿÿÿÿÿ¿×€€€€þû¦•ºÿÿÿÿÿÿÿÿŸ³þ̙̙³æ¼æ³žÿÿÿÿÿÿÿÿ¿×èÓêÕÕêû€†°þ€„¥¨ˆ€Âÿÿ¿ÿÿ¿Æªùï쨕¹ôŽÅôÿÿÿ€€€€€€€€¨Õª•ºÿÿÿ¿€•ü¿À¾€ºÀþ€ˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€€”ˆýÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿëתÕïÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ£Õ«ÔŠ„¨…€À€€€À€Àª•µÿ€€úÿÿÿøߪëÿÿÿÿÿßüÿ€€€€€€€€Š ª•ºÿ—ÿÿÿÿ¿µ€€€ºÀþƒ€Ð¿€€€úÿÿÿÿÿÿÿ¿×€ªÐ¨ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßêßþõ¯õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€Àª…€€€€€€€€€€€€€€€€€€€€€€€€ª…€€€€€Ð‚üÿ€€€€€€€€ÀÄЊºÿÿŸ€€€€€ ƒ€ýƒÀŽ€€ÀŽ€€ÀŽ€€ÀΙ³×ÀŠÕŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿªµ‘Úªýÿÿÿÿ¯ÝªÕÿÿ¿×üÿÿÿªÕªÁŠÍêÕŠ ýë ‡ŽÐ¯Õþÿ§õ«þúõïêê©Õÿ¯žÕª€€€€€€€€ÕªÕŠºÿÿŸ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ôª¥‹õ«ÿŸºÿÿÿÿÿÿÿÿÿÿÿÿÿתÕÿÿÿÿߪժժ×êѺ×üÿÿÿÔˆ‘¢ÄˆÑˆÑˆ‘ªÄˆ‘¢Ä¨”¢Ä¨ÄˆÕÿÿïêÿժժŪժժ€€€€€€€€€€€ÐªªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕª•ÕŠ€€€€€€ºÿÿŸ€€à ‡ ƒ €ˆÀŽ€€ð€€ô€€ðÿÿ¿×¨µÑ”ÕêתÕêרժÝûÿŸ³æÌ™Ïùÿ™ÏùÌת׫ժժµª×ÔªÕª€€€€€€€€€€€€ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€€À”ºÿÿŸ€€ ‡ ƒ ŠÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿× ÕªÕÕªÕŠ°ÿñÿ¿ÚÕëÿÿ×àÿÿÿÿÿÿÿÿÿÕªÕªÕªÕŽµ·×ÔªÕª€€€€€€€€€€€€ºŸÕªÿÿÿÿ¿€€€ºÀ†Àþƒ¨€€€úÿÿÿÿÿÿÿ¿×€€€€ªÕªŠºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×¨ÕªÕÿøÓŠªÕ¨ÕŠÐŠ€ ”‚¨ŠÕªÕªÕªÕª™šÕ¨í¯ÕªÕªÕÔªÕª€€€€€€€€€€€”ºÿ€Õªÿÿ¿À¾€ºÀž€ú€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿÿÿŸºÿÿÿÿÿÿÿÿ¿¸þṜ¼¸æ°ðƒŸÿÿÿÿÿÿÿÿ¿×¨Õÿ×ÝÿûÀö€€°þ€„娀€Åÿÿ¿ÿÿŸ¿¨üÏÕ©Õ´¥«®ôÿÿÿ€€€€€€€€ªÕª•ºÿÿÿÿƒÕê¿À¾€ºÀþ€ˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€‚•‚ÿ¯ÿ‹ºÿÿÿÿÿÿÿÿÿÿÿÿëתկÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿŸ €€ Ñ‚€†Î€€€€¨€€€°ÿƒ€€øÓª•üÿèþÿÿÿÿÿ×ü߀€€€€€€€””ª•ºÿÇþÿÿÿÿµ€€€ºÀþƒ€Ð¿€€€úÿÿÿÿÿÿÿ¿×”‚ŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßú×þÕ¿õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€Á€€€€€€€€€€€€€€€€€€€€€€€€€€à€Ð€þÿ€€€€€€€€¨Õ€€ºÿÿŸ€€€€€ ƒ€ýƒÀŽ€€ÀŽ€€ÀŽ€€ÀΙ³×ԪѨÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ«õÕÞªÿÿÿÿÿ•¯ÕêÝÿÿ¿×üÿÿÿþú§ªÕŠÀϪÕê˨է¡ÔŠýëת̊ý›¿ŠÊªÕªÔªÕþÿªÕª€€€€€€€€Ñª•ŠºÿÿŸ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ъ¥‹Õú÷šºÿÿÿ·ÿÿÿÿÿÿÿÿÿÿªýÿÿÿÿß«ÕªôêתӪ×üÿÿÿê ‘‚„ˆÐ€Ñˆ‘¨Àˆ‘¢„¨”¢Ä¨Äˆ•õÿÿªõߪÝÒª«ÕªÕª€€€€€€€€€€€ÀªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕ‚€€€€€€ºÿÿŸ€…€ ‡ ƒ €ˆÀŽÀ‚ÀÀªõÀ‚Àÿÿ¿×ÀªÑª×ª×ªÕªª•ªõúÿŸóùÌ™ÌùÿÓœÌѪ֪ժժݩ×ÔªÕª€€€€€€€€€€€€ºúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€€ÐŠºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀÀ†Àþÿ¿×¨ÕªÕÕªÕŠº‡þÿŸþÿÀÿÿÆÂþÿÿÿÿÿÿÿÿÔªÕªÕª·µ¿×ÔªÕª€€€€€€€€€€€€º¿Å¨ÿÿÿÿ¿ÀŠ€ºÀŽÀþ¨€ªÕúÿÿÿÿÿÿÿ¿×€€€€ Õª•ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×¨ÕªÕŸÔŠ€€€€€€ €À€Å€€€€€€€ìúÓ¨ÕêÔªÕªÕÔªÕª€€€€€€€€‚€€•ºÿ€Õªÿÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿ«¥‰ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿÿÿûŸÅ€ð „õ¨ÕªÅðÿ¿ÿÿÏÿãÿ¿ÔëÕ¾ÔªýûûÓª€€€€€€€€¨€ª…ºÿûÿÿŸÔª¿À¾€ºÀþˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€‚ШÿªÿŸºÿÿÿÿÿÿÿÿÿÿÿÿûתտÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿߪ€ªÀŠ€€€†€€€€€€ˆ°ÿŸÕª½…€þïÿÿÿÿÿÿÿ÷ü§€€€€€€€€•Õª•ºÿÇüÿÿÿÿ¿€€ÀºÀþ‡€Ð¿€€€úÿÿÿÿÿÿÿ¿×€Š€¨ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßúÕÿ×¾õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ŒÂÿÿ€€€€€€€€Õª•ºÿÿŸ€€€€€ ƒ€ô€ÀŽ€€ÀŽ€€ÀŽ€€Àþÿ¿×ЪъÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ«ýÿÿªÿÿÿÿÿå«Õ®ýªÿ¿×üÿÿÿЪժєúϮժÕú쀈•€×«ý«õ¹Õî…¤…Õêÿµª»ú–ªÕª€€€€€€€€ÕŠÀŠº¿ÕŠ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†ÀÖª½×Ôª¥­ýïýŸ¹ÿßû¿þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ª×º„ªÕªÓ®×üÿÿÿꈑªÄˆÑˆÑˆ‘ªÄˆ‘¢Ä¨”¢Ä¨ÄˆÕòŸÕªžÕþ¯ßæªÕŠÕª€€€€€€€€€€€€ªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕ€€€€ÔŠ„€ºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×À‚Ô‚÷¯ÝšÚîãºÕªÕêÿÿÿÿÿÿÿÿÿÿÿÿÿÕªÖªÕªÕªÕ«×ÔªÕª€€€€€€€€€€€€ºêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€€ÕŠºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕÕªÕ‚ºÑªÕºÞªÀ¢ÕʪªÕªÕªÕªÕªÕªÕªÕ«Õ©õ¿×ÔªÕª€€€€€€€€€€€€ºÿÀªÿÿÿÿ¿À¾€ºÀŽÀþ¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€ªÕꞺÿÿÿÿÿÿÿÿ¿¸ðáùœ¼¸ð°ðƒçüÿÿÿÿÿÿÿ¿×¨ÕªÕÓ •êƒªÝª•ª…€ €€À€ÁÔªÕªÕª•ÔƒÁ¢Õ©Õ‚€€€ÔªÕª€€€€€€€€Š€ •ºÿ€Ðªÿÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿýÿºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ü«ýÿïÿû‡”Ï€€ð À’”¨€ õÿ‡þÿçÿÿÿŸíÿ™Ý”¬¨ÕªÕª€€€€€€€€€”ª”ºÿõÿÿÿЪ¼À¾€ºÀþˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€Š€€ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúתտýÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€Õª¢€ü€€€€€„€€°˜€€ð¿€€€ÿïÿÿÿÿÿÿÿÿ¼¯€€€€€€€€Ôª¥•ºÿßüÿÿÿÿ¿ÕªÕ¾ÕþתտժÕúÿÿÿÿÿÿÿ¿×ԪЪÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿߪÕÕÖªõÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€°†¶ƒàÿÿ€€€€€€€€ªÕ”€ºÿÿŸ€€€€€ ƒ€ô€ÀŽ€€ÀŽ€€ÀŽ€€Àþÿ¿×Ј…ŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ«ý«ÿêÿÿÿÿÿå«õªÝªý¿×üÿÿÿѪՔլÿ«ÕªÏ×ö• ÅªÕº×šÓâõëÔŠ¥…ÕÐåïõ÷Ϫժ€€€€€€€€Ð ÕŠºÿÿŸ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ô‚•Õÿ«õ‹ùî׫¿úÿÿÿÿÿÿÿÿÿÿàÿÿÿÿ÷¾Õª…ªÕªÛªÕüÿÿÿÕ‚”ª„ˆÐˆÁˆ‘¨Äˆ‘¢Ä¨”‚ĨĈĪժժժժªÕªÕʪ€€€€€€€€€€€€úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×€€€€Ô‚‚ºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€€”€ÿúÝ«ÖþôïÕªÕîÿÿ÷ÿÿÿÿÿÿÿÿÿÿÕªÔªÕºÕªõŸ×ÔªÕª€€€€€€€€€€€€º¨ÿçÿÿÿÿ¿€€À¿Àƒðÿ‡ €€€úÿÿÿÿÿÿÿ¿×€€€€€Ôª•ºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕÕª•ˆŠþÿÿ¿þÿ€ðÿ‹‚ÿÿÿÿÿÿÿÿ¿íéÔªÕªÕªÕª×ÔªÕª€€€€€€€€€€€€ºÿÑ¢Õúÿÿ¿À¾€ºÀŽÀþ¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€êÿÿŸºÿÿÿÿÿÿÿÿŸ³æÌñÌ™³æ¼æ³æüÿÿÿÿÿÿÿ¿×”ÕªÕ”ªÕ€„ªÝª…ª…€¡€€ ‚Ъժժ•ÔÈÕ¯µªÓ½…ÿ¤ÔªÕª€€€€€€€€ Õ¢•ºÿß‚ÀÈþÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿÿÿ„ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿªýÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ü«ýÿÏàƒ€Ÿ€€€ô€‘€Ðª€ õÿ‡þÿñÿÿÿÏÕûýïÿÿÿÿÿ€€€€€€€ª•€”ºÿôÿÿÿ‡¨µ€€€ºÀþ€À¾€€€þÿÿÿÿÿÿÿ¿×¨€ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúߪõ¿ýÿÿÿÿÿÿÿÿÿÿÿ¿×üëÿÿ€€”ˆ€ˆ€€€€Œ¨€€€€ÔŠÕ²˜€€ð¿€€Àÿïÿÿÿÿÿÿÿÿü¯€€€€€€€€Õ‚¤ºÿŸúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ÀªÕ‚ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßú¿Åú¿õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€€€€€€˜€€€€€€€€€€†€€€€€€€€ÀœÇ±ðÿꀀ€€€€€€¨Õ‚ŠºÿÿŸ€…€€€ ƒ€ô€ÀŽÀ‚ÀŽÀªÕŽÀ‚Àþÿ¿×ЪժÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿªýëÿÿÿÿÿý«õºÕºõ¿×üÿÿÿ……ÕªúßþԪю€×´Õ¢€¨Õª×ªÕªÕªÕªÕЪ­¥ÕªÕʪժ€€€€€€€€Õª•Šºßª•€€€ ‡ ƒ€€ÀŽ€€ÀŽ€€ü€€ÀªÕ¾×ÀŠ”ÊÕªÕ‹™«Ý®•úÿÿÿ¿¸æŒœÌ¹ê™Ÿüá߮ݪõªÔªÓ¦ÕüÿÿÿÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªªÕêªÕª€€€€€€€€€€€€úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×€€€€€€ÐŠºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€ •ÐßÿÿŠºÿﱪõêÿÿ×ÿÿÿÿÿÿÿÿÿÿÕªÖêժשµ»×ÔªÕª€€€€€€€€€€€€ºªý«ÿÿÿÿ¿€€€¾À‚Ðÿ‡ €€€úÿÿÿÿÿÿÿ¿×€€€€‘Õª•ºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕժŊðÿÿÿ¿þÿ€ðÿ‡‚ŸÿÿÿÿÿÿÿÿÍâ֪ժݪýý×ÔªÕª€€€€€€€€€€€€ºÿƒ Åêÿÿ¿À¾€ºÀŽÀþ¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€êÿÿÿÿÿÿÿÿÿŸ¿æÌáÌŸ³æ¼æ³æüÿÿÿÿÿÿÿ¿×ØÒêªÁªÕüÓêͪ…ª…€¡©… ‚ÒªÕêÕª•ÂŠ˜×ªÓ­ÿ¿«ÝªÕª€€€€€€€€ª•ª•ºÿŸˆ€ªõÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿÿÏšºÿÿÿÿÿÿÿÿÿÿÿÿÿתÕÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ü¿Õª›à€ÐŠÕ …Ü€Ô€€ˆÕª•õÿ¨ÕðÿÿÿïÓªµ§ÿªÅ¾êÿª€€€€€€€€ª¨¥•º¿ñÿÿÿÿª±€€€ºÀþ€À¾€€€úÿÿÿÿÿÿÿ¿×Ј€¨ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúÿªý¿ýÿÿÿÿÿÿÿÿÿÿÿ¿×ü«õÿ€€€€€€ Õ‚€€€€€€€€ÔªÕª€ð¿ªÕªÿïÿÿÿÿïÿÿÿüÿ€€€€€€€€Ð¢•ˆºÿÿúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×„¨Õ¢ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßê¿‘ú¯õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿŒ€à€€€À‡€€€ø»Àª€€€€€€ž€þЂ€€€Àí¶ã€øÿª€€€€€€€€¨•ª•ºÿÿŸ€€ … ƒ€ô€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×”ÕÚŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ¯ßªõûÿÿÿÿ¿ÕªÕêÕºÕ¿×üÿÿÿÕŠ •Õª…ý‰¨Š¨ÑªÑŠ…ªÔ¨ÑŠ…ªÕª¨ÕªÕª­¥ªÕŠÕªÕª€€€€€€€€Õ‚ˆºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€ÐŽ€€ô€€Ðþÿ¿×ÀªÅÊýîÕŠÖªõªÕîÿÿÿŸ³æ̙ϙ֙ÏùÌߪժժÕêÖ®ÕüÿÿÿÚªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕ¢ÕªÕª€€€€€€€€€€€€ºÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕª×€€€€€¨……ºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×ЪÔÿªßžºáÿŸ®Õ¾ÿÿ×þÿÿÿÿÿÿÿÿ¿õªÐúÁªÕªÕª×ÔªÕª€€€€€€€€€€€€ºªõ©ÿÿÿÿ¿€€€ºÀ†Ðÿƒ €€€úÿÿÿÿÿÿÿ¿×€€€€ Õª•ºÿÿŸ€€€€€ ƒ ÕŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕժЂªÕªÕºÔª€ Õ‚‚ŠÑªÕªÕªÕªÍêÓªÕöߪÿþ×ÔªÕª€€€€€€€€€€€€ºÿÇ„Õèÿÿ¿À¾€ºÀžÀþ€¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€ŸÓ™•ºÿÿÿÿÿÿÿÿÿ¸ðÌÁ¼œ³ø°æÃþÿÿÿÿÿÿÿ¿×èÒÖÊÔªõøƒÿ®ª€¡ª… Š‚ҪվתÕШ›íߪÓꦭծժ€€€€€€€€ª…ª•ºÿÿƒ€ªÔÿ¿À¾€ºÀþ€ª€º€ªÕÿÿÿÿÿÿÿÿ¿×€€€ˆÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ¿ÕªÕúÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÕ®³¬Ô€ˆÔª…ÞϪ•€€€À€ µÿ€Àúÿÿÿ÷×õ§ÿÿ¯•ýÿÿ€€€€€€€€Šª¥•ºÿáÿÿÿÿ‹µ€€€ºÀþƒ€À¾€€€úÿÿÿÿÿÿÿ¿×€¢Ð‚ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúÿºý¿ýÿÿÿÿÿÿÿÿÿÿÿ¿×üÿõÿÁªÕ Õ‚…ŠÀ€€€€€€‚€€€ Õò÷‡€€€îÇÿÿÿÿÿ€øÿ€€€€€€€€Õª…ŠºÿÿŸ€€ €€¨ƒ€ýƒÀŽ€€Ð€€ÀŽ€€Ðƒ‚¸×„ˆÑªÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿª¿‘ú«ýÿÿÿÿÿª×úÿÿÿ¿×üÿÿÿÿƒàƒ€ Ýñ©µõÿÿëÿýë‡Ààÿÿûÿªÿÿý¿³öýÿ³¦Õª€€€€€€€€Ð ÕŠºÿÿŸ€€ ‡ ƒ€ô€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×”­êªÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿÿÕªÕþÿÿÿÿ«Õ«ÕëÕºÕ¾×üÿÿÿŪժժժժժժժժժժժ¥ÕªÕª¨Õª•ªÕŠÕªÕª€€€€€€€€”€ÐˆºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€ÐŽ€€ô€€Ðþÿ¿×ԪՊߪÿ®ÕºÕú‘ê÷ÿÿŸ³æ̙ϙڙÏÿÌߪݪժժ֨ÕüÿÿÿÕªÚªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕÔêªÕª€€€€€€€ÿ \ No newline at end of file diff --git a/res/TITLE.HGR.UNPACKED/FIGHT.NIGHT b/res/TITLE.HGR.UNPACKED/FIGHT.NIGHT new file mode 100644 index 0000000..be74685 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/FIGHT.NIGHT differ diff --git a/res/TITLE.HGR.UNPACKED/FORMULA.1.RACER b/res/TITLE.HGR.UNPACKED/FORMULA.1.RACER new file mode 100644 index 0000000..89bdae2 --- /dev/null +++ b/res/TITLE.HGR.UNPACKED/FORMULA.1.RACER @@ -0,0 +1 @@ +€€€€€€€€€€€˜°þàÿù¿þÏÿóÿüŸÿçÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÅª‘ À€‚„€Õ¢Õˆ€ À€‘ „ˆÕ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Õª•¨ÕªÁªÕŠÔªÕ Õª…€€€€€€€€€€€€€€€€€‘¢Ô À ÅˆÐ€€•¢Ä¨Ñ‚ԨѢĈ•ªÔ¨€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øЀÀ‡õá—ø€ Á‚€€”€ð€€€Š€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õ‚€Š€ÐЀ€…¥Ë–Ѐ Á‚€€”€ €€€Š€€€€€€€€€€€€€€€€€€ž€ø€àÇ€€¼€€àÇ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€ÐÚ®¯•€€€Š •Ð€À‚­ÕŠèªÕÀ‚¨…€€ ÕÖë«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€¨ðჀ€¼¨€àÇ€€¼€ð€€€ž€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€´Õª Ô‚Š€¨¨ÕÊ‚­ÕŠ¨€ €€Õ´•€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ª€‚ĈтÁŠ•ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿÿþÿÿðÿÿ‡€¼ø€àÇ€€üÿÿ€€ÿÿ¿€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ À‚Ú ©¨€À‚…€€¨€Ð€€€€”€€€€€€€€€€€€€€€€€€ÿÿ—¨ÿÿ€€Ôÿ€ ýÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€ €€€‚€€€…Š€¨€ Á‚€€”€€ Á‚€€€€ˆ€€À€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øÐþÿ‡…Š”ø€ Á‚€€Ôÿÿ€€€Š€€€€€€€€€€ÐÚ®¯•€€€Àªø€àÃת•¼ÕªáƒÐŠ€€€ÕÖë«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€ÐР€…€”Ѐ Á‚€€”€Ð€€€€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õª…ªÕªÐªÕ‚…€”¨€ Á‚€€ÔªÕ€€€Õª•€€€€€€€€€€€€€€€€€…€¼ø€ Á‡€€¼€€àƒ€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€Õª©ÐÕª…€€èª€ÀÖª…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿ‡€ž€¨ðÀ‚ß¾½¨€àÇ€€¼€Ð€€€€ž€€€€€€€€€€ ÕªÕ‚€€€Š”€Ð€À‚…€€¨€€À‚…€€€€¨ÕªÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ «Õ‚Š”¨¨€À‚…€€èªÕ€€€€”€€€€€€€€€€Ðúÿ¯…€€€…࿨€ ÁúÿŸÔÿÿ¡ø€€€Õø¿ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€€€€€€€€€ÀŸ¿þÌùóçÏ™¿€ÃŸ¿þ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÅª‘ ÔŠÕ¢À€Õ¢Õ¨•ªÅ€ÑªÔŠÕ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ø¿àÀçÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€‘ªÔ¨Ñ¢ÅˆÐ „€•¢Ô¨Ñ‚ԨѢĊ‘ª„¨€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”¨€à€€”€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€”¨€À‚€€”€€ €Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øЀÀ‡õá—ø€ Á‚€€”€ð€€€Š€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õ‚€Š€ÐЀ€…¥Ë–Ѐ Á‚€€”€ €€€Š€€€€€€€€€€ðÿÿÿƒ€€€ž€ø€àÇ€€¼€€àÇ€€€€üÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€Ðâÿ©…€€€Š •Ð€À‚­ÕŠèªÕÀ‚¨…€€€Õ઀€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€À³æÌ™ÃáÀ™ŒàÙ³à€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚À€ À€¢À€ Àˆ€ À€‘ „ˆ€€€€€€€€€€€€€€€Š€ªÄ¨Ñ¢Åˆ•ŠÔ¨Ñ¢…€€ª€ªÄ¨Ñ¢ÅŠ€€€€€€€€€€€€€€€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€ÿÿ¿øÿÿÃÿÿŸüÿÿáÿÿ€€€€€€€€€€€€€€€€€‘¢ À Àˆ¢Ä€¢Ä €„  Äˆ‘‚„ˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€…€¨Ð€ …€€¨€€À‚€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿÿþÿÿðÿÿ‡€¼ø€àÇ€€üÿÿ€€ÿÿ¿€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ À‚Ú ©¨€À‚…€€¨€Ð€€€€”€€€€€€€€€€€€€€€€€€ÿÿ—¨ÿÿ€€Ôÿ€ ýÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€ðÿÿÿƒ€€€…Š€¨€ Á‚€€”€€ Á‚€€€ ­˜°€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€Ð‚¿¨…€€€Àªø€àÃת•¼ÕªáƒÐŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€êÿÿЀü‡…€”øÿ¿ÁúÿŸ”€Ð€€€ÿë¿€€€€€€€€€€€€€€€€€À³þ°øÃáÌŸŒ€ÃŸ¿ø€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ€ªÔ¨Ñ¢ÅŠ•ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚À€Ð À€‚‘€ Àˆ€ Àˆ‘ „ˆ€€€€€€€€€€€€€€€ €ˆÔ  ÄŠ¢ˆÁ €€€ €‚Ĉ‘ „‚€€€€€€€€€€€€€€€€€€€€€€€€€˜°þàÿù¿þÏÿóÿüŸÿçÿ€€€€€€€€€€€€€€€€€€€€€€Õª•¨ÕªÁªÕŠÔªÕ Õª…€€€€€€€€€€€€€€€€€•¢ À ÀŠÐ€€¢Ä €„  Åˆ‘‚„ˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õª…ªÕªÐªÕ‚…€”¨€ Á‚€€ÔªÕ€€€Õª•€€€€€€€€€€€€€€€€€…€¼ø€ Á‡€€¼€€àƒ€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€Õª©ÐÕª…€€èª€ÀÖª…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€€àÀÁ—€€€Š”€Ð€À‚…€€¨€€À‚…€€€ ­ÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€¨ðჀ€¼¨€àÇ€€¼€ð€€€ž€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€´Õª Ô‚Š€¨¨ÕÊ‚­ÕŠ¨€ €€Õ´•€€€€€€€€€€€€€€€€€À³†°øÀáÌ™Œ€ƒ˜³à€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¢Äˆ‘€‚‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€¢ÅŠ¢À€Õ‚„€Õ¢À¨ ÀˆÑªÔŠ•€€€€€€€€€€€€€€€ˆ”ˆÔ Ð ÅŠ…¢¨Á €€¨”Š¨Ñ …‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€•ª À ÁŠ‚€ªÔ Ð‚” Ð¢ÅŠ‘¢„¨€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”¨€à€€”€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€”¨€À‚€€”€€ €Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øÐþÿ‡…Š”ø€ Á‚€€Ôÿÿ€€€Š€€€€€€€€€€€øÿ×—€€€Àªø€àÃת•¼ÕªáƒÐŠ€€ Õþÿ«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€ÐР€…€”Ѐ Á‚€€”€Ð€€€€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€ÀŸ¿†°˜óçÏ™Œà˜¿þ€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ”ªÔ¨‘€‚Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚Ä€¨À€‘€„€€¢Àˆ€ À¢‘ Ä€€€€€€€€€€€€€€€€‚€ˆÔ  Áˆ¢ˆÁ €€€ €‚Ĉ ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿÿ¿øÿÿÃÿÿŸüÿÿáÿÿ€€€€€€€€€€€€€€€€€•Š À Àˆ‚Á€¢” €‚„ €¢Äˆ‘¢„ˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€…€¨Ð€ …€€¨€€À‚€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿ‡€ž€¨ðÀ‚ß¾½¨€àÇ€€¼€Ð€€€€ž€€€€€€€€€€€€€€€€€€Š”€Ð€À‚…€€¨€€À‚…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ «Õ‚Š”¨¨€À‚…€€èªÕ€€€€”€€€€€€€€€€Ðúÿ¯•€€€…࿨€ ÁúÿŸÔÿÿ¡ø€€ Õþÿ«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€êÿÿЀü‡…€”øÿ¿ÁúÿŸ”€Ð€€€ÿë¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ€‚”ˆ‘€‚‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚Ä€ À€Á€„€€¢Àˆ€ À¢‘ „‚€€€€€€€€€€€€€€€ª€ªÄ Ð¢Äˆ•ŠÔˆÁ …€€ª€ªÄˆÐ¢„‚€€€€€€€€€€€€€€ \ No newline at end of file diff --git a/res/TITLE.HGR.UNPACKED/FS2 b/res/TITLE.HGR.UNPACKED/FS2 new file mode 100644 index 0000000..a39a6e9 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/FS2 differ diff --git a/res/TITLE.HGR.UNPACKED/FUJI.SPEED.WAY b/res/TITLE.HGR.UNPACKED/FUJI.SPEED.WAY new file mode 100644 index 0000000..8463f59 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/FUJI.SPEED.WAY differ diff --git a/res/TITLE.HGR.UNPACKED/HARDBALL b/res/TITLE.HGR.UNPACKED/HARDBALL new file mode 100644 index 0000000..22929f3 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/HARDBALL differ diff --git a/res/TITLE.HGR.UNPACKED/INTL.GRAN.PRIX b/res/TITLE.HGR.UNPACKED/INTL.GRAN.PRIX new file mode 100644 index 0000000..faf6a14 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/INTL.GRAN.PRIX differ diff --git a/res/TITLE.HGR.UNPACKED/INTL.HOCKEY b/res/TITLE.HGR.UNPACKED/INTL.HOCKEY new file mode 100644 index 0000000..da8dd0b Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/INTL.HOCKEY differ diff --git a/res/TITLE.HGR.UNPACKED/KARATE.CHAMP b/res/TITLE.HGR.UNPACKED/KARATE.CHAMP new file mode 100644 index 0000000..3220abd Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/KARATE.CHAMP differ diff --git a/res/TITLE.HGR.UNPACKED/ONE.ON.ONE b/res/TITLE.HGR.UNPACKED/ONE.ON.ONE new file mode 100644 index 0000000..a29809b Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/ONE.ON.ONE differ diff --git a/res/TITLE.HGR.UNPACKED/POOL b/res/TITLE.HGR.UNPACKED/POOL new file mode 100644 index 0000000..3f866f4 --- /dev/null +++ b/res/TITLE.HGR.UNPACKED/POOL @@ -0,0 +1 @@ +ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€üùÿùƒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ïÿ‡øÿU*U*U*U*U*U*ÿ¿€€ÿÿU*U*U*U*U*U*ÿ‡øÿý*uŠ€€€Ó¶åøãÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©ÍŸö¿¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý*uŠ€€€ÓÆŸÓš¿€€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‡øÿU*U*U*U*U*U*ÿÿàÿÿU*U*U*U*U*U*ÿ‡øÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ü±å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ü€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€ü€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€€˜Õ׌€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ïÿðÿU*U*U*U*U*U*ÿŸ€€þÿU*U*U*U*U*U*ÿƒàÿý*uŠ€€€ÓžÕ°ªƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©½ê†ìÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€üý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÕŒ€Óš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŸüÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿþÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«¶å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«†€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€ü±åÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ïÿ€àÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ€€þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿý*uŠ€€€üùÿùóÿƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€€«¶êøãÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U€¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€þý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÿÏŸÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«ÆŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«†€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÕªU*U*U*U*U*U*ÕªÕªÕªU*U*U*U*U*U*ÕªÕªÕ*uŠ€€€Ó¶åÓš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ï¿€Àÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€üÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿý*uŠ€€€€˜Õ‡¼ªó‡€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý€€€€€€€€ïŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€þý*uŠ€€€«ÞÊ°ªó‡€€€€€€€€€€€€€€€€€€€€€€€Ô+U€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€þý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÕ¼åÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€ÓÆŸÓš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ï¿€€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€ÿý*uŠ€€€ü±åöíÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿý€€€€€€€€ï¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿý*uŠ€€€üÙÊùóÿƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€üÿÿÿÿÿÿÿÿÿÿÿÿÿ¿€€ÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€Ó¶åøƒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UªÕªÕªU*U*U*U*U*U*ÕªÕªÕªU*U*U*U*U*U*ÕªÕªÕ€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€À©ÍŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€ÀÕŒ€Óš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ïŸ€€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€þý*uŠ€€€«¶å›ûÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€þý€€€€€€€€ïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý*uŠ€€€€ØÊ×¼ªƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€ÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ€€þÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ÓžÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€À©½å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€ÀÿÏŸÖŒ¿€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ïŸ€€¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€þý*uŠ€€€«ÆŸó™¿¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý*uŠ€€€ü±êÖìÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€àÿU*U*U*U*U*U*ÿŸ€€þÿU*U*U*U*U*U*ÿÀÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€üùÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«†€€€€€€€€€€€€€€€øƒ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€øƒ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«¶å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿŸüÿU*U*U*U*U*U*ÿÿàÿÿU*U*U*U*U*U*ÿþÿý*uŠ€€ÀÕ¼åÖìÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©€››€¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý*uŠ€€€Ó¶êÓúÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿðÿU*U*U*U*U*U*ÿ¿€€ÿÿU*U*U*U*U*U*ÿƒàÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€˜Õ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«†€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«žÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ \ No newline at end of file diff --git a/res/TITLE.HGR.UNPACKED/SHUFFLEBOARD b/res/TITLE.HGR.UNPACKED/SHUFFLEBOARD new file mode 100644 index 0000000..6a502bc Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/SHUFFLEBOARD differ diff --git a/res/TITLE.HGR.UNPACKED/SKI.CRAZED b/res/TITLE.HGR.UNPACKED/SKI.CRAZED new file mode 100644 index 0000000..a89d597 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/SKI.CRAZED differ diff --git a/res/TITLE.HGR.UNPACKED/SOLO.FLIGHT b/res/TITLE.HGR.UNPACKED/SOLO.FLIGHT new file mode 100644 index 0000000..82e521c Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/SOLO.FLIGHT differ diff --git a/res/TITLE.HGR.UNPACKED/SPDWAY.CLASSIC b/res/TITLE.HGR.UNPACKED/SPDWAY.CLASSIC new file mode 100644 index 0000000..ec6f4a6 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/SPDWAY.CLASSIC differ diff --git a/res/TITLE.HGR.UNPACKED/SUMMER.GAMES b/res/TITLE.HGR.UNPACKED/SUMMER.GAMES new file mode 100644 index 0000000..553ae4d Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/SUMMER.GAMES differ diff --git a/res/TITLE.HGR.UNPACKED/SUMMER.GAMES.II b/res/TITLE.HGR.UNPACKED/SUMMER.GAMES.II new file mode 100644 index 0000000..f73916c Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/SUMMER.GAMES.II differ diff --git a/res/TITLE.HGR.UNPACKED/SUPER.HUEY b/res/TITLE.HGR.UNPACKED/SUPER.HUEY new file mode 100644 index 0000000..344ff8d Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/SUPER.HUEY differ diff --git a/res/TITLE.HGR.UNPACKED/SUPER.ICEHOCKEY b/res/TITLE.HGR.UNPACKED/SUPER.ICEHOCKEY new file mode 100644 index 0000000..e3c41e8 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/SUPER.ICEHOCKEY differ diff --git a/res/TITLE.HGR.UNPACKED/TAG.TEAM b/res/TITLE.HGR.UNPACKED/TAG.TEAM new file mode 100644 index 0000000..51d7cba Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/TAG.TEAM differ diff --git a/res/TITLE.HGR.UNPACKED/THE.DAM.BUSTERS b/res/TITLE.HGR.UNPACKED/THE.DAM.BUSTERS new file mode 100644 index 0000000..c898706 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/THE.DAM.BUSTERS differ diff --git a/res/TITLE.HGR.UNPACKED/TOMAHAWK b/res/TITLE.HGR.UNPACKED/TOMAHAWK new file mode 100644 index 0000000..9eb6191 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/TOMAHAWK differ diff --git a/res/TITLE.HGR.UNPACKED/TRACK.AND.FIELD b/res/TITLE.HGR.UNPACKED/TRACK.AND.FIELD new file mode 100644 index 0000000..6f0ff07 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/TRACK.AND.FIELD differ diff --git a/res/TITLE.HGR.UNPACKED/WINTER.GAMES b/res/TITLE.HGR.UNPACKED/WINTER.GAMES new file mode 100644 index 0000000..666d2d3 Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/WINTER.GAMES differ diff --git a/res/TITLE.HGR.UNPACKED/WORLD.KARATE b/res/TITLE.HGR.UNPACKED/WORLD.KARATE new file mode 100644 index 0000000..0e0404a Binary files /dev/null and b/res/TITLE.HGR.UNPACKED/WORLD.KARATE differ diff --git a/res/TITLE.HGR.UNPACKED/_FileInformation.txt b/res/TITLE.HGR.UNPACKED/_FileInformation.txt new file mode 100644 index 0000000..00a5107 --- /dev/null +++ b/res/TITLE.HGR.UNPACKED/_FileInformation.txt @@ -0,0 +1,36 @@ +# This file is automatically generated + +AMER.CHALLENGE=Type(06),AuxType(4000),Access(C3) +AUTOBAHN=Type(06),AuxType(4000),Access(C3) +BASEBALL=Type(06),AuxType(4000),Access(C3) +BLACK.BELT=Type(06),AuxType(4000),Access(C3) +BOP.N.WRESTLE=Type(06),AuxType(4000),Access(C3) +CHAMP.BSKETBALL=Type(06),AuxType(4000),Access(C3) +CHAMP.WRESTLE=Type(06),AuxType(4000),Access(C3) +CMPTR.FOOSBALL=Type(06),AuxType(4000),Access(C3) +DIVE.BOMBER=Type(06),AuxType(4000),Access(C3) +FIGHT.NIGHT=Type(06),AuxType(4000),Access(C3) +FORMULA.1.RACER=Type(06),AuxType(4000),Access(C3) +FS2=Type(06),AuxType(4000),Access(C3) +FUJI.SPEED.WAY=Type(06),AuxType(4000),Access(C3) +HARDBALL=Type(06),AuxType(4000),Access(C3) +INTL.GRAN.PRIX=Type(06),AuxType(4000),Access(C3) +INTL.HOCKEY=Type(06),AuxType(4000),Access(C3) +KARATE.CHAMP=Type(06),AuxType(4000),Access(C3) +ONE.ON.ONE=Type(06),AuxType(4000),Access(C3) +POOL=Type(06),AuxType(4000),Access(C3) +SHUFFLEBOARD=Type(06),AuxType(4000),Access(C3) +SKI.CRAZED=Type(06),AuxType(4000),Access(C3) +SOLO.FLIGHT=Type(06),AuxType(4000),Access(C3) +SPDWAY.CLASSIC=Type(06),AuxType(4000),Access(C3) +SUMMER.GAMES=Type(06),AuxType(4000),Access(C3) +SUMMER.GAMES.II=Type(06),AuxType(4000),Access(C3) +SUPER.HUEY=Type(06),AuxType(4000),Access(C3) +SUPER.ICEHOCKEY=Type(06),AuxType(4000),Access(C3) +TAG.TEAM=Type(06),AuxType(4000),Access(C3) +THE.DAM.BUSTERS=Type(06),AuxType(4000),Access(C3) +TOMAHAWK=Type(06),AuxType(4000),Access(C3) +TRACK.AND.FIELD=Type(06),AuxType(4000),Access(C3) +WINTER.GAMES=Type(06),AuxType(4000),Access(C3) +WORLD.KARATE=Type(06),AuxType(4000),Access(C3) +_FileInformation.txt=Type(06),AuxType(4000),Access(C3) diff --git a/res/TITLE.HGR/AMER.CHALLENGE b/res/TITLE.HGR/AMER.CHALLENGE index 01bfe55..766730e 100644 Binary files a/res/TITLE.HGR/AMER.CHALLENGE and b/res/TITLE.HGR/AMER.CHALLENGE differ diff --git a/res/TITLE.HGR/AUTOBAHN b/res/TITLE.HGR/AUTOBAHN index 89bd2e6..f78e234 100644 Binary files a/res/TITLE.HGR/AUTOBAHN and b/res/TITLE.HGR/AUTOBAHN differ diff --git a/res/TITLE.HGR/BASEBALL b/res/TITLE.HGR/BASEBALL index 4560b70..7a019f6 100644 Binary files a/res/TITLE.HGR/BASEBALL and b/res/TITLE.HGR/BASEBALL differ diff --git a/res/TITLE.HGR/BLACK.BELT b/res/TITLE.HGR/BLACK.BELT index 539c20b..08c1a69 100644 Binary files a/res/TITLE.HGR/BLACK.BELT and b/res/TITLE.HGR/BLACK.BELT differ diff --git a/res/TITLE.HGR/BOP.N.WRESTLE b/res/TITLE.HGR/BOP.N.WRESTLE index 4154365..2179aef 100644 Binary files a/res/TITLE.HGR/BOP.N.WRESTLE and b/res/TITLE.HGR/BOP.N.WRESTLE differ diff --git a/res/TITLE.HGR/CHAMP.BSKETBALL b/res/TITLE.HGR/CHAMP.BSKETBALL index c7fd83a..1eba1f4 100644 Binary files a/res/TITLE.HGR/CHAMP.BSKETBALL and b/res/TITLE.HGR/CHAMP.BSKETBALL differ diff --git a/res/TITLE.HGR/CHAMP.WRESTLE b/res/TITLE.HGR/CHAMP.WRESTLE index 18ff44b..adb7b91 100644 Binary files a/res/TITLE.HGR/CHAMP.WRESTLE and b/res/TITLE.HGR/CHAMP.WRESTLE differ diff --git a/res/TITLE.HGR/CMPTR.FOOSBALL b/res/TITLE.HGR/CMPTR.FOOSBALL index 2433cb5..47b8a74 100644 Binary files a/res/TITLE.HGR/CMPTR.FOOSBALL and b/res/TITLE.HGR/CMPTR.FOOSBALL differ diff --git a/res/TITLE.HGR/DIVE.BOMBER b/res/TITLE.HGR/DIVE.BOMBER index f74c00b..3f566d0 100644 --- a/res/TITLE.HGR/DIVE.BOMBER +++ b/res/TITLE.HGR/DIVE.BOMBER @@ -1 +1 @@ -€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÁªÅŠºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€ÐŽ€€ô€€Ðþÿ¿×ÄȪ«×ªÕªÖªõ«ÕêýÿÿŸ°æŒž¼¾æ™¿üÀ׫ժݪվժÕüÿÿÿ€€€€€€€€€€€€ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€ŠÕŠºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€Ô¢ÕݪýŸºøÿð¿®ÕûÿÿÇøÿÿÿÿÿÿÿÿ¿õªÁúѪզթ×ÔªÕª€€€€€€€€€€€€º«Õ¡ÿÿÿÿ¿€€€ºÀ†Ðÿƒ €€€úÿÿÿÿÿÿÿ¿×€€€€ Õª•ºÿÿŸ€€ €€¨ƒàÿ‹ÀŽ€€ÐŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕÕŠÕˆªÕªÕªÔª€€€€‚ŠÕªÕªÕªÕªÏê󪵪ϪժÕÔªÕª€€€€€€€€€€€€ºÿ¯ Ò¢ÿÿ¿À¾€ºÀžÀþ€¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€ÿôß›ºÿÿÿÿÿÿÿÿÿ³þ̉ü™³æ¼æ³žÿÿÿÿÿÿÿÿ¿×誩ÕÕªõ·ÕŽƒ†¶ª…€€©Åª‰‚‚ùÿ¿ÿ¿ÕЪùïîÛõ¨½¨íÔÿÿÿ€€€€€€€€ Õª•ºÿÿÿ¯ •ÿ¿À¾€ºÀþ€ˆ€º€úÿÿÿÿÿÿÿÿÿ¿×€€ÐªÿÿÓšºÿÿÿÿÿÿÿÿÿÿÿÿ¯ßªõëÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿç¡Á£…ˆ€Š€Ž˜€€€€€À€ µÿ€€úÿÿÿóϪíÿÿÿÿÿÿýÿ€€€€€€€€ª…ª•ºÿÓÿÿÿÿ¯µ€€€ºÀþƒ€À¾€€€úÿÿÿÿÿÿÿ¿×€¢‘‚ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßêÿºý¯õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÕÿ•€Ð€ÐªÕªÕªÕ€€€€€€€€€€€€¨ÕªÕªÕîÕª€€€€€øÿ€€€€€€€€¨ŠºÿÿŸ€€€€€ ƒ€ýƒÀŽ€€ÀŽ€€ÀŽ€€ÀΙ³×€ªÕªÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿª½úªýÿÿÿÿÇþÕªýÿÿ¿×üÿÿÿ½†Õþ¨ÕÔ̪ÕúŸÔþ…Õ¨õÿÔÿÿŸõ‡õÿÿÿŸõÿÿÿÿ¯Õª€€€€€€€€…ÕŠºÿÿŸ€€ ‡ ƒ€ô€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ôª©©ßþÿŸºÿÿÿÿÿÿÿÿÿÿÿÿÿÕªÕþÿÿÿÿºÕªÕªÕªÑ¾×üÿÿÿÔ‚”‚„ˆÐ Á€”¨Ð ‘€…Š‚„ª„ŠÔŠªÕê§ÕªÕªÕ¨ÕªÕª€€€€€€€€€€€ÔªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕª€€€ÕªÕŠºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€Ð€€ô€€Ðÿÿ¿×êÔ¢ÕÕªÕŠÙªŸÊÕºÕþÿŸ³æÌ™Ïùà™ÿùÌתիݪժժ×ü®Õª€€€€€€€€€€€€ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€•Ô”ºÿÿŸ€€ ‡ ƒ ŠÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€ÕªÕߪ՚Šÿß¿úÝúÿÿÇøÿÿÿÿÿÿÿÿ¿õªõêժݟõºÓÔªÕª€€€€€€€€€€€€º¯Õ¢ÿÿÿÿ¿€€€ºÀ†Ðÿƒ¨€€€úÿÿÿÿÿÿÿ¿×€€€€ Õª…ºÿÿߪժߪÕê×êÿ¯Õ®ÕªÕ¯ÕªÕ®Õ®Õþÿ¿×¨ÕªÕý§ŠªÕ¨ÕªÔŠ€ ”ÒŠŠÕªÕªÕªÕª±êö«Õ©ÍªÕªÕÔªÕª€€€€€€€€€€€€ºÿŸ¨Òªÿÿ¿À¾€ºÀžÀþ€º€€ðÿÿÿÿÿÿÿÿ¿×€€€€þû¦•ºÿÿÿÿÿÿÿÿŸ³þ̙̙³æ¼æ³žÿÿÿÿÿÿÿÿ¿×èÓêÕÕêû€†°þ€„¥¨ˆ€Âÿÿ¿ÿÿ¿Æªùï쨕¹ôŽÅôÿÿÿ€€€€€€€€¨Õª•ºÿÿÿ¿€•ü¿À¾€ºÀþ€ˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€€”ˆýÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿëתÕïÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ£Õ«ÔŠ„¨…€À€€€À€Àª•µÿ€€úÿÿÿøߪëÿÿÿÿÿßüÿ€€€€€€€€Š ª•ºÿ—ÿÿÿÿ¿µ€€€ºÀþƒ€Ð¿€€€úÿÿÿÿÿÿÿ¿×€ªÐ¨ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßêßþõ¯õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€Àª…€€€€€€€€€€€€€€€€€€€€€€€€ª…€€€€€Ð‚üÿ€€€€€€€€ÀÄЊºÿÿŸ€€€€€ ƒ€ýƒÀŽ€€ÀŽ€€ÀŽ€€ÀΙ³×ÀŠÕŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿªµ‘Úªýÿÿÿÿ¯ÝªÕÿÿ¿×üÿÿÿªÕªÁŠÍêÕŠ ýë ‡ŽÐ¯Õþÿ§õ«þúõïêê©Õÿ¯žÕª€€€€€€€€ÕªÕŠºÿÿŸ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ôª¥‹õ«ÿŸºÿÿÿÿÿÿÿÿÿÿÿÿÿתÕÿÿÿÿߪժժ×êѺ×üÿÿÿÔˆ‘¢ÄˆÑˆÑˆ‘ªÄˆ‘¢Ä¨”¢Ä¨ÄˆÕÿÿïêÿժժŪժժ€€€€€€€€€€€ÐªªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕª•ÕŠ€€€€€€ºÿÿŸ€€à ‡ ƒ €ˆÀŽ€€ð€€ô€€ðÿÿ¿×¨µÑ”ÕêתÕêרժÝûÿŸ³æÌ™Ïùÿ™ÏùÌת׫ժժµª×ÔªÕª€€€€€€€€€€€€ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€€À”ºÿÿŸ€€ ‡ ƒ ŠÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿× ÕªÕÕªÕŠ°ÿñÿ¿ÚÕëÿÿ×àÿÿÿÿÿÿÿÿÿÕªÕªÕªÕŽµ·×ÔªÕª€€€€€€€€€€€€ºŸÕªÿÿÿÿ¿€€€ºÀ†Àþƒ¨€€€úÿÿÿÿÿÿÿ¿×€€€€ªÕªŠºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×¨ÕªÕÿøÓŠªÕ¨ÕŠÐŠ€ ”‚¨ŠÕªÕªÕªÕª™šÕ¨í¯ÕªÕªÕÔªÕª€€€€€€€€€€€”ºÿ€Õªÿÿ¿À¾€ºÀž€ú€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿÿÿŸºÿÿÿÿÿÿÿÿ¿¸þṜ¼¸æ°ðƒŸÿÿÿÿÿÿÿÿ¿×¨Õÿ×ÝÿûÀö€€°þ€„娀€Åÿÿ¿ÿÿŸ¿¨üÏÕ©Õ´¥«®ôÿÿÿ€€€€€€€€ªÕª•ºÿÿÿÿƒÕê¿À¾€ºÀþ€ˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€‚•‚ÿ¯ÿ‹ºÿÿÿÿÿÿÿÿÿÿÿÿëתկÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿŸ €€ Ñ‚€†Î€€€€¨€€€°ÿƒ€€øÓª•üÿèþÿÿÿÿÿ×ü߀€€€€€€€””ª•ºÿÇþÿÿÿÿµ€€€ºÀþƒ€Ð¿€€€úÿÿÿÿÿÿÿ¿×”‚ŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßú×þÕ¿õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€Á€€€€€€€€€€€€€€€€€€€€€€€€€€à€Ð€þÿ€€€€€€€€¨Õ€€ºÿÿŸ€€€€€ ƒ€ýƒÀŽ€€ÀŽ€€ÀŽ€€ÀΙ³×ԪѨÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ«õÕÞªÿÿÿÿÿ•¯ÕêÝÿÿ¿×üÿÿÿþú§ªÕŠÀϪÕê˨է¡ÔŠýëת̊ý›¿ŠÊªÕªÔªÕþÿªÕª€€€€€€€€Ñª•ŠºÿÿŸ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ъ¥‹Õú÷šºÿÿÿ·ÿÿÿÿÿÿÿÿÿÿªýÿÿÿÿß«ÕªôêתӪ×üÿÿÿê ‘‚„ˆÐ€Ñˆ‘¨Àˆ‘¢„¨”¢Ä¨Äˆ•õÿÿªõߪÝÒª«ÕªÕª€€€€€€€€€€€ÀªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕ‚€€€€€€ºÿÿŸ€…€ ‡ ƒ €ˆÀŽÀ‚ÀÀªõÀ‚Àÿÿ¿×ÀªÑª×ª×ªÕªª•ªõúÿŸóùÌ™ÌùÿÓœÌѪ֪ժժݩ×ÔªÕª€€€€€€€€€€€€ºúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€€ÐŠºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀÀ†Àþÿ¿×¨ÕªÕÕªÕŠº‡þÿŸþÿÀÿÿÆÂþÿÿÿÿÿÿÿÿÔªÕªÕª·µ¿×ÔªÕª€€€€€€€€€€€€º¿Å¨ÿÿÿÿ¿ÀŠ€ºÀŽÀþ¨€ªÕúÿÿÿÿÿÿÿ¿×€€€€ Õª•ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×¨ÕªÕŸÔŠ€€€€€€ €À€Å€€€€€€€ìúÓ¨ÕêÔªÕªÕÔªÕª€€€€€€€€‚€€•ºÿ€Õªÿÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿ«¥‰ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿÿÿûŸÅ€ð „õ¨ÕªÅðÿ¿ÿÿÏÿãÿ¿ÔëÕ¾ÔªýûûÓª€€€€€€€€¨€ª…ºÿûÿÿŸÔª¿À¾€ºÀþˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€‚ШÿªÿŸºÿÿÿÿÿÿÿÿÿÿÿÿûתտÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿߪ€ªÀŠ€€€†€€€€€€ˆ°ÿŸÕª½…€þïÿÿÿÿÿÿÿ÷ü§€€€€€€€€•Õª•ºÿÇüÿÿÿÿ¿€€ÀºÀþ‡€Ð¿€€€úÿÿÿÿÿÿÿ¿×€Š€¨ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßúÕÿ×¾õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ŒÂÿÿ€€€€€€€€Õª•ºÿÿŸ€€€€€ ƒ€ô€ÀŽ€€ÀŽ€€ÀŽ€€Àþÿ¿×ЪъÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ«ýÿÿªÿÿÿÿÿå«Õ®ýªÿ¿×üÿÿÿЪժєúϮժÕú쀈•€×«ý«õ¹Õî…¤…Õêÿµª»ú–ªÕª€€€€€€€€ÕŠÀŠº¿ÕŠ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†ÀÖª½×Ôª¥­ýïýŸ¹ÿßû¿þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ª×º„ªÕªÓ®×üÿÿÿꈑªÄˆÑˆÑˆ‘ªÄˆ‘¢Ä¨”¢Ä¨ÄˆÕòŸÕªžÕþ¯ßæªÕŠÕª€€€€€€€€€€€€ªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕ€€€€ÔŠ„€ºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×À‚Ô‚÷¯ÝšÚîãºÕªÕêÿÿÿÿÿÿÿÿÿÿÿÿÿÕªÖªÕªÕªÕ«×ÔªÕª€€€€€€€€€€€€ºêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€€ÕŠºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕÕªÕ‚ºÑªÕºÞªÀ¢ÕʪªÕªÕªÕªÕªÕªÕªÕ«Õ©õ¿×ÔªÕª€€€€€€€€€€€€ºÿÀªÿÿÿÿ¿À¾€ºÀŽÀþ¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€ªÕꞺÿÿÿÿÿÿÿÿ¿¸ðáùœ¼¸ð°ðƒçüÿÿÿÿÿÿÿ¿×¨ÕªÕÓ •êƒªÝª•ª…€ €€À€ÁÔªÕªÕª•ÔƒÁ¢Õ©Õ‚€€€ÔªÕª€€€€€€€€Š€ •ºÿ€Ðªÿÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿýÿºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ü«ýÿïÿû‡”Ï€€ð À’”¨€ õÿ‡þÿçÿÿÿŸíÿ™Ý”¬¨ÕªÕª€€€€€€€€€”ª”ºÿõÿÿÿЪ¼À¾€ºÀþˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€Š€€ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúתտýÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€Õª¢€ü€€€€€„€€°˜€€ð¿€€€ÿïÿÿÿÿÿÿÿÿ¼¯€€€€€€€€Ôª¥•ºÿßüÿÿÿÿ¿ÕªÕ¾ÕþתտժÕúÿÿÿÿÿÿÿ¿×ԪЪÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿߪÕÕÖªõÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€°†¶ƒàÿÿ€€€€€€€€ªÕ”€ºÿÿŸ€€€€€ ƒ€ô€ÀŽ€€ÀŽ€€ÀŽ€€Àþÿ¿×Ј…ŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ«ý«ÿêÿÿÿÿÿå«õªÝªý¿×üÿÿÿѪՔլÿ«ÕªÏ×ö• ÅªÕº×šÓâõëÔŠ¥…ÕÐåïõ÷Ϫժ€€€€€€€€Ð ÕŠºÿÿŸ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ô‚•Õÿ«õ‹ùî׫¿úÿÿÿÿÿÿÿÿÿÿàÿÿÿÿ÷¾Õª…ªÕªÛªÕüÿÿÿÕ‚”ª„ˆÐˆÁˆ‘¨Äˆ‘¢Ä¨”‚ĨĈĪժժժժªÕªÕʪ€€€€€€€€€€€€úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×€€€€Ô‚‚ºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€€”€ÿúÝ«ÖþôïÕªÕîÿÿ÷ÿÿÿÿÿÿÿÿÿÿÕªÔªÕºÕªõŸ×ÔªÕª€€€€€€€€€€€€º¨ÿçÿÿÿÿ¿€€À¿Àƒðÿ‡ €€€úÿÿÿÿÿÿÿ¿×€€€€€Ôª•ºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕÕª•ˆŠþÿÿ¿þÿ€ðÿ‹‚ÿÿÿÿÿÿÿÿ¿íéÔªÕªÕªÕª×ÔªÕª€€€€€€€€€€€€ºÿÑ¢Õúÿÿ¿À¾€ºÀŽÀþ¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€êÿÿŸºÿÿÿÿÿÿÿÿŸ³æÌñÌ™³æ¼æ³æüÿÿÿÿÿÿÿ¿×”ÕªÕ”ªÕ€„ªÝª…ª…€¡€€ ‚Ъժժ•ÔÈÕ¯µªÓ½…ÿ¤ÔªÕª€€€€€€€€ Õ¢•ºÿß‚ÀÈþÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿÿÿ„ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿªýÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ü«ýÿÏàƒ€Ÿ€€€ô€‘€Ðª€ õÿ‡þÿñÿÿÿÏÕûýïÿÿÿÿÿ€€€€€€€ª•€”ºÿôÿÿÿ‡¨µ€€€ºÀþ€À¾€€€þÿÿÿÿÿÿÿ¿×¨€ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúߪõ¿ýÿÿÿÿÿÿÿÿÿÿÿ¿×üëÿÿ€€”ˆ€ˆ€€€€Œ¨€€€€ÔŠÕ²˜€€ð¿€€Àÿïÿÿÿÿÿÿÿÿü¯€€€€€€€€Õ‚¤ºÿŸúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ÀªÕ‚ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßú¿Åú¿õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€€€€€€˜€€€€€€€€€€†€€€€€€€€ÀœÇ±ðÿꀀ€€€€€€¨Õ‚ŠºÿÿŸ€…€€€ ƒ€ô€ÀŽÀ‚ÀŽÀªÕŽÀ‚Àþÿ¿×ЪժÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿªýëÿÿÿÿÿý«õºÕºõ¿×üÿÿÿ……ÕªúßþԪю€×´Õ¢€¨Õª×ªÕªÕªÕªÕЪ­¥ÕªÕʪժ€€€€€€€€Õª•Šºßª•€€€ ‡ ƒ€€ÀŽ€€ÀŽ€€ü€€ÀªÕ¾×ÀŠ”ÊÕªÕ‹™«Ý®•úÿÿÿ¿¸æŒœÌ¹ê™Ÿüá߮ݪõªÔªÓ¦ÕüÿÿÿÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªªÕêªÕª€€€€€€€€€€€€úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×€€€€€€ÐŠºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€ •ÐßÿÿŠºÿﱪõêÿÿ×ÿÿÿÿÿÿÿÿÿÿÕªÖêժשµ»×ÔªÕª€€€€€€€€€€€€ºªý«ÿÿÿÿ¿€€€¾À‚Ðÿ‡ €€€úÿÿÿÿÿÿÿ¿×€€€€‘Õª•ºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕժŊðÿÿÿ¿þÿ€ðÿ‡‚ŸÿÿÿÿÿÿÿÿÍâ֪ժݪýý×ÔªÕª€€€€€€€€€€€€ºÿƒ Åêÿÿ¿À¾€ºÀŽÀþ¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€êÿÿÿÿÿÿÿÿÿŸ¿æÌáÌŸ³æ¼æ³æüÿÿÿÿÿÿÿ¿×ØÒêªÁªÕüÓêͪ…ª…€¡©… ‚ÒªÕêÕª•ÂŠ˜×ªÓ­ÿ¿«ÝªÕª€€€€€€€€ª•ª•ºÿŸˆ€ªõÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿÿÏšºÿÿÿÿÿÿÿÿÿÿÿÿÿתÕÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ü¿Õª›à€ÐŠÕ …Ü€Ô€€ˆÕª•õÿ¨ÕðÿÿÿïÓªµ§ÿªÅ¾êÿª€€€€€€€€ª¨¥•º¿ñÿÿÿÿª±€€€ºÀþ€À¾€€€úÿÿÿÿÿÿÿ¿×Ј€¨ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúÿªý¿ýÿÿÿÿÿÿÿÿÿÿÿ¿×ü«õÿ€€€€€€ Õ‚€€€€€€€€ÔªÕª€ð¿ªÕªÿïÿÿÿÿïÿÿÿüÿ€€€€€€€€Ð¢•ˆºÿÿúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×„¨Õ¢ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßê¿‘ú¯õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿŒ€à€€€À‡€€€ø»Àª€€€€€€ž€þЂ€€€Àí¶ã€øÿª€€€€€€€€¨•ª•ºÿÿŸ€€ … ƒ€ô€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×”ÕÚŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ¯ßªõûÿÿÿÿ¿ÕªÕêÕºÕ¿×üÿÿÿÕŠ •Õª…ý‰¨Š¨ÑªÑŠ…ªÔ¨ÑŠ…ªÕª¨ÕªÕª­¥ªÕŠÕªÕª€€€€€€€€Õ‚ˆºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€ÐŽ€€ô€€Ðþÿ¿×ÀªÅÊýîÕŠÖªõªÕîÿÿÿŸ³æ̙ϙ֙ÏùÌߪժժÕêÖ®ÕüÿÿÿÚªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕ¢ÕªÕª€€€€€€€€€€€€ºÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕª×€€€€€¨……ºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×ЪÔÿªßžºáÿŸ®Õ¾ÿÿ×þÿÿÿÿÿÿÿÿ¿õªÐúÁªÕªÕª×ÔªÕª€€€€€€€€€€€€ºªõ©ÿÿÿÿ¿€€€ºÀ†Ðÿƒ €€€úÿÿÿÿÿÿÿ¿×€€€€ Õª•ºÿÿŸ€€€€€ ƒ ÕŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕժЂªÕªÕºÔª€ Õ‚‚ŠÑªÕªÕªÕªÍêÓªÕöߪÿþ×ÔªÕª€€€€€€€€€€€€ºÿÇ„Õèÿÿ¿À¾€ºÀžÀþ€¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€ŸÓ™•ºÿÿÿÿÿÿÿÿÿ¸ðÌÁ¼œ³ø°æÃþÿÿÿÿÿÿÿ¿×èÒÖÊÔªõøƒÿ®ª€¡ª… Š‚ҪվתÕШ›íߪÓꦭծժ€€€€€€€€ª…ª•ºÿÿƒ€ªÔÿ¿À¾€ºÀþ€ª€º€ªÕÿÿÿÿÿÿÿÿ¿×€€€ˆÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ¿ÕªÕúÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÕ®³¬Ô€ˆÔª…ÞϪ•€€€À€ µÿ€Àúÿÿÿ÷×õ§ÿÿ¯•ýÿÿ€€€€€€€€Šª¥•ºÿáÿÿÿÿ‹µ€€€ºÀþƒ€À¾€€€úÿÿÿÿÿÿÿ¿×€¢Ð‚ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúÿºý¿ýÿÿÿÿÿÿÿÿÿÿÿ¿×üÿõÿÁªÕ Õ‚…ŠÀ€€€€€€‚€€€ Õò÷‡€€€îÇÿÿÿÿÿ€øÿ€€€€€€€€Õª…ŠºÿÿŸ€€ €€¨ƒ€ýƒÀŽ€€Ð€€ÀŽ€€Ðƒ‚¸×„ˆÑªÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿª¿‘ú«ýÿÿÿÿÿª×úÿÿÿ¿×üÿÿÿÿƒàƒ€ Ýñ©µõÿÿëÿýë‡Ààÿÿûÿªÿÿý¿³öýÿ³¦Õª€€€€€€€€Ð ÕŠºÿÿŸ€€ ‡ ƒ€ô€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×”­êªÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿÿÕªÕþÿÿÿÿ«Õ«ÕëÕºÕ¾×üÿÿÿŪժժժժժժժժժժժ¥ÕªÕª¨Õª•ªÕŠÕªÕª€€€€€€€€”€ÐˆºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€ÐŽ€€ô€€Ðþÿ¿×ԪՊߪÿ®ÕºÕú‘ê÷ÿÿŸ³æ̙ϙڙÏÿÌߪݪժժ֨ÕüÿÿÿÕªÚªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕÔêªÕª€€€€€€€ÿ \ No newline at end of file +€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÁªÅŠºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€ÐŽ€€ô€€Ðþÿ¿×ÄȪ«×ªÕªÖªõ«ÕêýÿÿŸ°æŒž¼¾æ™¿üÀ׫ժݪվժÕüÿÿÿŠª¥•ºÿáÿ€€€€ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€ŠÕŠºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€Ô¢ÕݪýŸºøÿð¿®ÕûÿÿÇøÿÿÿÿÿÿÿÿ¿õªÁúѪզթ×ÔªÕªÿÿÿ‹µ€€€€€€€º«Õ¡ÿÿÿÿ¿€€€ºÀ†Ðÿƒ €€€úÿÿÿÿÿÿÿ¿×€€€€ Õª•ºÿÿŸ€€ €€¨ƒàÿ‹ÀŽ€€ÐŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕÕŠÕˆªÕªÕªÔª€€€€‚ŠÕªÕªÕªÕªÏê󪵪ϪժÕÔªÕªºÀþƒ€À¾€€€€€ºÿ¯ Ò¢ÿÿ¿À¾€ºÀžÀþ€¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€ÿôß›ºÿÿÿÿÿÿÿÿÿ³þ̉ü™³æ¼æ³žÿÿÿÿÿÿÿÿ¿×誩ÕÕªõ·ÕŽƒ†¶ª…€€©Åª‰‚‚ùÿ¿ÿ¿ÕЪùïîÛõ¨½¨íÔÿÿÿ€€úÿÿÿÿÿ Õª•ºÿÿÿ¯ •ÿ¿À¾€ºÀþ€ˆ€º€úÿÿÿÿÿÿÿÿÿ¿×€€ÐªÿÿÓšºÿÿÿÿÿÿÿÿÿÿÿÿ¯ßªõëÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿç¡Á£…ˆ€Š€Ž˜€€€€€À€ µÿ€€úÿÿÿóϪíÿÿÿÿÿÿýÿÿÿ¿×€¢Ð‚ª…ª•ºÿÓÿÿÿÿ¯µ€€€ºÀþƒ€À¾€€€úÿÿÿÿÿÿÿ¿×€¢‘‚ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßêÿºý¯õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÕÿ•€Ð€ÐªÕªÕªÕ€€€€€€€€€€€€¨ÕªÕªÕîÕª€€€€€øÿÿÿÿŸºÿÿÿ¨ŠºÿÿŸ€€€€€ ƒ€ýƒÀŽ€€ÀŽ€€ÀŽ€€ÀΙ³×€ªÕªÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿª½úªýÿÿÿÿÇþÕªýÿÿ¿×üÿÿÿ½†Õþ¨ÕÔ̪ÕúŸÔþ…Õ¨õÿÔÿÿŸõ‡õÿÿÿŸõÿÿÿÿ¯Õªÿÿÿÿÿÿÿÿ…ÕŠºÿÿŸ€€ ‡ ƒ€ô€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ôª©©ßþÿŸºÿÿÿÿÿÿÿÿÿÿÿÿÿÕªÕþÿÿÿÿºÕªÕªÕªÑ¾×üÿÿÿÔ‚”‚„ˆÐ Á€”¨Ð ‘€…Š‚„ª„ŠÔŠªÕê§ÕªÕªÕ¨ÕªÕªÿúÿºý¿ýÿ€€€ÔªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕª€€€ÕªÕŠºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€Ð€€ô€€Ðÿÿ¿×êÔ¢ÕÕªÕŠÙªŸÊÕºÕþÿŸ³æÌ™Ïùà™ÿùÌתիݪժժ×ü®Õªÿÿÿÿÿÿÿÿ€€€€ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€•Ô”ºÿÿŸ€€ ‡ ƒ ŠÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€ÕªÕߪ՚Šÿß¿úÝúÿÿÇøÿÿÿÿÿÿÿÿ¿õªõêժݟõºÓÔªÕªÿÿ¿×üÿõÿ€€€€º¯Õ¢ÿÿÿÿ¿€€€ºÀ†Ðÿƒ¨€€€úÿÿÿÿÿÿÿ¿×€€€€ Õª…ºÿÿߪժߪÕê×êÿ¯Õ®ÕªÕ¯ÕªÕ®Õ®Õþÿ¿×¨ÕªÕý§ŠªÕ¨ÕªÔŠ€ ”ÒŠŠÕªÕªÕªÕª±êö«Õ©ÍªÕªÕÔªÕªÁªÕ Õ‚…Š€€€€ºÿŸ¨Òªÿÿ¿À¾€ºÀžÀþ€º€€ðÿÿÿÿÿÿÿÿ¿×€€€€þû¦•ºÿÿÿÿÿÿÿÿŸ³þ̙̙³æ¼æ³žÿÿÿÿÿÿÿÿ¿×èÓêÕÕêû€†°þ€„¥¨ˆ€Âÿÿ¿ÿÿ¿Æªùï쨕¹ôŽÅôÿÿÿÀ€€€€€€¨Õª•ºÿÿÿ¿€•ü¿À¾€ºÀþ€ˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€€”ˆýÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿëתÕïÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ£Õ«ÔŠ„¨…€À€€€À€Àª•µÿ€€úÿÿÿøߪëÿÿÿÿÿßüÿ‚€€€ ÕòŠ ª•ºÿ—ÿÿÿÿ¿µ€€€ºÀþƒ€Ð¿€€€úÿÿÿÿÿÿÿ¿×€ªÐ¨ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßêßþõ¯õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€Àª…€€€€€€€€€€€€€€€€€€€€€€€€ª…€€€€€Ð‚üÿ÷‡€€€îÇÿÀÄЊºÿÿŸ€€€€€ ƒ€ýƒÀŽ€€ÀŽ€€ÀŽ€€ÀΙ³×ÀŠÕŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿªµ‘Úªýÿÿÿÿ¯ÝªÕÿÿ¿×üÿÿÿªÕªÁŠÍêÕŠ ýë ‡ŽÐ¯Õþÿ§õ«þúõïêê©Õÿ¯žÕªÿÿÿÿ€øÿÕªÕŠºÿÿŸ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ôª¥‹õ«ÿŸºÿÿÿÿÿÿÿÿÿÿÿÿÿתÕÿÿÿÿߪժժ×êѺ×üÿÿÿÔˆ‘¢ÄˆÑˆÑˆ‘ªÄˆ‘¢Ä¨”¢Ä¨ÄˆÕÿÿïêÿժժŪժժժ…ŠºÿÿŸ€€€ÐªªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕª•ÕŠ€€€€€€ºÿÿŸ€€à ‡ ƒ €ˆÀŽ€€ð€€ô€€ðÿÿ¿×¨µÑ”ÕêתÕêרժÝûÿŸ³æÌ™Ïùÿ™ÏùÌת׫ժժµª×ÔªÕª€€ €€¨ƒ€€€€ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€€À”ºÿÿŸ€€ ‡ ƒ ŠÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿× ÕªÕÕªÕŠ°ÿñÿ¿ÚÕëÿÿ×àÿÿÿÿÿÿÿÿÿÕªÕªÕªÕŽµ·×ÔªÕª€ýƒÀŽ€€Ð€€€€ºŸÕªÿÿÿÿ¿€€€ºÀ†Àþƒ¨€€€úÿÿÿÿÿÿÿ¿×€€€€ªÕªŠºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×¨ÕªÕÿøÓŠªÕ¨ÕŠÐŠ€ ”‚¨ŠÕªÕªÕªÕª™šÕ¨í¯ÕªÕªÕÔªÕª€€ÀŽ€€Ð€€€”ºÿ€Õªÿÿ¿À¾€ºÀž€ú€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿÿÿŸºÿÿÿÿÿÿÿÿ¿¸þṜ¼¸æ°ðƒŸÿÿÿÿÿÿÿÿ¿×¨Õÿ×ÝÿûÀö€€°þ€„娀€Åÿÿ¿ÿÿŸ¿¨üÏÕ©Õ´¥«®ôÿÿÿƒ‚¸×„ˆÑªªÕª•ºÿÿÿÿƒÕê¿À¾€ºÀþ€ˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€‚•‚ÿ¯ÿ‹ºÿÿÿÿÿÿÿÿÿÿÿÿëתկÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿŸ €€ Ñ‚€†Î€€€€¨€€€°ÿƒ€€øÓª•üÿèþÿÿÿÿÿ×üßÿÿÿŸºÿÿÿ””ª•ºÿÇþÿÿÿÿµ€€€ºÀþƒ€Ð¿€€€úÿÿÿÿÿÿÿ¿×”‚ŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßú×þÕ¿õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€Á€€€€€€€€€€€€€€€€€€€€€€€€€€à€Ð€þÿÿÿÿÿÿÿÿÿ¨Õ€€ºÿÿŸ€€€€€ ƒ€ýƒÀŽ€€ÀŽ€€ÀŽ€€ÀΙ³×ԪѨÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ«õÕÞªÿÿÿÿÿ•¯ÕêÝÿÿ¿×üÿÿÿþú§ªÕŠÀϪÕê˨է¡ÔŠýëת̊ý›¿ŠÊªÕªÔªÕþÿªÕªÿª¿‘ú«ýÿѪ•ŠºÿÿŸ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ъ¥‹Õú÷šºÿÿÿ·ÿÿÿÿÿÿÿÿÿÿªýÿÿÿÿß«ÕªôêתӪ×üÿÿÿê ‘‚„ˆÐ€Ñˆ‘¨Àˆ‘¢„¨”¢Ä¨Äˆ•õÿÿªõߪÝÒª«ÕªÕªÿÿÿÿª×úÿ€€€ÀªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕ‚€€€€€€ºÿÿŸ€…€ ‡ ƒ €ˆÀŽÀ‚ÀÀªõÀ‚Àÿÿ¿×ÀªÑª×ª×ªÕªª•ªõúÿŸóùÌ™ÌùÿÓœÌѪ֪ժժݩ×ÔªÕªÿÿ¿×üÿÿÿ€€€€ºúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€€ÐŠºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀÀ†Àþÿ¿×¨ÕªÕÕªÕŠº‡þÿŸþÿÀÿÿÆÂþÿÿÿÿÿÿÿÿÔªÕªÕª·µ¿×ÔªÕªÿƒàƒ€ Ýñ€€€€º¿Å¨ÿÿÿÿ¿ÀŠ€ºÀŽÀþ¨€ªÕúÿÿÿÿÿÿÿ¿×€€€€ Õª•ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×¨ÕªÕŸÔŠ€€€€€€ €À€Å€€€€€€€ìúÓ¨ÕêÔªÕªÕÔªÕª©µõÿÿëÿ‚€€•ºÿ€Õªÿÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿ«¥‰ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿÿÿûŸÅ€ð „õ¨ÕªÅðÿ¿ÿÿÏÿãÿ¿ÔëÕ¾ÔªýûûÓªýë‡Ààÿÿ¨€ª…ºÿûÿÿŸÔª¿À¾€ºÀþˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€‚ШÿªÿŸºÿÿÿÿÿÿÿÿÿÿÿÿûתտÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿߪ€ªÀŠ€€€†€€€€€€ˆ°ÿŸÕª½…€þïÿÿÿÿÿÿÿ÷ü§ûÿªÿÿý¿•Õª•ºÿÇüÿÿÿÿ¿€€ÀºÀþ‡€Ð¿€€€úÿÿÿÿÿÿÿ¿×€Š€¨ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßúÕÿ×¾õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ŒÂÿÿ³öýÿ³¦ÕªÕª•ºÿÿŸ€€€€€ ƒ€ô€ÀŽ€€ÀŽ€€ÀŽ€€Àþÿ¿×ЪъÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ«ýÿÿªÿÿÿÿÿå«Õ®ýªÿ¿×üÿÿÿЪժєúϮժÕú쀈•€×«ý«õ¹Õî…¤…Õêÿµª»ú–ªÕªÐ ÕŠºÿÿŸÕŠÀŠº¿ÕŠ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†ÀÖª½×Ôª¥­ýïýŸ¹ÿßû¿þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ª×º„ªÕªÓ®×üÿÿÿꈑªÄˆÑˆÑˆ‘ªÄˆ‘¢Ä¨”¢Ä¨ÄˆÕòŸÕªžÕþ¯ßæªÕŠÕª€€ ‡ ƒ€€€€ªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕ€€€€ÔŠ„€ºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×À‚Ô‚÷¯ÝšÚîãºÕªÕêÿÿÿÿÿÿÿÿÿÿÿÿÿÕªÖªÕªÕªÕ«×ÔªÕª€ô€ÀŽÀ†À€€€€ºêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×€€€€€€ÕŠºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕÕªÕ‚ºÑªÕºÞªÀ¢ÕʪªÕªÕªÕªÕªÕªÕªÕ«Õ©õ¿×ÔªÕªŽÀþÿÀ†À€€€€ºÿÀªÿÿÿÿ¿À¾€ºÀŽÀþ¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€ªÕꞺÿÿÿÿÿÿÿÿ¿¸ðáùœ¼¸ð°ðƒçüÿÿÿÿÿÿÿ¿×¨ÕªÕÓ •êƒªÝª•ª…€ €€À€ÁÔªÕªÕª•ÔƒÁ¢Õ©Õ‚€€€ÔªÕªþÿ¿×”­êªŠ€ •ºÿ€Ðªÿÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿýÿºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ü«ýÿïÿû‡”Ï€€ð À’”¨€ õÿ‡þÿçÿÿÿŸíÿ™Ý”¬¨ÕªÕªÿÿÿŸºÿÿÿ€”ª”ºÿõÿÿÿЪ¼À¾€ºÀþˆÀ¾€úÿÿÿÿÿÿÿÿÿ¿×€Š€€ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúתտýÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€Õª¢€ü€€€€€„€€°˜€€ð¿€€€ÿïÿÿÿÿÿÿÿÿ¼¯ÿÿÿÿÿÿÿÿÔª¥•ºÿßüÿÿÿÿ¿ÕªÕ¾ÕþתտժÕúÿÿÿÿÿÿÿ¿×ԪЪÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿߪÕÕÖªõÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€°†¶ƒàÿÿÿÿÕªÕþÿÿªÕ”€ºÿÿŸ€€€€€ ƒ€ô€ÀŽ€€ÀŽ€€ÀŽ€€Àþÿ¿×Ј…ŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ«ý«ÿêÿÿÿÿÿå«õªÝªý¿×üÿÿÿѪՔլÿ«ÕªÏ×ö• ÅªÕº×šÓâõëÔŠ¥…ÕÐåïõ÷Ϫժÿÿ«Õ«ÕëÕРՊºÿÿŸ€€ ‡ ƒ€€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×Ô‚•Õÿ«õ‹ùî׫¿úÿÿÿÿÿÿÿÿÿÿàÿÿÿÿ÷¾Õª…ªÕªÛªÕüÿÿÿÕ‚”ª„ˆÐˆÁˆ‘¨Äˆ‘¢Ä¨”‚ĨĈĪժժժժªÕªÕʪºÕ¾×üÿÿÿ€€€€úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×€€€€Ô‚‚ºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€€”€ÿúÝ«ÖþôïÕªÕîÿÿ÷ÿÿÿÿÿÿÿÿÿÿÕªÔªÕºÕªõŸ×ԪժŪժժժ€€€€º¨ÿçÿÿÿÿ¿€€À¿Àƒðÿ‡ €€€úÿÿÿÿÿÿÿ¿×€€€€€Ôª•ºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕÕª•ˆŠþÿÿ¿þÿ€ðÿ‹‚ÿÿÿÿÿÿÿÿ¿íéÔªÕªÕªÕª×ÔªÕªÕªÕªÕªÕª€€€€ºÿÑ¢Õúÿÿ¿À¾€ºÀŽÀþ¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€êÿÿŸºÿÿÿÿÿÿÿÿŸ³æÌñÌ™³æ¼æ³æüÿÿÿÿÿÿÿ¿×”ÕªÕ”ªÕ€„ªÝª…ª…€¡€€ ‚Ъժժ•ÔÈÕ¯µªÓ½…ÿ¤ÔªÕªÕªÕªÕªÕª Õ¢•ºÿß‚ÀÈþÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿÿÿ„ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿªýÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ü«ýÿÏàƒ€Ÿ€€€ô€‘€Ðª€ õÿ‡þÿñÿÿÿÏÕûýïÿÿÿÿÿժժ¨Õªª•€”ºÿôÿÿÿ‡¨µ€€€ºÀþ€À¾€€€þÿÿÿÿÿÿÿ¿×¨€ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúߪõ¿ýÿÿÿÿÿÿÿÿÿÿÿ¿×üëÿÿ€€”ˆ€ˆ€€€€Œ¨€€€€ÔŠÕ²˜€€ð¿€€Àÿïÿÿÿÿÿÿÿÿü¯•ªÕŠÕªÕªÕ‚¤ºÿŸúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ÀªÕ‚ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßú¿Åú¿õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿ€€€€€€€€€€€€˜€€€€€€€€€€†€€€€€€€€ÀœÇ±ðÿꔀЈºÿÿŸ¨Õ‚ŠºÿÿŸ€…€€€ ƒ€ô€ÀŽÀ‚ÀŽÀªÕŽÀ‚Àþÿ¿×ЪժÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿªýëÿÿÿÿÿý«õºÕºõ¿×üÿÿÿ……ÕªúßþԪю€×´Õ¢€¨Õª×ªÕªÕªÕªÕЪ­¥ÕªÕʪժ€€  ‡ ƒÕª•Šºßª•€€€ ‡ ƒ€€ÀŽ€€ÀŽ€€ü€€ÀªÕ¾×ÀŠ”ÊÕªÕ‹™«Ý®•úÿÿÿ¿¸æŒœÌ¹ê™Ÿüá߮ݪõªÔªÓ¦ÕüÿÿÿÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªªÕêªÕª€€€ÀŽ€€Ð€€€€úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×€€€€€€ÐŠºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×€ •ÐßÿÿŠºÿﱪõêÿÿ×ÿÿÿÿÿÿÿÿÿÿÕªÖêժשµ»×ÔªÕªŽ€€ô€€Ð€€€€ºªý«ÿÿÿÿ¿€€€¾À‚Ðÿ‡ €€€úÿÿÿÿÿÿÿ¿×€€€€‘Õª•ºÿÿŸ€€€€€ ƒ ŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕժŊðÿÿÿ¿þÿ€ðÿ‡‚ŸÿÿÿÿÿÿÿÿÍâ֪ժݪýý×ÔªÕªþÿ¿×ÔªÕŠ€€€€ºÿƒ Åêÿÿ¿À¾€ºÀŽÀþ¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€êÿÿÿÿÿÿÿÿÿŸ¿æÌáÌŸ³æ¼æ³æüÿÿÿÿÿÿÿ¿×ØÒêªÁªÕüÓêͪ…ª…€¡©… ‚ÒªÕêÕª•ÂŠ˜×ªÓ­ÿ¿«ÝªÕªßªÿ®ÕºÕúª•ª•ºÿŸˆ€ªõÿ¿À¾€ºÀ¾€º€º€€Ðÿÿÿÿÿÿÿÿ¿×€€€€ÿÿÏšºÿÿÿÿÿÿÿÿÿÿÿÿÿתÕÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×ü¿Õª›à€ÐŠÕ …Ü€Ô€€ˆÕª•õÿ¨ÕðÿÿÿïÓªµ§ÿªÅ¾êÿª‘ê÷ÿÿŸ³æª¨¥•º¿ñÿÿÿÿª±€€€ºÀþ€À¾€€€úÿÿÿÿÿÿÿ¿×Ј€¨ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿúÿªý¿ýÿÿÿÿÿÿÿÿÿÿÿ¿×ü«õÿ€€€€€€ Õ‚€€€€€€€€ÔªÕª€ð¿ªÕªÿïÿÿÿÿïÿÿÿüÿ̙ϙڙÏÿТ•ˆºÿÿúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿×„¨Õ¢ÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿßê¿‘ú¯õÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÿÿŒ€à€€€À‡€€€ø»Àª€€€€€€ž€þЂ€€€Àí¶ã€øÿªÌߪݪժը•ª•ºÿÿŸ€€ … ƒ€ô€ÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×”ÕÚŠÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ¯ßªõûÿÿÿÿ¿ÕªÕêÕºÕ¿×üÿÿÿÕŠ •Õª…ý‰¨Š¨ÑªÑŠ…ªÔ¨ÑŠ…ªÕª¨ÕªÕª­¥ªÕŠÕªÕªªÖ¨ÕüÿÿÿÕ‚ˆºÿÿŸ€€  ‡ ƒ€€€ÀŽ€€ÐŽ€€ô€€Ðþÿ¿×ÀªÅÊýîÕŠÖªõªÕîÿÿÿŸ³æ̙ϙ֙ÏùÌߪժժÕêÖ®ÕüÿÿÿÚªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕ¢ÕªÕªÕªÚªÕªÕª€€€€ºÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕªÕª×€€€€€¨……ºÿÿŸ€€ ‡ ƒ €ˆÀŽÀ†ÀŽÀþÿÀ†Àþÿ¿×ЪÔÿªßžºáÿŸ®Õ¾ÿÿ×þÿÿÿÿÿÿÿÿ¿õªÐúÁªÕªÕª×ÔªÕªÕªÕªÕªÕª€€€€ºªõ©ÿÿÿÿ¿€€€ºÀ†Ðÿƒ €€€úÿÿÿÿÿÿÿ¿×€€€€ Õª•ºÿÿŸ€€€€€ ƒ ÕŠÀŽ€€ÀŽ€€ÀŽÀ†Àþÿ¿×¨ÕªÕժЂªÕªÕºÔª€ Õ‚‚ŠÑªÕªÕªÕªÍêÓªÕöߪÿþ×ÔªÕªÕªÕªÕªÕª€€€€ºÿÇ„Õèÿÿ¿À¾€ºÀžÀþ€¨€úÿÿÿÿÿÿÿÿÿ¿×€€€€ŸÓ™•ºÿÿÿÿÿÿÿÿÿ¸ðÌÁ¼œ³ø°æÃþÿÿÿÿÿÿÿ¿×èÒÖÊÔªõøƒÿ®ª€¡ª… Š‚ҪվתÕШ›íߪÓꦭծժժժժժª…ª•ºÿÿƒ€ªÔÿ¿À¾€ºÀþ€ª€º€ªÕÿÿÿÿÿÿÿÿ¿×€€€ˆÿÿÿŸºÿÿÿÿÿÿÿÿÿÿÿÿ¿ÕªÕúÿÿÿÿÿÿÿÿÿÿÿÿ¿×üÿÕ®³¬Ô€ˆÔª…ÞϪ•€€€À€ µÿ€Àúÿÿÿ÷×õ§ÿÿ¯•ýÿÿÕªÕÔêªÕª \ No newline at end of file diff --git a/res/TITLE.HGR/FIGHT.NIGHT b/res/TITLE.HGR/FIGHT.NIGHT index be74685..cd43ac2 100644 Binary files a/res/TITLE.HGR/FIGHT.NIGHT and b/res/TITLE.HGR/FIGHT.NIGHT differ diff --git a/res/TITLE.HGR/FORMULA.1.RACER b/res/TITLE.HGR/FORMULA.1.RACER index 89bdae2..3d5cf68 100644 --- a/res/TITLE.HGR/FORMULA.1.RACER +++ b/res/TITLE.HGR/FORMULA.1.RACER @@ -1 +1 @@ -€€€€€€€€€€€˜°þàÿù¿þÏÿóÿüŸÿçÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÅª‘ À€‚„€Õ¢Õˆ€ À€‘ „ˆÕ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Õª•¨ÕªÁªÕŠÔªÕ Õª…€€€€€€€€€€€€€€€€€‘¢Ô À ÅˆÐ€€•¢Ä¨Ñ‚ԨѢĈ•ªÔ¨€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øЀÀ‡õá—ø€ Á‚€€”€ð€€€Š€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õ‚€Š€ÐЀ€…¥Ë–Ѐ Á‚€€”€ €€€Š€€€€€€€€€€€€€€€€€€ž€ø€àÇ€€¼€€àÇ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€ÐÚ®¯•€€€Š •Ð€À‚­ÕŠèªÕÀ‚¨…€€ ÕÖë«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€¨ðჀ€¼¨€àÇ€€¼€ð€€€ž€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€´Õª Ô‚Š€¨¨ÕÊ‚­ÕŠ¨€ €€Õ´•€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ª€‚ĈтÁŠ•ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿÿþÿÿðÿÿ‡€¼ø€àÇ€€üÿÿ€€ÿÿ¿€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ À‚Ú ©¨€À‚…€€¨€Ð€€€€”€€€€€€€€€€€€€€€€€€ÿÿ—¨ÿÿ€€Ôÿ€ ýÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€ €€€‚€€€…Š€¨€ Á‚€€”€€ Á‚€€€€ˆ€€À€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øÐþÿ‡…Š”ø€ Á‚€€Ôÿÿ€€€Š€€€€€€€€€€ÐÚ®¯•€€€Àªø€àÃת•¼ÕªáƒÐŠ€€€ÕÖë«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€ÐР€…€”Ѐ Á‚€€”€Ð€€€€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õª…ªÕªÐªÕ‚…€”¨€ Á‚€€ÔªÕ€€€Õª•€€€€€€€€€€€€€€€€€…€¼ø€ Á‡€€¼€€àƒ€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€Õª©ÐÕª…€€èª€ÀÖª…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿ‡€ž€¨ðÀ‚ß¾½¨€àÇ€€¼€Ð€€€€ž€€€€€€€€€€ ÕªÕ‚€€€Š”€Ð€À‚…€€¨€€À‚…€€€€¨ÕªÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ «Õ‚Š”¨¨€À‚…€€èªÕ€€€€”€€€€€€€€€€Ðúÿ¯…€€€…࿨€ ÁúÿŸÔÿÿ¡ø€€€Õø¿ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€€€€€€€€€ÀŸ¿þÌùóçÏ™¿€ÃŸ¿þ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÅª‘ ÔŠÕ¢À€Õ¢Õ¨•ªÅ€ÑªÔŠÕ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ø¿àÀçÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€‘ªÔ¨Ñ¢ÅˆÐ „€•¢Ô¨Ñ‚ԨѢĊ‘ª„¨€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”¨€à€€”€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€”¨€À‚€€”€€ €Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øЀÀ‡õá—ø€ Á‚€€”€ð€€€Š€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õ‚€Š€ÐЀ€…¥Ë–Ѐ Á‚€€”€ €€€Š€€€€€€€€€€ðÿÿÿƒ€€€ž€ø€àÇ€€¼€€àÇ€€€€üÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€Ðâÿ©…€€€Š •Ð€À‚­ÕŠèªÕÀ‚¨…€€€Õ઀€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€À³æÌ™ÃáÀ™ŒàÙ³à€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚À€ À€¢À€ Àˆ€ À€‘ „ˆ€€€€€€€€€€€€€€€Š€ªÄ¨Ñ¢Åˆ•ŠÔ¨Ñ¢…€€ª€ªÄ¨Ñ¢ÅŠ€€€€€€€€€€€€€€€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€ÿÿ¿øÿÿÃÿÿŸüÿÿáÿÿ€€€€€€€€€€€€€€€€€‘¢ À Àˆ¢Ä€¢Ä €„  Äˆ‘‚„ˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€…€¨Ð€ …€€¨€€À‚€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿÿþÿÿðÿÿ‡€¼ø€àÇ€€üÿÿ€€ÿÿ¿€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ À‚Ú ©¨€À‚…€€¨€Ð€€€€”€€€€€€€€€€€€€€€€€€ÿÿ—¨ÿÿ€€Ôÿ€ ýÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€ðÿÿÿƒ€€€…Š€¨€ Á‚€€”€€ Á‚€€€ ­˜°€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€Ð‚¿¨…€€€Àªø€àÃת•¼ÕªáƒÐŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€êÿÿЀü‡…€”øÿ¿ÁúÿŸ”€Ð€€€ÿë¿€€€€€€€€€€€€€€€€€À³þ°øÃáÌŸŒ€ÃŸ¿ø€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ€ªÔ¨Ñ¢ÅŠ•ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚À€Ð À€‚‘€ Àˆ€ Àˆ‘ „ˆ€€€€€€€€€€€€€€€ €ˆÔ  ÄŠ¢ˆÁ €€€ €‚Ĉ‘ „‚€€€€€€€€€€€€€€€€€€€€€€€€€˜°þàÿù¿þÏÿóÿüŸÿçÿ€€€€€€€€€€€€€€€€€€€€€€Õª•¨ÕªÁªÕŠÔªÕ Õª…€€€€€€€€€€€€€€€€€•¢ À ÀŠÐ€€¢Ä €„  Åˆ‘‚„ˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õª…ªÕªÐªÕ‚…€”¨€ Á‚€€ÔªÕ€€€Õª•€€€€€€€€€€€€€€€€€…€¼ø€ Á‡€€¼€€àƒ€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€Õª©ÐÕª…€€èª€ÀÖª…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€€àÀÁ—€€€Š”€Ð€À‚…€€¨€€À‚…€€€ ­ÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€¨ðჀ€¼¨€àÇ€€¼€ð€€€ž€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€´Õª Ô‚Š€¨¨ÕÊ‚­ÕŠ¨€ €€Õ´•€€€€€€€€€€€€€€€€€À³†°øÀáÌ™Œ€ƒ˜³à€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¢Äˆ‘€‚‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€¢ÅŠ¢À€Õ‚„€Õ¢À¨ ÀˆÑªÔŠ•€€€€€€€€€€€€€€€ˆ”ˆÔ Ð ÅŠ…¢¨Á €€¨”Š¨Ñ …‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€•ª À ÁŠ‚€ªÔ Ð‚” Ð¢ÅŠ‘¢„¨€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”¨€à€€”€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€”¨€À‚€€”€€ €Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øÐþÿ‡…Š”ø€ Á‚€€Ôÿÿ€€€Š€€€€€€€€€€€øÿ×—€€€Àªø€àÃת•¼ÕªáƒÐŠ€€ Õþÿ«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€ÐР€…€”Ѐ Á‚€€”€Ð€€€€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€ÀŸ¿†°˜óçÏ™Œà˜¿þ€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ”ªÔ¨‘€‚Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚Ä€¨À€‘€„€€¢Àˆ€ À¢‘ Ä€€€€€€€€€€€€€€€€‚€ˆÔ  Áˆ¢ˆÁ €€€ €‚Ĉ ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿÿ¿øÿÿÃÿÿŸüÿÿáÿÿ€€€€€€€€€€€€€€€€€•Š À Àˆ‚Á€¢” €‚„ €¢Äˆ‘¢„ˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€…€¨Ð€ …€€¨€€À‚€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àÿ‡€ž€¨ðÀ‚ß¾½¨€àÇ€€¼€Ð€€€€ž€€€€€€€€€€€€€€€€€€Š”€Ð€À‚…€€¨€€À‚…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ «Õ‚Š”¨¨€À‚…€€èªÕ€€€€”€€€€€€€€€€Ðúÿ¯•€€€…࿨€ ÁúÿŸÔÿÿ¡ø€€ Õþÿ«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€êÿÿЀü‡…€”øÿ¿ÁúÿŸ”€Ð€€€ÿë¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ€‚”ˆ‘€‚‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚Ä€ À€Á€„€€¢Àˆ€ À¢‘ „‚€€€€€€€€€€€€€€€ª€ªÄ Ð¢Äˆ•ŠÔˆÁ …€€ª€ªÄˆÐ¢„‚€€€€€€€€€€€€€€ \ No newline at end of file +€€€€€€€€€€€˜°þàÿù¿þÏÿóÿüŸÿçÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÅª‘ À€‚„€Õ¢Õˆ€ À€‘ „ˆÕ‚€€€€€€€€€€€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Õª•¨ÕªÁªÕŠÔªÕ Õª…€€€€€€€€€€€€€€€€€‘¢Ô À ÅˆÐ€€•¢Ä¨Ñ‚ԨѢĈ•ªÔ¨€€€€€€”€¨ «Õ‚€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š”¨¨€À‚…€€€€€ €€Š€øЀÀ‡õá—ø€ Á‚€€”€ð€€€Š€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€èªÕ€€€€€€€€ Õ‚€Š€ÐЀ€…¥Ë–Ѐ Á‚€€”€ €€€Š€€€€€€€€€€€€€€€€€€ž€ø€àÇ€€¼€€àÇ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€ÐÚ®¯•€€€Š •Ð€À‚­ÕŠèªÕÀ‚¨…€€ ÕÖë«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðúÿ¯€€€€€àƒ€€ž€¨ðჀ€¼¨€àÇ€€¼€ð€€€ž€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€•€€€…࿨€€€€€À‚€€´Õª Ô‚Š€¨¨ÕÊ‚­ÕŠ¨€ €€Õ´•€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ª€‚ĈтÁŠ•ª€€€€€€€€€€€€€€€ ÁúÿŸÔÿ€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿ¡ø€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Õþÿ«€€€€€€€€€àÿÿþÿÿðÿÿ‡€¼ø€àÇ€€üÿÿ€€ÿÿ¿€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ À‚Ú ©¨€À‚…€€¨€Ð€€€€”€€€€€€€€€€€€€€€€€€ÿÿ—¨ÿÿ€€Ôÿ€ ýÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€ €€€‚€€€…Š€¨€ Á‚€€”€€ Á‚€€€€ˆ€€À€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øÐþÿ‡…Š”ø€ Á‚€€Ôÿÿ€€€Š€€€€€€€€€€ÐÚ®¯•€€€Àªø€àÃת•¼ÕªáƒÐŠ€€€ÕÖë«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€ÐР€…€”Ѐ Á‚€€”€Ð€€€€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”€ø Á‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¨ø€À‚…€€€€€ Õª…ªÕªÐªÕ‚…€”¨€ Á‚€€ÔªÕ€€€Õª•€€€€€€€€€€€€€€€€€…€¼ø€ Á‡€€¼€€àƒ€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€¨€ €€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€Õª©ÐÕª…€€èª€ÀÖª…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”€€€€€€€€€€€àÿ‡€ž€¨ðÀ‚ß¾½¨€àÇ€€¼€Ð€€€€ž€€€€€€€€€€ ÕªÕ‚€€€Š”€Ð€À‚…€€¨€€À‚…€€€€¨ÕªÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€¨ «Õ‚Š”¨¨€À‚…€€èªÕ€€€€”€€€€€€€€€€Ðúÿ¯…€€€…࿨€ ÁúÿŸÔÿÿ¡ø€€€Õø¿ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€€€€€€€€€ÀŸ¿þÌùóçÏ™¿€ÃŸ¿þ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÅª‘ ÔŠÕ¢À€Õ¢Õ¨•ªÅ€ÑªÔŠÕ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ø¿àÀçÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€‘ªÔ¨Ñ¢ÅˆÐ „€•¢Ô¨Ñ‚ԨѢĊ‘ª„¨€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”¨€à€€”€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€”¨€À‚€€”€€ €Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€Š€øЀÀ‡õá—ø€ Á‚€€”€ð€€€Š€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ Õ‚€Š€ÐЀ€…¥Ë–Ѐ Á‚€€”€ €€€Š€€€€€€€€€€ðÿÿÿƒ€€€ž€ø€àÇ€€¼€€àÇ€€€€üÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€Ðâÿ©…€€€Š •Ð€À‚­ÕŠèªÕÀ‚¨…€€€Õ઀€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€À³æÌ™ÃáÀ™ŒàÙ³à€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚À€ À€¢À€ Àˆ€ À€‘ „ˆ€€€€€€€€€€€€€€€Š€ªÄ¨Ñ¢Åˆ•ŠÔ¨Ñ¢…€€ª€ªÄ¨Ñ¢ÅŠ€€€€€€€êÿÿЀü‡€€€€€€€€€€€˜°à€àÀ™°†Ì³àŒ˜ƒæÀ€€€€€€€€€€€€€€€€€€€€€€ÿÿ¿øÿÿÃÿÿŸüÿÿáÿÿ€€€€€€€€€€€€€€€€€‘¢ À Àˆ¢Ä€¢Ä €„  Äˆ‘‚„ˆ€€€€€€…€”øÿ¿Áú€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€…€¨Ð€ …€€¨€€À‚€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿŸ”€Ð€€€€€€€€àÿÿþÿÿðÿÿ‡€¼ø€àÇ€€üÿÿ€€ÿÿ¿€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿë¿€€€€€€€€€€À‚€€”€¨ À‚Ú ©¨€À‚…€€¨€Ð€€€€”€€€€€€€€€€€€€€€€€€ÿÿ—¨ÿÿ€€Ôÿ€ ýÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€ðÿÿÿƒ€€€…Š€¨€ Á‚€€”€€ Á‚€€€ ­˜°€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€”€ø Á‚€Š€¨ø€À‚…€€¨€ €€€”€€€€€€€€€€Ð‚¿¨…€€€Àªø€àÃת•¼ÕªáƒÐŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ €€êÿÿЀü‡…€”øÿ¿ÁúÿŸ”€Ð€€€ÿë¿€€€€€€€€€€€€€€€€€À³þ°øÃáÌŸŒ€ÃŸ¿ø€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ€ªÔ¨Ñ¢ÅŠ•ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚À€Ð À€‚‘€ Àˆ€ Àˆ‘ „ˆ€€€€€€€€€€€€€€€ €ˆÔ  ÄŠ¢ˆÁ €€€ €‚Ĉ‘ „‚€€€€€€€€€€€€€€€€€€€€€€€€€˜°þàÿù¿þÏÿóÿüŸÿçÿ€€€€€€€€€€€€€€€€€€€€€€Õª•¨ÕªÁªÕŠÔªÕ Õª…€€€€€€€€€€€€€€€€€•¢ À ÀŠÐ€€¢Ä €„  Åˆ‘‚„ˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¼ø€À‡€€¼€€àƒ€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ€€€€€ Õª…ªÕªÐªÕ‚…€”¨€ Á‚€€ÔªÕ€€€Õª•€€€€€€€€€€€€€€€€€…€¼ø€ Á‡€€¼€€àƒ€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚”ˆ‘€‚€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€Õª©ÐÕª…€€èª€ÀÖª…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚€€€€€€€€€€€àƒ€€ž€ÐðÕª…ž¼Ð€àÇ€€¼Õª€€€ž€€€€€€€€€€€àÀÁ—€€€Š”€Ð€À‚…€€¨€€À‚…€€€ ­ÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€àƒ€€ž€¨ðჀ€¼¨€àÇ€€¼€ð€€€ž€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€À‚€€´Õª Ô‚Š€¨¨ÕÊ‚­ÕŠ¨€ €€Õ´•€€€€€€€€€€€€€€€€€À³†°øÀáÌ™Œ€ƒ˜³à€€€€€€€€€€€€€€€€€€€€€€€€€€€Š€¢Äˆ‘€‚‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€¢ÅŠ¢À€Õ‚„€Õ¢À¨ ÀˆÑªÔŠ•€€€€€€€€€€€€€€€ˆ”ˆÔ Ð ÅŠ…¢¨Á €€¨”Š¨Ñ …‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÐªÕ‚Õª•¨ÕªÁªÕŠ€€€€€€€€€€€€€€€€€•ª À ÁŠ‚€ªÔ Ð‚” Ð¢ÅŠ‘¢„¨€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€”¨€à€€”€€ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÀªÕŠÔªÕ Õª…Š€¨Ð€À‚…€€¨Õª€€ªÕª€€€€€€€€€€€€€€€€€Š€”¨€À‚€€”€€ €Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àª…€”€ø À‡úõ«ø€À‚…€€¨€ð€€€”€€€€€€€€€€€€€€€€€€ªÕ¾øªÕ‡€€¼Õ€à«ÕŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚Ä€ À€Á€€€€€ €€Š€øÐþÿ‡…Š”ø€ Á‚€€Ôÿÿ€€€Š€€€€€€€€€€€øÿ×—€€€Àªø€àÃת•¼ÕªáƒÐŠ€€ Õþÿ«€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€„€€¢Àˆ€€€€€€ €€Š€ÐР€…€”Ѐ Á‚€€”€Ð€€€€Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ À¢‘ „‚€€€€€àƒ€€ÞªÕ𨅀¼ÐªõÃת•¼€ð€€ªßª€€€€€€€€€€€€€€€€€ÀŸ¿†°˜óçÏ™Œà˜¿þ€€€€€€€€€€€€€€€€€€€€€€€€€€€ˆ”ªÔ¨‘€‚Š€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€‚Ä€¨À€‘€„€€¢Àˆ€ À¢‘ Ä€€€€€€€€€€€€€€€€‚€ˆÔ  Áˆ¢ˆÁ €€€ €‚Ĉ ‚€€€€€€€€€€€€€ª€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿÿ¿øÿÿÃÿÿŸüÿÿáÿÿ€€€€€€€€€€€€€€€€€•Š À Àˆ‚Á€¢” €‚„ €¢Äˆ‘¢„ˆ€€€€€€€ªÄ Ð¢Äˆ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€…€¨Ð€ …€€¨€€À‚€…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€•ŠÔˆÁ …€€€€€€àƒ€€ž€Ðð€…¯Á¾Ð€àÇ€€¼€ €€€ž€€€€€€€€€€€€€€€€€€€¨Ð€àƒ…€€¨€€À‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ª€ªÄˆÐ¢€€€€€àÿ‡€ž€¨ðÀ‚ß¾½¨€àÇ€€¼€Ð€€€€ž€€€€€€€€€€€€€€€€€€Š”€Ð€À‚…€€¨€€À‚…€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€„‚€€€€€€ \ No newline at end of file diff --git a/res/TITLE.HGR/FS2 b/res/TITLE.HGR/FS2 index a39a6e9..21864e3 100644 Binary files a/res/TITLE.HGR/FS2 and b/res/TITLE.HGR/FS2 differ diff --git a/res/TITLE.HGR/FUJI.SPEED.WAY b/res/TITLE.HGR/FUJI.SPEED.WAY index 8463f59..1fd8dcc 100644 Binary files a/res/TITLE.HGR/FUJI.SPEED.WAY and b/res/TITLE.HGR/FUJI.SPEED.WAY differ diff --git a/res/TITLE.HGR/HARDBALL b/res/TITLE.HGR/HARDBALL index 22929f3..4c141c8 100644 Binary files a/res/TITLE.HGR/HARDBALL and b/res/TITLE.HGR/HARDBALL differ diff --git a/res/TITLE.HGR/INTL.GRAN.PRIX b/res/TITLE.HGR/INTL.GRAN.PRIX index faf6a14..68d9a73 100644 Binary files a/res/TITLE.HGR/INTL.GRAN.PRIX and b/res/TITLE.HGR/INTL.GRAN.PRIX differ diff --git a/res/TITLE.HGR/INTL.HOCKEY b/res/TITLE.HGR/INTL.HOCKEY index da8dd0b..b6b87ea 100644 Binary files a/res/TITLE.HGR/INTL.HOCKEY and b/res/TITLE.HGR/INTL.HOCKEY differ diff --git a/res/TITLE.HGR/KARATE.CHAMP b/res/TITLE.HGR/KARATE.CHAMP index 3220abd..2f8a620 100644 Binary files a/res/TITLE.HGR/KARATE.CHAMP and b/res/TITLE.HGR/KARATE.CHAMP differ diff --git a/res/TITLE.HGR/ONE.ON.ONE b/res/TITLE.HGR/ONE.ON.ONE index a29809b..00f6c14 100644 Binary files a/res/TITLE.HGR/ONE.ON.ONE and b/res/TITLE.HGR/ONE.ON.ONE differ diff --git a/res/TITLE.HGR/POOL b/res/TITLE.HGR/POOL index 3f866f4..79701ff 100644 --- a/res/TITLE.HGR/POOL +++ b/res/TITLE.HGR/POOL @@ -1 +1 @@ -ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€üùÿùƒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ïÿ‡øÿU*U*U*U*U*U*ÿ¿€€ÿÿU*U*U*U*U*U*ÿ‡øÿý*uŠ€€€Ó¶åøãÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©ÍŸö¿¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý*uŠ€€€ÓÆŸÓš¿€€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‡øÿU*U*U*U*U*U*ÿÿàÿÿU*U*U*U*U*U*ÿ‡øÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ü±å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ü€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€ü€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€€˜Õ׌€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ïÿðÿU*U*U*U*U*U*ÿŸ€€þÿU*U*U*U*U*U*ÿƒàÿý*uŠ€€€ÓžÕ°ªƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©½ê†ìÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€üý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÕŒ€Óš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŸüÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿþÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«¶å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«†€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€ü±åÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ïÿ€àÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ€€þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿý*uŠ€€€üùÿùóÿƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€€«¶êøãÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U€¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€þý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÿÏŸÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«ÆŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«†€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÕªU*U*U*U*U*U*ÕªÕªÕªU*U*U*U*U*U*ÕªÕªÕ*uŠ€€€Ó¶åÓš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ï¿€Àÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€üÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿý*uŠ€€€€˜Õ‡¼ªó‡€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý€€€€€€€€ïŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€þý*uŠ€€€«ÞÊ°ªó‡€€€€€€€€€€€€€€€€€€€€€€€Ô+U€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€þý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÕ¼åÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€ÓÆŸÓš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ï¿€€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€ÿý*uŠ€€€ü±åöíÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿý€€€€€€€€ï¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿý*uŠ€€€üÙÊùóÿƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€üÿÿÿÿÿÿÿÿÿÿÿÿÿ¿€€ÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€Ó¶åøƒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UªÕªÕªU*U*U*U*U*U*ÕªÕªÕªU*U*U*U*U*U*ÕªÕªÕ€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€À©ÍŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€ÀÕŒ€Óš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ïŸ€€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€þý*uŠ€€€«¶å›ûÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€þý€€€€€€€€ïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý*uŠ€€€€ØÊ×¼ªƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€ÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ€€þÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ÓžÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€À©½å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€ÀÿÏŸÖŒ¿€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ïŸ€€¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€þý*uŠ€€€«ÆŸó™¿¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý*uŠ€€€ü±êÖìÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€àÿU*U*U*U*U*U*ÿŸ€€þÿU*U*U*U*U*U*ÿÀÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€üùÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«†€€€€€€€€€€€€€€€øƒ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€øƒ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«¶å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿŸüÿU*U*U*U*U*U*ÿÿàÿÿU*U*U*U*U*U*ÿþÿý*uŠ€€ÀÕ¼åÖìÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©€››€¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý*uŠ€€€Ó¶êÓúÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿðÿU*U*U*U*U*U*ÿ¿€€ÿÿU*U*U*U*U*U*ÿƒàÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€˜Õ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«†€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«žÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ \ No newline at end of file +ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€üùÿùƒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€ïÿ‡øÿU*U*U*U*U*U*ÿ¿€€ÿÿU*U*U*U*U*U*ÿ‡øÿý*uŠ€€€Ó¶åøãÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©ÍŸö¿¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý*uŠ€€€ÓÆŸÓš¿€€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‡øÿU*U*U*U*U*U*ÿÿàÿÿU*U*U*U*U*U*ÿ‡øÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ü±å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ü€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«†*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€ü€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€þïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€€˜Õ׌€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€ïÿðÿU*U*U*U*U*U*ÿŸ€€þÿU*U*U*U*U*U*ÿƒàÿý*uŠ€€€ÓžÕ°ªƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©½ê†ìÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€üý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÕŒ€Óš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŸüÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿþÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«¶å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«†€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€ü±åÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€ïÿ€àÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ€€þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿý*uŠ€€€üùÿùóÿƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€€«¶êøãÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U€¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€þý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÿÏŸÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«ÆŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«†€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ªÕªÕªU*U*U*U*U*U*ÕªÕªÕªU*U*U*U*U*U*ÕªÕªÕ*uŠ€€€Ó¶åÓš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€Ô+Uï¿€Àÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€üÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿý*uŠ€€€€˜Õ‡¼ªó‡€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý€€€€€€€€ïŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€þý*uŠ€€€«ÞÊ°ªó‡€€€€€€€€€€€€€€€€€€€€€€€Ô+U€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€þý€€€€€€€€ïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý*uŠ€€ÀÕ¼åÖŒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€ÿŸ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€€ÓÆŸÓš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ï¿€€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€ÿý*uŠ€€€ü±åöíÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿý€€€€€€€€ï¿€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÿý*uŠ€€€üÙÊùóÿƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€üÿÿÿÿÿÿÿÿÿÿÿÿÿ¿€€ÿý€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€Ó¶åøƒ€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UªÕªÕªU*U*U*U*U*U*ÕªÕªÕªU*U*U*U*U*U*ÕªÕªÕ*uŠ€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€À©ÍŸ€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€ÀÕŒ€Óš€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ïŸ€€ªÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª•€€þý*uŠ€€€«¶å›ûÊ­™€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€þý€€€€€€€€ïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý*uŠ€€€€ØÊ×¼ªƒ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uï¿€ÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ€€þÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€ÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€ÓžÕ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€À©€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€þ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€«ž*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Õ€€€€€€*uŠ€€À©½å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý*uŠ€€ÀÿÏŸÖŒ¿€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ïŸ€€¨ÕªÕªÕªÕªÕªÕªÕŠ€€ÔªÕªÕªÕªÕªÕªÕª…€€þý*uŠ€€€«ÆŸó™¿¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€Ô+Uïÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Àÿý*uŠ€€€ü±êÖìÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+Uïÿ€àÿU*U*U*U*U*U*ÿŸ€€þÿU*U*U*U*U*U*ÿÀÿý*uŠ€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€üùÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«†€€€€€€€€€€€€€€€øƒ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€øƒ€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€«¶å€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ïÿŸüÿU*U*U*U*U*U*ÿÿàÿÿU*U*U*U*U*U*ÿþÿý*uŠ€€ÀÕ¼åÖìÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ôÿý€€€€€€€€ï€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý*uŠ€€À©€››€¦µ€€€€€€€€€€€€€€€€€€€€€€€Ô+U€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€üý€€€€€€€€ïÿ‚€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ðÿý*uŠ€€€Ó¶êÓúÊ€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿðÿU*U*U*U*U*U*ÿ¿€€ÿÿU*U*U*U*U*U*ÿƒàÿý€€€€€€€€*uŠ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+U*uŠ€€€€˜Õ€€€€€€€€€€€€€€€€€€€€€€€€€€€Ô+UïÿÿÿÿU*U*U*U*U*U*ÿÿÿÿÿÿU*U*U*U*U*U*ÿÿÿÿý€€€€€€€€ \ No newline at end of file diff --git a/res/TITLE.HGR/SHUFFLEBOARD b/res/TITLE.HGR/SHUFFLEBOARD index 6a502bc..91341d8 100644 Binary files a/res/TITLE.HGR/SHUFFLEBOARD and b/res/TITLE.HGR/SHUFFLEBOARD differ diff --git a/res/TITLE.HGR/SKI.CRAZED b/res/TITLE.HGR/SKI.CRAZED index a89d597..0cda88b 100644 Binary files a/res/TITLE.HGR/SKI.CRAZED and b/res/TITLE.HGR/SKI.CRAZED differ diff --git a/res/TITLE.HGR/SOLO.FLIGHT b/res/TITLE.HGR/SOLO.FLIGHT index 82e521c..2518b90 100644 Binary files a/res/TITLE.HGR/SOLO.FLIGHT and b/res/TITLE.HGR/SOLO.FLIGHT differ diff --git a/res/TITLE.HGR/SPDWAY.CLASSIC b/res/TITLE.HGR/SPDWAY.CLASSIC index ec6f4a6..9572157 100644 Binary files a/res/TITLE.HGR/SPDWAY.CLASSIC and b/res/TITLE.HGR/SPDWAY.CLASSIC differ diff --git a/res/TITLE.HGR/SUMMER.GAMES b/res/TITLE.HGR/SUMMER.GAMES index 553ae4d..d2a8176 100644 Binary files a/res/TITLE.HGR/SUMMER.GAMES and b/res/TITLE.HGR/SUMMER.GAMES differ diff --git a/res/TITLE.HGR/SUMMER.GAMES.II b/res/TITLE.HGR/SUMMER.GAMES.II index f73916c..ca772ad 100644 Binary files a/res/TITLE.HGR/SUMMER.GAMES.II and b/res/TITLE.HGR/SUMMER.GAMES.II differ diff --git a/res/TITLE.HGR/SUPER.HUEY b/res/TITLE.HGR/SUPER.HUEY index 344ff8d..f5228f8 100644 Binary files a/res/TITLE.HGR/SUPER.HUEY and b/res/TITLE.HGR/SUPER.HUEY differ diff --git a/res/TITLE.HGR/SUPER.ICEHOCKEY b/res/TITLE.HGR/SUPER.ICEHOCKEY index e3c41e8..f97af31 100644 Binary files a/res/TITLE.HGR/SUPER.ICEHOCKEY and b/res/TITLE.HGR/SUPER.ICEHOCKEY differ diff --git a/res/TITLE.HGR/TAG.TEAM b/res/TITLE.HGR/TAG.TEAM index 51d7cba..860548a 100644 Binary files a/res/TITLE.HGR/TAG.TEAM and b/res/TITLE.HGR/TAG.TEAM differ diff --git a/res/TITLE.HGR/THE.DAM.BUSTERS b/res/TITLE.HGR/THE.DAM.BUSTERS index c898706..4d9b8a6 100644 Binary files a/res/TITLE.HGR/THE.DAM.BUSTERS and b/res/TITLE.HGR/THE.DAM.BUSTERS differ diff --git a/res/TITLE.HGR/TOMAHAWK b/res/TITLE.HGR/TOMAHAWK index 9eb6191..b0c4cf6 100644 Binary files a/res/TITLE.HGR/TOMAHAWK and b/res/TITLE.HGR/TOMAHAWK differ diff --git a/res/TITLE.HGR/TRACK.AND.FIELD b/res/TITLE.HGR/TRACK.AND.FIELD index 6f0ff07..7d14460 100644 Binary files a/res/TITLE.HGR/TRACK.AND.FIELD and b/res/TITLE.HGR/TRACK.AND.FIELD differ diff --git a/res/TITLE.HGR/WINTER.GAMES b/res/TITLE.HGR/WINTER.GAMES index 666d2d3..1fd2967 100644 Binary files a/res/TITLE.HGR/WINTER.GAMES and b/res/TITLE.HGR/WINTER.GAMES differ diff --git a/res/TITLE.HGR/WORLD.KARATE b/res/TITLE.HGR/WORLD.KARATE index 0e0404a..ca37af6 100644 Binary files a/res/TITLE.HGR/WORLD.KARATE and b/res/TITLE.HGR/WORLD.KARATE differ diff --git a/res/TITLE.HGR/_FileInformation.txt b/res/TITLE.HGR/_FileInformation.txt index 00a5107..1f7e5cf 100644 --- a/res/TITLE.HGR/_FileInformation.txt +++ b/res/TITLE.HGR/_FileInformation.txt @@ -1,36 +1,36 @@ # This file is automatically generated AMER.CHALLENGE=Type(06),AuxType(4000),Access(C3) -AUTOBAHN=Type(06),AuxType(4000),Access(C3) +AUTOBAHN=Type(06),AuxType(4000)C3) BASEBALL=Type(06),AuxType(4000),Access(C3) BLACK.BELT=Type(06),AuxType(4000),Access(C3) -BOP.N.WRESTLE=Type(06),AuxType(4000),Access(C3) +BOP.N.WRESTLE=Type(06),AuxType(4000)C3) CHAMP.BSKETBALL=Type(06),AuxType(4000),Access(C3) CHAMP.WRESTLE=Type(06),AuxType(4000),Access(C3) -CMPTR.FOOSBALL=Type(06),AuxType(4000),Access(C3) +CMPTR.FOOSBALL=Type(06),Au00),Access(C3) DIVE.BOMBER=Type(06),AuxType(4000),Access(C3) FIGHT.NIGHT=Type(06),AuxType(4000),Access(C3) -FORMULA.1.RACER=Type(06),AuxType(4000),Access(C3) +FORMULA.1.RACER=Type(ype(4000),Access(C3) FS2=Type(06),AuxType(4000),Access(C3) FUJI.SPEED.WAY=Type(06),AuxType(4000),Access(C3) -HARDBALL=Type(06),AuxType(4000),Access(C3) +HARDBALL=Type(06),Au00),Access(C3) INTL.GRAN.PRIX=Type(06),AuxType(4000),Access(C3) INTL.HOCKEY=Type(06),AuxType(4000),Access(C3) -KARATE.CHAMP=Type(06),AuxType(4000),Access(C3) +KARATE.CHAMP=Type(ype(4000),Access(C3) ONE.ON.ONE=Type(06),AuxType(4000),Access(C3) POOL=Type(06),AuxType(4000),Access(C3) -SHUFFLEBOARD=Type(06),AuxType(4000),Access(C3) +SHUFFLEBOARD=Type(06),A000),Access(C3) SKI.CRAZED=Type(06),AuxType(4000),Access(C3) SOLO.FLIGHT=Type(06),AuxType(4000),Access(C3) -SPDWAY.CLASSIC=Type(06),AuxType(4000),Access(C3) +SPDWAY.CLASSIC=Type(0pe(4000),Access(C3) SUMMER.GAMES=Type(06),AuxType(4000),Access(C3) SUMMER.GAMES.II=Type(06),AuxType(4000),Access(C3) -SUPER.HUEY=Type(06),AuxType(4000),Access(C3) +SUPER.HUEY=,AuxType(4000),Access(C3) SUPER.ICEHOCKEY=Type(06),AuxType(4000),Access(C3) TAG.TEAM=Type(06),AuxType(4000),Access(C3) -THE.DAM.BUSTERS=Type(06),AuxType(4000),Access(C3) +THE.DAM.Bype(06),AuxType(4000),Access(C3) TOMAHAWK=Type(06),AuxType(4000),Access(C3) TRACK.AND.FIELD=Type(06),AuxType(4000),Access(C3) -WINTER.GAMES=Type(06),AuxType(4000),Access(C3) +WIES=Type(06),AuxType(4000),Access(C3) WORLD.KARATE=Type(06),AuxType(4000),Access(C3) -_FileInformation.txt=Type(06),AuxType(4000),Access(C3) +_FileInformation.txt=Type(06),AuxType(4000),3) diff --git a/src/4sports.a b/src/4cade.a similarity index 84% rename from src/4sports.a rename to src/4cade.a index 5f1a592..e35da6f 100644 --- a/src/4sports.a +++ b/src/4cade.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2018-2021 by 4am +;(c) 2018-2020 by 4am ; !cpu 6502 !to "build/LAUNCHER.SYSTEM",plain @@ -14,9 +14,9 @@ RELBASE=$2000 ; first-run initialization, relocates code to language card and jumps ; to |Reenter| - !source "src/4sports.init.a" - !source "src/4sports.init.cffa.a" - !source "src/4sports.init.gs.a" + !source "src/4cade.init.a" + !source "src/4cade.init.cffa.a" + !source "src/4cade.init.gs.a" FirstMover !pseudopc RELBASE { @@ -78,14 +78,15 @@ RestoreStackNextTime ; reset to branch so we don't try to sta RestoreStackNextTime + 1 ; restore the same stack twice - ldx #$F1 -- lda STACKBASE - $EF,x ; restore stack - sta $100,x - inx - bne - STACKPTR ldx #$D1 ; SMC, restore stack pointer txs + inx +- lda STACKBASE - $100 + gStackSize,x + ; restore stack + sta $100,x + inx + bne - SwitchToBank1 +READ_RAM1_WRITE_RAM1 rts @@ -103,6 +104,7 @@ ResetVector ; 6 bytes, copied to $100 !source "src/ui.attract.dhgr.a" !source "src/ui.attract.shr.a" !source "src/ui.attract.gr.a" + !source "src/ui.attract.dgr.a" !source "src/ui.offscreen.a" !source "src/ui.cheats.a" !source "src/ui.credits.a" @@ -111,7 +113,6 @@ ResetVector ; 6 bytes, copied to $100 !source "src/ui.font.a" !source "src/ui.overlay.a" !source "src/parse.prefs.a" - !source "src/parse.common.a" !source "src/glue.launch.a" !source "src/glue.prorwts2.a" !source "src/glue.decompress.a" @@ -122,12 +123,19 @@ ResetVector ; 6 bytes, copied to $100 ; add new files above here !source "src/hw.vbl.a" !source "src/ui.wait.a" -gAttractModeStore -gFXStore -gDFXStore - !word $6000 + +gMegaAttractModeFilter ; module types to include in mega-attract mode + !byte %11111111 +; |||||||+- bit 0 include self-running demos +; ||||||+-- bit 1 include HGR title slideshows +; |||||+--- bit 2 include HGR action slideshows +; ||||+---- bit 3 include DHGR title slideshows +; |||+----- bit 4 include DHGR action slideshows +; ||+------ bit 5 include SHR box art slideshows +; |+------- bit 6 include GR action slideshows +; +-------- bit 7 include DGR action slideshows gSearchStore - !word $8200 + !word $6000 gSlideshowStore !word $0800 gGlobalPrefsStore @@ -135,13 +143,17 @@ gGlobalPrefsStore ; flips out if it has certain values (it will ; be set to $55 as part of the 64K memory test, ; which is apparently one of the acceptable values) -gGamesListStore - !word $FDFD ; SMC SwitchToBank2 +READ_RAM2_WRITE_RAM2 rts !source "src/prodos.path.a" ; paths end up on the same page +; iAddToPath (label is in constants.a) + jmp AddToPath ; no direct calling - target can move + +; iLoadFileDirect (label is in constants.a) + jmp LoadFileDirect ; no direct calling - target can move + ; WaitForVBL (label is in constants.a) jmp WaitForVBL_iie ; SMC to RTS on a II+ @@ -174,24 +186,21 @@ COPYSRC = * !pseudopc hdddataend { COPYDST = * !source "src/prodos.impl.lc2.a" - !source "src/ui.font.lc2.a" !source "src/glue.prorwts2.lc2.a" !source "src/glue.launch.lc2.a" !source "src/hw.accel.lc2.a" STACKBASE = * - LCRAM2_END = STACKBASE + 15 + OKVS_CACHE = STACKBASE + gStackSize + LCRAM2_END = OKVS_CACHE + 5 !if LCRAM2_END >= DisableAccelerator { !error "code is too large: ends at ", LCRAM2_END } - FONTDST = (LCRAM2_END + 255) and -256 + FONTDST = $E000 } EvenLasterMover FONTSRC = * !pseudopc FONTDST { - !source "src/ui.font.data.lc2.a" - !if * > $E000 { - !error "code is too large: ends at ", * - } + !source "src/ui.font.data.a" } !if RELBASE = $2000 { !ifdef PASS2 { @@ -199,6 +208,7 @@ EvenLasterMover !set PASS2=1 !warn "ProRWTS ends at ", hdddataend - 1 !warn "STACK at ", STACKBASE + !warn "OKVS CACHE at ", OKVS_CACHE !warn "LCRAM2 ends at ", LCRAM2_END !warn "RELBASE = ", $10000 - (LastMover - FirstMover) } diff --git a/src/4sports.init.a b/src/4cade.init.a similarity index 77% rename from src/4sports.init.a rename to src/4cade.init.a index 6ef02a7..e25c308 100644 --- a/src/4sports.init.a +++ b/src/4cade.init.a @@ -18,6 +18,44 @@ jsr ROM_NORMAL jsr ROM_IN0 jsr ROM_PR0 + + ; accommodate uppercase-only machines (64K ][+ is supported) + lda ROM_MACHINEID + cmp #$A0 + beq + ; Spectrum ED + cmp #$06 + beq + + lda #$DF + +HIDE_NEXT_2_BYTES ++ lda #$FF + sta zpCharMask + + ; print text title in same place as graphical title will appear + ldy #14 +- lda II,y + ora #$80 + +FORCE_UPPERCASE_IF_REQUIRED + sta $070C,y + dey + bpl - + ldy #12 +- lda INSTANT,y + ora #$80 + sta $04B5,y + dey + bpl - + ldy #10 +- lda REPLAY,y + ora #$80 + sta $0536,y + dey + bpl - + + ; TODO make this true again + ; proboothd duplicates the above code and jumps here, + ; so if you make any changes before this comment, you + ; MUST adjust the final JMP in src/proboothd/proboothd.a + jsr Has64K ; check for 64K (required) bcc + @@ -57,42 +95,10 @@ ; bit 7 = 1 if joystick ; and all other bits are 0 (we'll set bit 3 after copying it to LC RAM) - ; accommodate uppercase-only machines (64K ][+ is supported) - lda ROM_MACHINEID - cmp #$A0 - beq + ; Spectrum ED - cmp #$06 - beq + - lda #$DF - +HIDE_NEXT_2_BYTES -+ lda #$FF - sta zpCharMask - - ; print text title in same place as graphical title will appear - ldy #14 -- lda II,y - ora #$80 - +FORCE_UPPERCASE_IF_REQUIRED - sta $070C,y - dey - bpl - - ldy #12 -- lda INSTANT,y - ora #$80 - sta $04B5,y - dey - bpl - - ldy #10 -- lda REPLAY,y - ora #$80 - sta $0536,y - dey - bpl - - ; increase text window width so we can print to the edge of the screen without scrolling inc $21 ; print version or build number in lower right corner - ldx #30 + ldx #28 ldy #23 jsr SetCursorPosition +LDADDR LoadingVersion @@ -105,7 +111,7 @@ } ; set up text window so it only covers lower left corner - lda #30 + lda #28 sta $21 lda #19 sta $22 @@ -184,7 +190,7 @@ ldy #4 @ELM lda FONTSRC,x - ; relocate font data to RAM bank 2 + ; relocate font data to $E000 sta FONTDST,x inx bne @ELM @@ -282,14 +288,14 @@ REPLAY !text "R E P L A Y" !ifndef RELEASE { LoadingVersion - !byte 8 - !text "build 00" + !byte 10 + !text " build 00" LoadingBuild !word BUILDNUMBER } else { LoadingVersion - !byte 10 - !text " v1.0" + !byte 12 + !text "v1.0-alpha.1" } Loading64K !byte 3 @@ -346,7 +352,7 @@ PrintAsDecimal !source "src/hw.accel.a" !source "src/hw.vbl.init.a" - !source "src/parse.games.a" + !source "src/parse.common.a" OneTimeSetup lda zpMachineStatus @@ -373,8 +379,9 @@ CopyDevs lda hddopendir+1 ; save current directory as 'root' ldy hddopendir+3 + sta gRootDirectory+1 + sty gRootDirectory+3 jsr SwitchToBank1 - +ST16 gRootDirectory jsr LoadFile ; load preferences file into $8000 !word kRootDirectory @@ -384,42 +391,11 @@ CopyDevs !word gGlobalPrefsStore !word - !byte 16 - +LD16 SRC ; (SRC) points to free space after the OKVS data structure we just created - +ST16 gGamesListStore ; save pointer to free space for next store - - jsr LoadFile ; load games list file into $8200 - !word kRootDirectory - !word @kGameListConfFile -- !word $8200 - jsr ParseGamesList ; parse games list into OKVS data structure in LC RAM bank - !word gGamesListStore - !word - - -!ifndef RELEASE { - +READ_ROM_NO_WRITE - lda #40 - sta $21 - lda #36 - sta $24 - dec $25 - jsr $FC22 - lda SRC+1 - jsr $FDDA - lda SRC - jsr $FDDA - +READ_RAM1_WRITE_RAM1 -} - - +LDADDR gGamesListStore - jsr okvs_len - +LD16 WCOUNT - +ST16 GameCount - +ST16 SAVE jsr pref_get ; see if cheats are enabled by default + ; sets PTR -> cheat pref value as length-prefixed string '1' or '0' !word kCheat !word 0 - +ST16 PTR ; (PTR) -> cheat pref value as length-prefixed string '1' or '0' ldy #1 lda (PTR),y ; A = #$B1 or #$B0 and #1 ; A = #$01 or #$00 @@ -429,8 +405,40 @@ CopyDevs ora MachineStatus sta MachineStatus ; set bit 3 of MachineStatus - ; calculate and update visible game count (3-digit decimal number as ASCII string) - dey ; Y = 0 + rol + rol + rol + rol + and #%00000110 + tax ; X in (0,2,4,6) + ldy kGameCounts, x + sty GameCount ; store total game count based on based on (has-joystick) X (has-128K) + sty SAVE + ldy kGameCounts+1, x + sty GameCount+1 + sty SAVE+1 + lsr + tax ; X in (0,1,2,3) + lda kSearchIndexLo, x + sta @searchIndexSrc+1 ; set up search index record based on (has-joystick) X (has-128K) + lda kSearchIndexHi, x + sta @searchIndexSrc+2 + lda kSearchCacheLo, x + sta @searchCacheSrc+1 ; set up search cache record based on (has-joystick) X (has-128K) + lda kSearchCacheHi, x + sta @searchCacheSrc+2 + ldy #5 +@searchIndexSrc + lda $FDFD, y ; SMC + sta kSearchIndexRecord, y +@searchCacheSrc + lda $FDFD, y + sta kSearchCacheRecord, y + dey + bpl @searchIndexSrc + + ; convert GameCount (word) to VisibleGameCount (3-digit decimal number as ASCII string) + iny ; Y = 0 @outer lda #0 pha @@ -461,11 +469,49 @@ CopyDevs bit CLEARKBD jmp Reenter -@kGameListConfFile - !byte 10 - !text "GAMES.CONF" - @kPowersOfTen !byte 100 !byte 10 !byte 1 + +kSearchIndexLo + !byte kSearchIndexRecord00 + !byte >kSearchIndexRecord01 + !byte >kSearchIndexRecord10 + !byte >kSearchIndexRecord11 +kSearchCacheLo + !byte kSearchCacheRecord00 + !byte >kSearchCacheRecord01 + !byte >kSearchCacheRecord10 + !byte >kSearchCacheRecord11 +kSearchIndexRecord00 + !source "src/index/search00.idx.a" +kSearchIndexRecord01 + !source "src/index/search01.idx.a" +kSearchIndexRecord10 + !source "src/index/search10.idx.a" +kSearchIndexRecord11 + !source "src/index/search11.idx.a" +kSearchCacheRecord00 + !source "src/index/cache00.idx.a" +kSearchCacheRecord01 + !source "src/index/cache01.idx.a" +kSearchCacheRecord10 + !source "src/index/cache10.idx.a" +kSearchCacheRecord11 + !source "src/index/cache11.idx.a" +kGameCounts + !source "src/index/count00.a" + !source "src/index/count01.a" + !source "src/index/count10.a" + !source "src/index/count11.a" diff --git a/src/4sports.init.cffa.a b/src/4cade.init.cffa.a similarity index 100% rename from src/4sports.init.cffa.a rename to src/4cade.init.cffa.a diff --git a/src/4sports.init.gs.a b/src/4cade.init.gs.a similarity index 100% rename from src/4sports.init.gs.a rename to src/4cade.init.gs.a diff --git a/src/constants.a b/src/constants.a index 4a2784d..33ed210 100644 --- a/src/constants.a +++ b/src/constants.a @@ -1,26 +1,75 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2022 by 4am ; ;------------------------------------------------------------------------------ ; YE OLDE GRAND UNIFIED MEMORY MAP ; ; LC RAM BANK 1 -; D000..E92C - persistent data structures (gGlobalPrefsStore, gGamesListStore) -; E92D..FFF1 - main program code -; FFF2..FFF9 - API functions and global constants available for main program +; D000 - reserved +; D001..D06E - gGlobalPrefsStore +; ...unused... +; E000..E3FF - HGR font data +; ...unused... +; E730..FFEB - main program code +; FFEC..FFF9 - API functions and global constants available for main program ; code, prelaunchers, transition effects, &c. -; (Wait/UnwaitForVBL, MockingboardStuff, MachineStatus) +; (LoadFileDirect, Wait/UnwaitForVBL, MockingboardStuff, MachineStatus) ; FFFA..FFFF - NMI, reset, IRQ vectors ; ; LC RAM BANK 2 -; D000..D3FF - ProRWTS data -; D400..D677 - ProRWTS code -; D678..DB9D - HGR font code & ProRWTS glue code -; DB9E..DBAD - backup of stack (during gameplay and self-running demos) +; D000..D5FF - ProRWTS data +; D600..D8BD - ProRWTS code +; D8BE..DC76 - ProRWTS glue code +; DC77..DC7C - backup of stack (during gameplay and self-running demos) +; DC7D..DC82 - okvs cache (attract state saved across self-running demo) ; ...unused... -; DBB4..DBFF - (de)acceleration function -; DC00..DFFF - HGR font data +; DFB4..DFFF - (de)acceleration function +; +; MAIN MEMORY DURING SEARCH/BROWSE MODE +; 6000..9FFF - search index +; A000..BCFF - search cache +; BD00..BEFF - prefs buffer (used to write PREFS.CONF if cheat mode changes) +; BF00..BFFF - ProRWTS glue (supports LoadIndexedFile) +; +; MAIN MEMORY DURING MEGA-ATTRACT MODE +; 0100..0105 - re-entry code for demos (reloaded before demo) +; 0106..01BF - prelaunch code (reloaded before demo) +; 0400..07FF - text screen (cleared before each module) +; 0800..1EFF - slideshow configuration file (persistent during slideshow module) +; 2000..5FFF - hi-res screens (cleared before each module) +; 4000..5FFF - slideshow index file (loaded before slideshow module) +; 6000.. - mega-attract configuration file (reloaded before each module) +; BD00..BEFF - prefs buffer (clobbered if cheat mode changes) +; BF00..BFFF - ProRWTS glue (reset after demo) +; +; MAIN MEMORY DURING MINI-ATTRACT MODE +; 0100..0105 - re-entry code for demos (reloaded before demo) +; 0106..01BF - prelaunch code (reloaded before demo) +; 0400..07FF - text screen (cleared before each module) +; 0800..1FFF - mini-attract index file (loaded once) +; 2000..5FFF - hi-res screens +; 6000.. - mini-attract configuration file (reloaded before each module) +; 6000.. - transition effect code (reloaded before each screenshot module) +; BF00..BFFF - ProRWTS glue (reset after demo) +; +; MAIN MEMORY DURING GAME LAUNCH +; 0100..0105 - re-entry code +; 0106..01BF - prelaunch code +; 0400..7FFF - text screen cleared +; 2000..5FFF - hi-res screens cleared +; A000.. - prelaunch index file +; +; MAIN MEMORY DURING CREDITS (preserves search index and cache) +; 0800.. - credits text +; +; MAIN MEMORY DURING GLOBAL HELP (preserves search index and cache) +; 0800.. - help text +; +; MAIN MEMORY DURING PER-GAME HELP (clobbers search cache) +; 0800.. - help text +; A000.. - game help index file +; ;------------------------------------------------------------------------------ !ifndef _CONSTANTS_ { @@ -39,11 +88,11 @@ CLR80VID = $C00C ; 40 columns (also used to get out of DHGR mode) SET80VID = $C00D ; 80 columns (also used to get into DHGR mode) PRIMARYCHARSET= $C00E ; no mousetext for you SLOT3STATUS = $C017 ; bit 7 only -TBCOLOR = $C022 ; IIgs text foreground and background colors (also VidHD) +TBCOLOR = $C022 ; IIgs text foreground and background colors (also VidHD but write-only) NEWVIDEO = $C029 ; IIgs graphics modes (also VidHD) SPEAKER = $C030 ; chirp chirp -CLOCKCTL = $C034 ; bits 0-3 are IIgs border color (also VidHD) -SHADOW = $C035 ; IIgs auxmem-to-bank-E1 shadowing (also VidHD) +CLOCKCTL = $C034 ; bits 0-3 are IIgs border color (also VidHD but write-only) +SHADOW = $C035 ; IIgs auxmem-to-bank-E1 shadowing (also VidHD but write-only) TEXTMODE = $C051 PAGE1 = $C054 ; page 1 (affects text, HGR, DHGR) PAGE2 = $C055 ; page 2 (affects text, HGR, DHGR) @@ -57,6 +106,7 @@ ROM_TEXT2COPY =$F962 ; turn on alternate display mode on IIgs ROM_REBOOT = $FAA6 ROM_TEXT = $FB2F ROM_MACHINEID =$FBB3 +ROM_MACHINE2C =$FBC0 ROM_HOME = $FC58 ROM_COUT = $FDED ROM_NORMAL = $FE84 ; NORMAL text (instead of INVERSE or FLASH) @@ -100,12 +150,10 @@ firstletter= $FA ; byte MatchCount = $FB ; byte BestMatchScore = $FC ; byte -; $FE ; used by ParseGamesList -; $FF ; used by ParseGamesList - ; main memory +gStackSize = 6 ; seems like only six are needed gPathname = $BFD0 ; used by SetPath/AddToPath -gKeyLen = $1F00 ; used by ParseGamesList +gKeyLen = $1F00 gKey = $1F01 UILine1 = $1FB0 UILine2 = $1FD8 @@ -114,25 +162,32 @@ UI_ToPlay = $1FF7 gValLen = $1F80 gVal = $1F81 -; LC RAM 1 +gSearchIndex = $6000 +gSearchCache = $A000 + +; LC RAM 1 & 2 +iAddToPath = $FFEC +iLoadFileDirect = $FFEF ; note: you really want LC RAM 2 banked in before calling this WaitForVBL = $FFF2 UnwaitForVBL = $FFF5 -MockingboardStuff = $FFF8 ; bit 7 = 1 if speech chip present (Mockingboard "C") - ; bit 6 = 1 if Mockingboard "B" (stereo) found (else Mockingboard "A") - ; bit 4-5 unused +MockingboardStuff = $FFF8 ; bit 7 = 1 if SC-01 speech chip present (Speech I) + ; bit 6 = 1 if SSI-263 speech chip present (Mockingboard "B"-"D") + ; bit 5 = 1 if two AY-3-8910s present (Sound II / Mockingboard "A"-"D") + ; bit 5 = 0 if only AY-3-8910 present (Sound I) + ; bit 4 unused ; bits 0-3: slot number MachineStatus = $FFF9 ; LC RAM 2 -DisableAccelerator = $DBB4 +DisableAccelerator = $DFB4 EnableAccelerator = DisableAccelerator+3 ; AND masks for MockingboardStuff MOCKINGBOARD_SLOT = %00001111 -HAS_SPEECH = %10000000 +HAS_SPEECH = %11000000 -; AND masks for game info bitfield (after game display name in gGamesListStore) +; AND masks for game info bitfield (after game display name in gSearchStore) HAS_DHGR_TITLE = %10000000 ; this one is hard-coded via BMI instead of AND/BNE CHEAT_CATEGORY = %00001111 @@ -144,20 +199,32 @@ HAS_VIDHD = %00010000 SUPPORTS_SHR = %00110000 CHEATS_ENABLED = %00001000 +; AND masks for gMegaAttractModeFilter +ATTRACT_DEMO = %00000001 +ATTRACT_HGR_TITLE = %00000010 +ATTRACT_HGR_ACTION = %00000100 +ATTRACT_DHGR_TITLE = %00001000 +ATTRACT_DHGR_ACTION = %00010000 +ATTRACT_SHR = %00100000 +ATTRACT_GR = %01000000 +ATTRACT_DGR = %10000000 + +PRELAUNCH_STANDARD_SIZE = 61 ; LoadStandardPrelaunch, eventually to be determined at build-time + ; shared symbols for prelaunch and effects to call ProRWTS2 functions -iCurBlockLo = $D401 -iCurBlockHi = $D403 -iProDOS_enter = $D678 -LoadFileDirect = $DB01 -iAuxReq = $DB27 -launchpatch = $D616 -iAddToPath = $FEC3 -itraverse = $D8E0 +iCurBlockLo = $D601 ; constant +iCurBlockHi = $D603 ; constant +launchpatch = $D85C ; glue.launch.a +itraverse = $DB4B ; Roger Rabbit, avoid, use Infiltrator 2 style instead + ; also Columns (via file in disk image) +ldrlo = $55 ; constant ldrhi = $56 ; constant namlo = $57 ; constant namhi = $58 ; constant -ldrlo2 = $59 ; constant -ldrhi2 = $5A ; constant +ldrlo2 = $64 ; constant +ldrhi2 = $65 ; constant + +; Columns and Dangerous Dave also call (de)accelerator functions directly _CONSTANTS_=* } diff --git a/src/fx/fx.cover.fade.a b/src/fx/fx.cover.fade.a old mode 100644 new mode 100755 index a5d51a3..08d40e4 --- a/src/fx/fx.cover.fade.a +++ b/src/fx/fx.cover.fade.a @@ -6,7 +6,7 @@ ; !cpu 6502 -!to "build/FX/COVERFADE",plain +!to "build/COVERFADE",plain *=$6000 !source "src/fx/macros.a" diff --git a/src/fx/fx.dgr.fizzle.a b/src/fx/fx.dgr.fizzle.a new file mode 100644 index 0000000..8d42dcf --- /dev/null +++ b/src/fx/fx.dgr.fizzle.a @@ -0,0 +1,52 @@ +;license:MIT +;(c) 2017-2021 by qkumba/4am/John Brooks +; +!cpu 6502 +!to "build/DGR.FIZZLE",plain +*=$6000 + + !source "src/fx/macros.a" + + +OVERCOPY_TO_0 start, end + ;$FF clobbered + ;X=0 + ;Y=0 + jmp loop + +start +!pseudopc 0 { + ;X=0 + ;Y=0 +loop txa +loop1 eor #$05 ; LFSR form 0x0500 with period 2047 +wait inx + bpl wait + tax +loop2 txa + ora #$04 + sta * != >STAGE0 { !error "Templates are not all on same page" } -; Note: the final k_rts is later copied to zero page $0F and used in MainLoop, -; so don't put any more code before BoxInitialStages. BoxInitialStages diff --git a/src/fx/fx.dhgr.48boxes.down.a b/src/fx/fx.dhgr.48boxes.down.a index df78e60..4b96c86 100644 --- a/src/fx/fx.dhgr.48boxes.down.a +++ b/src/fx/fx.dhgr.48boxes.down.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.DOWN",plain +!to "build/FX.INDEXED/DHGR.48.DOWN",plain *=$6000 USES_CLEAR = 0 diff --git a/src/fx/fx.dhgr.48boxes.longdiagonal.a b/src/fx/fx.dhgr.48boxes.longdiagonal.a index f0fb17a..ccbfa95 100644 --- a/src/fx/fx.dhgr.48boxes.longdiagonal.a +++ b/src/fx/fx.dhgr.48boxes.longdiagonal.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.LDIAGON",plain +!to "build/FX.INDEXED/DHGR.48.LDIAGON",plain *=$6000 USES_CLEAR = 0 diff --git a/src/fx/fx.dhgr.48boxes.pageturn.clear.a b/src/fx/fx.dhgr.48boxes.pageturn.clear.a new file mode 100644 index 0000000..257a2d6 --- /dev/null +++ b/src/fx/fx.dhgr.48boxes.pageturn.clear.a @@ -0,0 +1,51 @@ +;license:MIT +;(c) 2020 by 4am & qkumba +; +!cpu 6502 +!to "build/FX.INDEXED/DHGR.48.PAGEC",plain +*=$6000 + + !source "src/fx/fx.dhgr.48boxes.common.a" + + !byte $E1,$E2,$E1,$E7,$ED,$F3,$F9,$FF + !byte $E7,$E8,$E7,$E8,$EE,$F4,$FA,$00 + !byte $ED,$EE,$ED,$EE,$ED,$F3,$F9,$FF + !byte $F3,$F4,$F3,$F4,$F3,$F4,$FA,$00 + !byte $F9,$FA,$F9,$FA,$F9,$FA,$F9,$FF + !byte $FF,$00,$FF,$00,$FF,$00,$FF,$00 + +StagesHi ; high bytes of address of drawing routine for each stage + !byte clear0F + !byte clear0E + !byte clear0D + !byte clear0C + !byte clear0B + !byte clear0A + !byte clear09 + !byte clear08 + !byte clear07 + !byte clear06 + !byte clear05 + !byte clear04 + !byte clear03 + !byte clear02 + !byte clear01 + !byte clear00 + !byte 0,0,0,0,0,0,0,0,0,0,0,0,0 + !byte copy00 + !byte copy01 + !byte copy02 + !byte copy03 + !byte copy04 + !byte copy05 + !byte copy06 + !byte copy07 + !byte copy08 + !byte copy09 + !byte copy0A + !byte copy0B + !byte copy0C + !byte copy0D + !byte copy0E + !byte copy0F +EndStagesHi diff --git a/src/fx/fx.dhgr.48boxes.sidetoside.a b/src/fx/fx.dhgr.48boxes.sidetoside.a index 3257285..3eec14e 100644 --- a/src/fx/fx.dhgr.48boxes.sidetoside.a +++ b/src/fx/fx.dhgr.48boxes.sidetoside.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.SIDES",plain +!to "build/FX.INDEXED/DHGR.48.SIDES",plain *=$6000 USES_CLEAR = 0 diff --git a/src/fx/fx.dhgr.48boxes.snake.a b/src/fx/fx.dhgr.48boxes.snake.a index 243260e..de982eb 100644 --- a/src/fx/fx.dhgr.48boxes.snake.a +++ b/src/fx/fx.dhgr.48boxes.snake.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.SNAKE",plain +!to "build/FX.INDEXED/DHGR.48.SNAKE",plain *=$6000 USES_CLEAR = 0 diff --git a/src/fx/fx.dhgr.48boxes.snake.clear.a b/src/fx/fx.dhgr.48boxes.snake.clear.a index 13e6c17..f89925a 100644 --- a/src/fx/fx.dhgr.48boxes.snake.clear.a +++ b/src/fx/fx.dhgr.48boxes.snake.clear.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.SNAKEC",plain +!to "build/FX.INDEXED/DHGR.48.SNAKEC",plain *=$6000 !source "src/fx/fx.dhgr.48boxes.common.a" diff --git a/src/fx/fx.dhgr.48boxes.spiral.a b/src/fx/fx.dhgr.48boxes.spiral.a index 038e3c3..80d75e3 100644 --- a/src/fx/fx.dhgr.48boxes.spiral.a +++ b/src/fx/fx.dhgr.48boxes.spiral.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.SPIRAL",plain +!to "build/FX.INDEXED/DHGR.48.SPIRAL",plain *=$6000 USES_CLEAR = 0 diff --git a/src/fx/fx.dhgr.48boxes.spiral.clear.a b/src/fx/fx.dhgr.48boxes.spiral.clear.a index bbb55f9..b265fed 100644 --- a/src/fx/fx.dhgr.48boxes.spiral.clear.a +++ b/src/fx/fx.dhgr.48boxes.spiral.clear.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.SPIRALC",plain +!to "build/FX.INDEXED/DHGR.48.SPIRALC",plain *=$6000 !source "src/fx/fx.dhgr.48boxes.common.a" diff --git a/src/fx/fx.dhgr.48boxes.sync.a b/src/fx/fx.dhgr.48boxes.sync.a index 479f717..75f4e11 100644 --- a/src/fx/fx.dhgr.48boxes.sync.a +++ b/src/fx/fx.dhgr.48boxes.sync.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.SYNC",plain +!to "build/FX.INDEXED/DHGR.48.SYNC",plain *=$6000 USES_CLEAR = 0 diff --git a/src/fx/fx.dhgr.48boxes.sync.clear.a b/src/fx/fx.dhgr.48boxes.sync.clear.a index be09d80..4ecb098 100644 --- a/src/fx/fx.dhgr.48boxes.sync.clear.a +++ b/src/fx/fx.dhgr.48boxes.sync.clear.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am & qkumba ; !cpu 6502 -!to "build/FX/DHGR.48.SYNCC",plain +!to "build/FX.INDEXED/DHGR.48.SYNCC",plain *=$6000 !source "src/fx/fx.dhgr.48boxes.common.a" diff --git a/src/fx/fx.dhgr.bar.dissolve.a b/src/fx/fx.dhgr.bar.dissolve.a index 5697632..93a0763 100644 --- a/src/fx/fx.dhgr.bar.dissolve.a +++ b/src/fx/fx.dhgr.bar.dissolve.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am ; !cpu 6502 -!to "build/FX/DHGR.BAR.DISSLV",plain +!to "build/FX.INDEXED/DHGR.BAR.DISSLV",plain *=$6000 hgrlo = $0200 ; [$C0 bytes, main memory only] @@ -10,11 +10,8 @@ hgr1hi = $0300 ; [$C0 bytes, main memory only] !source "src/fx/macros.a" - ldx #(end-start) ; copy code to zero page -- lda start-1, x - sta $FF, x - dex - bne - + +COPY_TO_0 start, end + ;X=0 +BUILD_HGR_LOOKUP_TABLES_X_IS_ALREADY_0 hgrlo, hgr1hi jmp loop diff --git a/src/fx/fx.dhgr.bubbles.a b/src/fx/fx.dhgr.bubbles.a index 5f2f9aa..1930e86 100644 --- a/src/fx/fx.dhgr.bubbles.a +++ b/src/fx/fx.dhgr.bubbles.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BUBBLES",plain +!to "build/FX.INDEXED/DHGR.BUBBLES",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.bubbles.in.a b/src/fx/fx.dhgr.bubbles.in.a index e9a432c..6556416 100644 --- a/src/fx/fx.dhgr.bubbles.in.a +++ b/src/fx/fx.dhgr.bubbles.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BUBBLES.IN",plain +!to "build/FX.INDEXED/DHGR.BUBBLES.IN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.butterfly.a b/src/fx/fx.dhgr.butterfly.a index 1098314..7668ff9 100644 --- a/src/fx/fx.dhgr.butterfly.a +++ b/src/fx/fx.dhgr.butterfly.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BUTTERFLY",plain +!to "build/FX.INDEXED/DHGR.BUTTERFLY",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.butterfly.in.a b/src/fx/fx.dhgr.butterfly.in.a index 3c81dbf..f9e2424 100644 --- a/src/fx/fx.dhgr.butterfly.in.a +++ b/src/fx/fx.dhgr.butterfly.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BFLY.IN",plain +!to "build/FX.INDEXED/DHGR.BFLY.IN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.butterfly.ripple.a b/src/fx/fx.dhgr.butterfly.ripple.a index 5bfc2f9..16c9f23 100644 --- a/src/fx/fx.dhgr.butterfly.ripple.a +++ b/src/fx/fx.dhgr.butterfly.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BFLY.RIP",plain +!to "build/FX.INDEXED/DHGR.BFLY.RIP",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.corner4.a b/src/fx/fx.dhgr.corner4.a index 6c505b3..433d105 100644 --- a/src/fx/fx.dhgr.corner4.a +++ b/src/fx/fx.dhgr.corner4.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.CORNER4",plain +!to "build/FX.INDEXED/DHGR.CORNER4",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.corner4.in.a b/src/fx/fx.dhgr.corner4.in.a index 534bf29..f59054a 100644 --- a/src/fx/fx.dhgr.corner4.in.a +++ b/src/fx/fx.dhgr.corner4.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.CORNER4.IN",plain +!to "build/FX.INDEXED/DHGR.CORNER4.IN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.corner4.ripple.a b/src/fx/fx.dhgr.corner4.ripple.a index 89097ea..931d910 100644 --- a/src/fx/fx.dhgr.corner4.ripple.a +++ b/src/fx/fx.dhgr.corner4.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.CORNER4RIP",plain +!to "build/FX.INDEXED/DHGR.CORNER4RIP",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.diagonal.a b/src/fx/fx.dhgr.diagonal.a index 65dddca..c5805c1 100644 --- a/src/fx/fx.dhgr.diagonal.a +++ b/src/fx/fx.dhgr.diagonal.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/DHGR.DIAGONAL",plain +!to "build/FX.INDEXED/DHGR.DIAGONAL",plain *=$6000 hgrlo = $0200 ; [$C0 bytes, main memory only] @@ -11,12 +11,8 @@ copymasks= $02C0 ; [$08 bytes, different values in main and !source "src/fx/macros.a" - ldx #(end-start) ; copy code to zero page -- lda start-1, x - sta $FF, x - dex - bne - - + +COPY_TO_0 start, end + ;X=0 +BUILD_HGR_LOOKUP_TABLES_X_IS_ALREADY_0 hgrlo, hgr1hi ldy #8 ; copy copymask arrays into place in main and auxmem diff --git a/src/fx/fx.dhgr.fizzle.a b/src/fx/fx.dhgr.fizzle.a index d2712ec..d067471 100644 --- a/src/fx/fx.dhgr.fizzle.a +++ b/src/fx/fx.dhgr.fizzle.a @@ -2,10 +2,12 @@ ;(c) 2017-2020 by qkumba/4am/John Brooks ; !cpu 6502 -!to "build/FX/DHGR.FIZZLE",plain +!to "build/FX.INDEXED/DHGR.FIZZLE",plain *=$6000 -addrs=$C0 ; [$40 bytes] +addrs=$BF ; [$40 bytes] + + !source "src/fx/macros.a" ldx #$1F ; build address lookup table - txa @@ -15,18 +17,18 @@ addrs=$C0 ; [$40 bytes] sta addrs+$20, x dex bpl - - ldx #(end-start) ; copy LFSR code to zero page -- lda start-1, x - sta $FF, x - dex - bne - + + +OVERCOPY_TO_0 start, end + ;$FF clobbered + ;X=0 + ;Y=0 jmp copyaux start !pseudopc 0 { +;Y=0 on entry to copyaux copyaux sta $C003 ; copy $4000/aux to $8000/main ldx #$20 - ldy #$00 a lda $4000, y b sta $8000, y iny @@ -37,8 +39,7 @@ b sta $8000, y bne a sta $C002 sta $C001 ; 80STORE mode -; X,Y=0 on entry to LFSR -; in: X,Y=0 +;X,Y=0 on entry to LFSR loop txa loop1 eor #$35 ; LFSR form 0x3500 with period 16383 tax @@ -62,9 +63,9 @@ dst sta $FD00, y bmi exit txa bne loop1 -exit lda $4000 ; last lousy byte (because LFSR never hits 0) - sta $2000 - sta $C000 ; 80STORE mode off + lda (src+1), y ; last lousy byte (because LFSR never hits 0) + sta (dst+1), y +exit sta $C000 ; 80STORE mode off rts aux sta $C055 ; switch $2000 access to aux memory (read/write!) sta 127 then we're done +ROW_X_TO_BASE_ADDRESSES +ROW_X_TO_MIRROR_ADDRESSES diff --git a/src/fx/fx.dhgr.precomputed.2bit.a b/src/fx/fx.dhgr.precomputed.2bit.a index ca45f02..c233e5b 100644 --- a/src/fx/fx.dhgr.precomputed.2bit.a +++ b/src/fx/fx.dhgr.precomputed.2bit.a @@ -57,11 +57,7 @@ +BUILD_HGR_LOOKUP_TABLES_X_IS_ALREADY_0 hgrlo, hgr1hi +BUILD_MIRROR_COLS mirror_cols +COPY_SELF_TO_AUXMEM - ldx #(end-start) ; copy InputLoop code to zero page -- lda start-1, x - sta $FF, x - dex - bne - + +COPY_TO_0 start, end jmp InputLoop start @@ -70,7 +66,7 @@ Exit2Bit rts InputLoop ldy #0 input=*+1 - ldx .coords, y ; first value: HGR row + 1 + ldx .coords ; first value: HGR row + 1 beq Exit2Bit ; if 0 then we're done +ROW_X_TO_2BIT_BASE_ADDRESSES diff --git a/src/fx/fx.dhgr.r.by.pixel.a b/src/fx/fx.dhgr.r.by.pixel.a index e10d585..c1c3452 100644 --- a/src/fx/fx.dhgr.r.by.pixel.a +++ b/src/fx/fx.dhgr.r.by.pixel.a @@ -2,7 +2,7 @@ ;(c) 2018 by 4am ; !cpu 6502 -!to "build/FX/DHGR.R.BY.PIXEL",plain +!to "build/FX.INDEXED/DHGR.R.BY.PIXEL",plain *=$6000 hgrlo = $0201 ; [$C0 bytes, main memory only, offset by 1 because lookups will be based on $0200,x] @@ -11,12 +11,8 @@ copymasks= $02C1 ; [$07 bytes, different values in main and !source "src/fx/macros.a" - ldx #(end-start) ; copy code to zero page -- lda start-1, x - sta $FF, x - dex - bne - - + +COPY_TO_0 start, end + ;X=0 +BUILD_HGR_LOOKUP_TABLES_X_IS_ALREADY_0 hgrlo, hgr1hi ldy #7 ; copy copymask arrays into place in main and auxmem diff --git a/src/fx/fx.dhgr.radial.a b/src/fx/fx.dhgr.radial.a index fcd8224..0f27b2a 100644 --- a/src/fx/fx.dhgr.radial.a +++ b/src/fx/fx.dhgr.radial.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.RADIAL",plain +!to "build/FX.INDEXED/DHGR.RADIAL",plain *=$6000 mirror_src1 = $E8 ; word diff --git a/src/fx/fx.dhgr.radial2.a b/src/fx/fx.dhgr.radial2.a index 6b33c6c..c60413a 100644 --- a/src/fx/fx.dhgr.radial2.a +++ b/src/fx/fx.dhgr.radial2.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.RADIAL2",plain +!to "build/FX.INDEXED/DHGR.RADIAL2",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.radial3.a b/src/fx/fx.dhgr.radial3.a index 5567a8c..a44462c 100644 --- a/src/fx/fx.dhgr.radial3.a +++ b/src/fx/fx.dhgr.radial3.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.RADIAL3",plain +!to "build/FX.INDEXED/DHGR.RADIAL3",plain *=$6000 mirror_src1 = $E8 ; word diff --git a/src/fx/fx.dhgr.radial4.a b/src/fx/fx.dhgr.radial4.a index 4257249..a9dd46f 100644 --- a/src/fx/fx.dhgr.radial4.a +++ b/src/fx/fx.dhgr.radial4.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.RADIAL4",plain +!to "build/FX.INDEXED/DHGR.RADIAL4",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.radial5.a b/src/fx/fx.dhgr.radial5.a index b72d48d..7e7bcf7 100644 --- a/src/fx/fx.dhgr.radial5.a +++ b/src/fx/fx.dhgr.radial5.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.RADIAL5",plain +!to "build/FX.INDEXED/DHGR.RADIAL5",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.redlines.a b/src/fx/fx.dhgr.redlines.a index 78ec4b5..4f1810a 100644 --- a/src/fx/fx.dhgr.redlines.a +++ b/src/fx/fx.dhgr.redlines.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am ; !cpu 6502 -!to "build/FX/DHGR.REDLINES",plain +!to "build/FX.INDEXED/DHGR.REDLINES",plain *=$6000 ; for red line: @@ -14,11 +14,8 @@ hgr1hi = $0300 ; [$C0 bytes, main memory only] !source "src/fx/macros.a" - ldx #(end-start) ; copy code to zero page -- lda start-1, x - sta $FF, x - dex - bne - + +COPY_TO_0 start, end + ;X=0 +BUILD_HGR_LOOKUP_TABLES_X_IS_ALREADY_0 hgrlo, hgr1hi jmp loop diff --git a/src/fx/fx.dhgr.ripple.a b/src/fx/fx.dhgr.ripple.a index 5a961b1..28311e9 100644 --- a/src/fx/fx.dhgr.ripple.a +++ b/src/fx/fx.dhgr.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.RIPPLE",plain +!to "build/FX.INDEXED/DHGR.RIPPLE",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.slow.star.a b/src/fx/fx.dhgr.slow.star.a index 030acf4..6f14155 100644 --- a/src/fx/fx.dhgr.slow.star.a +++ b/src/fx/fx.dhgr.slow.star.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SLOW.STAR",plain +!to "build/FX.INDEXED/DHGR.SLOW.STAR",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.slow.star.in.a b/src/fx/fx.dhgr.slow.star.in.a index f2ef206..fc2c30b 100644 --- a/src/fx/fx.dhgr.slow.star.in.a +++ b/src/fx/fx.dhgr.slow.star.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SLOW.STARI",plain +!to "build/FX.INDEXED/DHGR.SLOW.STARI",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.slow.star.ripple.a b/src/fx/fx.dhgr.slow.star.ripple.a index 44b24fa..e3c2b19 100644 --- a/src/fx/fx.dhgr.slow.star.ripple.a +++ b/src/fx/fx.dhgr.slow.star.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SLOWST.RIP",plain +!to "build/FX.INDEXED/DHGR.SLOWST.RIP",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.snowflake.a b/src/fx/fx.dhgr.snowflake.a index ac8e01b..c60c7a4 100644 --- a/src/fx/fx.dhgr.snowflake.a +++ b/src/fx/fx.dhgr.snowflake.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SNOWFLAKE",plain +!to "build/FX.INDEXED/DHGR.SNOWFLAKE",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.snowflake.in.a b/src/fx/fx.dhgr.snowflake.in.a index 893edb8..868b690 100644 --- a/src/fx/fx.dhgr.snowflake.in.a +++ b/src/fx/fx.dhgr.snowflake.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SNOWFL.IN",plain +!to "build/FX.INDEXED/DHGR.SNOWFL.IN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.snowflake.ripple.a b/src/fx/fx.dhgr.snowflake.ripple.a index 3b8b2de..90f3bbb 100644 --- a/src/fx/fx.dhgr.snowflake.ripple.a +++ b/src/fx/fx.dhgr.snowflake.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SNOWFL.RIP",plain +!to "build/FX.INDEXED/DHGR.SNOWFL.RIP",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.soft.diagonal.a b/src/fx/fx.dhgr.soft.diagonal.a index b6d81c5..5799927 100644 --- a/src/fx/fx.dhgr.soft.diagonal.a +++ b/src/fx/fx.dhgr.soft.diagonal.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am ; !cpu 6502 -!to "build/FX/DHGR.SOFT.DIAG",plain +!to "build/FX.INDEXED/DHGR.SOFT.DIAG",plain *=$6000 src = $F0 diff --git a/src/fx/fx.dhgr.soft.iris.a b/src/fx/fx.dhgr.soft.iris.a index de20e4f..8b2eca0 100644 --- a/src/fx/fx.dhgr.soft.iris.a +++ b/src/fx/fx.dhgr.soft.iris.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SOFT.IRIS",plain +!to "build/FX.INDEXED/DHGR.SOFT.IRIS",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.soft.iris.in.a b/src/fx/fx.dhgr.soft.iris.in.a index 49bc1f7..4df4e31 100644 --- a/src/fx/fx.dhgr.soft.iris.in.a +++ b/src/fx/fx.dhgr.soft.iris.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SOFTIRISIN",plain +!to "build/FX.INDEXED/DHGR.SOFTIRISIN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.star.a b/src/fx/fx.dhgr.star.a index a791058..e9523d9 100644 --- a/src/fx/fx.dhgr.star.a +++ b/src/fx/fx.dhgr.star.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.STAR",plain +!to "build/FX.INDEXED/DHGR.STAR",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.star.in.a b/src/fx/fx.dhgr.star.in.a index 510abd1..d8c2574 100644 --- a/src/fx/fx.dhgr.star.in.a +++ b/src/fx/fx.dhgr.star.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.STAR.IN",plain +!to "build/FX.INDEXED/DHGR.STAR.IN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.star.ripple.a b/src/fx/fx.dhgr.star.ripple.a index c45cd0e..2e48b40 100644 --- a/src/fx/fx.dhgr.star.ripple.a +++ b/src/fx/fx.dhgr.star.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.STAR.RIP",plain +!to "build/FX.INDEXED/DHGR.STAR.RIP",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.swirl.a b/src/fx/fx.dhgr.swirl.a index d2f68bc..c7a270a 100644 --- a/src/fx/fx.dhgr.swirl.a +++ b/src/fx/fx.dhgr.swirl.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.SWIRL",plain +!to "build/FX.INDEXED/DHGR.SWIRL",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.1bit.a" diff --git a/src/fx/fx.dhgr.wavy.iris.a b/src/fx/fx.dhgr.wavy.iris.a index 9356a39..1740b0d 100644 --- a/src/fx/fx.dhgr.wavy.iris.a +++ b/src/fx/fx.dhgr.wavy.iris.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.WAVY.IRIS",plain +!to "build/FX.INDEXED/DHGR.WAVY.IRIS",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.wavy.iris.bloom.a b/src/fx/fx.dhgr.wavy.iris.bloom.a index 1c312e1..b732dc9 100644 --- a/src/fx/fx.dhgr.wavy.iris.bloom.a +++ b/src/fx/fx.dhgr.wavy.iris.bloom.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BLOOM",plain +!to "build/FX.INDEXED/DHGR.BLOOM",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.wavy.iris.bloom.in.a b/src/fx/fx.dhgr.wavy.iris.bloom.in.a index 6da6cf2..f29cbaf 100644 --- a/src/fx/fx.dhgr.wavy.iris.bloom.in.a +++ b/src/fx/fx.dhgr.wavy.iris.bloom.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BLOOM.IN",plain +!to "build/FX.INDEXED/DHGR.BLOOM.IN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.wavy.iris.in.a b/src/fx/fx.dhgr.wavy.iris.in.a index c20e1f9..1cbefb8 100644 --- a/src/fx/fx.dhgr.wavy.iris.in.a +++ b/src/fx/fx.dhgr.wavy.iris.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.WAVY.IN",plain +!to "build/FX.INDEXED/DHGR.WAVY.IN",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.wavy.ripple.a b/src/fx/fx.dhgr.wavy.ripple.a index a0ba687..9769d8f 100644 --- a/src/fx/fx.dhgr.wavy.ripple.a +++ b/src/fx/fx.dhgr.wavy.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.WAVY.RIP",plain +!to "build/FX.INDEXED/DHGR.WAVY.RIP",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.dhgr.wavy.ripple.bloom.a b/src/fx/fx.dhgr.wavy.ripple.bloom.a index 729e08a..c6476e8 100644 --- a/src/fx/fx.dhgr.wavy.ripple.bloom.a +++ b/src/fx/fx.dhgr.wavy.ripple.bloom.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/DHGR.BLOOM.RIP",plain +!to "build/FX.INDEXED/DHGR.BLOOM.RIP",plain *=$6000 !source "src/fx/fx.dhgr.precomputed.2bit.a" diff --git a/src/fx/fx.gr.fizzle.a b/src/fx/fx.gr.fizzle.a index 53e30a0..6a51c34 100644 --- a/src/fx/fx.gr.fizzle.a +++ b/src/fx/fx.gr.fizzle.a @@ -1,86 +1,57 @@ ;license:MIT -;(c) 2019 by qkumba +;(c) 2017-2021 by qkumba/4am/John Brooks !cpu 6502 -!to "build/FX/GR.FIZZLE",plain -*=$6400 +!to "build/GR.FIZZLE",plain +*=$6000 - ;init RNG + !source "src/fx/macros.a" - ldx #1 - stx @rnd1+1 - dex - stx @rnd2+1 + +OVERCOPY_TO_0 start, end + ;$FF clobbered + ;X=0 + ;Y=0 + jmp loop - ;iterate - -@loop - ldy @rnd1+1 - ldx @rnd2+1 - lsr @rnd2+1 - ror @rnd1+1 +start +!pseudopc 0 { + ;X=0 + ;Y=0 +loop txa +loop1 eor #$05 ; LFSR form 0x0500 with period 2047 +wait inx + bpl wait + tax +loop2 txa + and #$03 + ora #$04 + sta 127 then we're done +ROW_X_TO_BASE_ADDRESSES +ROW_X_TO_MIRROR_ADDRESSES diff --git a/src/fx/fx.hgr.precomputed.2bit.a b/src/fx/fx.hgr.precomputed.2bit.a index 89fa891..e097002 100644 --- a/src/fx/fx.hgr.precomputed.2bit.a +++ b/src/fx/fx.hgr.precomputed.2bit.a @@ -265,11 +265,7 @@ zerotbl !byte $f0, $f2, $ca, $d2, $d8, $e0, $e2, $e6, $ea, $ee +BUILD_HGR_LOOKUP_TABLES hgrlo, hgr1hi +BUILD_MIRROR_COLS mirror_cols +BUILD_SPARSE_BITMASKS_2BIT copymasks, mirror_copymasks - ldx #(end-start-1) ; copy InputLoop code to zero page -- lda start, x - sta $0, x - dex - bpl - + +COPY_TO_0 start, end jmp InputLoop start !pseudopc 0 { @@ -277,7 +273,7 @@ Exit2Bit rts InputLoop ldy #0 input=*+1 - ldx .coords, y ; first value: HGR row + 1 + ldx .coords ; first value: HGR row + 1 beq Exit2Bit ; if 0 then we're done +ROW_X_TO_2BIT_BASE_ADDRESSES diff --git a/src/fx/fx.hgr.precomputed.3bit.a b/src/fx/fx.hgr.precomputed.3bit.a index 9082695..bb42a9c 100644 --- a/src/fx/fx.hgr.precomputed.3bit.a +++ b/src/fx/fx.hgr.precomputed.3bit.a @@ -228,11 +228,7 @@ ripplezp +BUILD_3BIT_HGR_LOOKUP_TABLES +BUILD_EXTRA_COLS +BUILD_SPARSE_BITMASKS_3BIT - ldx #(end-start-1) ; copy InputLoop code to zero page -- lda start, x - sta $0, x - dex - bpl - + +COPY_TO_0 start, end jmp InputLoop start !pseudopc 0 { @@ -240,7 +236,7 @@ Exit3Bit rts InputLoop ldy #0 input=*+1 - lda .coords, y + lda .coords bmi Exit3Bit ; if high bit is 1 then we're done cmp #$40 php diff --git a/src/fx/fx.hgr.r.by.2.a b/src/fx/fx.hgr.r.by.2.a index a53e4d8..ee0c265 100644 --- a/src/fx/fx.hgr.r.by.2.a +++ b/src/fx/fx.hgr.r.by.2.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/R.BY.2",plain +!to "build/FX.INDEXED/R.BY.2",plain *=$6000 maskindex = $fd diff --git a/src/fx/fx.hgr.r.by.palette.a b/src/fx/fx.hgr.r.by.palette.a index 6ded648..6fadb55 100644 --- a/src/fx/fx.hgr.r.by.palette.a +++ b/src/fx/fx.hgr.r.by.palette.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/R.BY.PALETTE",plain +!to "build/FX.INDEXED/R.BY.PALETTE",plain *=$6000 maskindex = $fd diff --git a/src/fx/fx.hgr.r.by.pixel.a b/src/fx/fx.hgr.r.by.pixel.a index cbf7204..d0e4fae 100644 --- a/src/fx/fx.hgr.r.by.pixel.a +++ b/src/fx/fx.hgr.r.by.pixel.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/R.BY.PIXEL",plain +!to "build/FX.INDEXED/R.BY.PIXEL",plain *=$6000 maskindex = $fd diff --git a/src/fx/fx.hgr.radbubbles.a b/src/fx/fx.hgr.radbubbles.a index f4fa515..ce41c03 100644 --- a/src/fx/fx.hgr.radbubbles.a +++ b/src/fx/fx.hgr.radbubbles.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/RADBUBBLES",plain +!to "build/FX.INDEXED/RADBUBBLES",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.radial.a b/src/fx/fx.hgr.radial.a index aaaa8b3..4a3a8ff 100644 --- a/src/fx/fx.hgr.radial.a +++ b/src/fx/fx.hgr.radial.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/RADIAL",plain +!to "build/FX.INDEXED/RADIAL",plain *=$6000 mirror_src1 = $E8 ; word diff --git a/src/fx/fx.hgr.radial2.a b/src/fx/fx.hgr.radial2.a index 4dda4c1..fcab75b 100644 --- a/src/fx/fx.hgr.radial2.a +++ b/src/fx/fx.hgr.radial2.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/RADIAL2",plain +!to "build/FX.INDEXED/RADIAL2",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.radial3.a b/src/fx/fx.hgr.radial3.a index 1def09f..98bab27 100644 --- a/src/fx/fx.hgr.radial3.a +++ b/src/fx/fx.hgr.radial3.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/RADIAL3",plain +!to "build/FX.INDEXED/RADIAL3",plain *=$6000 mirror_src1 = $E8 ; word diff --git a/src/fx/fx.hgr.radial4.a b/src/fx/fx.hgr.radial4.a index b614635..20c8f69 100644 --- a/src/fx/fx.hgr.radial4.a +++ b/src/fx/fx.hgr.radial4.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/RADIAL4",plain +!to "build/FX.INDEXED/RADIAL4",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.radial5.a b/src/fx/fx.hgr.radial5.a index 4909ec9..d8264e6 100644 --- a/src/fx/fx.hgr.radial5.a +++ b/src/fx/fx.hgr.radial5.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/RADIAL5",plain +!to "build/FX.INDEXED/RADIAL5",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.redlines.a b/src/fx/fx.hgr.redlines.a index 3e842bc..1767a02 100644 --- a/src/fx/fx.hgr.redlines.a +++ b/src/fx/fx.hgr.redlines.a @@ -2,7 +2,7 @@ ;(c) 2020 by 4am ; !cpu 6502 -!to "build/FX/REDLINES",plain +!to "build/FX.INDEXED/REDLINES",plain *=$6000 row1 = $fe diff --git a/src/fx/fx.hgr.ripple.a b/src/fx/fx.hgr.ripple.a index cba1417..5968631 100644 --- a/src/fx/fx.hgr.ripple.a +++ b/src/fx/fx.hgr.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/RIPPLE",plain +!to "build/FX.INDEXED/RIPPLE",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.slow.star.a b/src/fx/fx.hgr.slow.star.a index a8eb19b..7c8394d 100644 --- a/src/fx/fx.hgr.slow.star.a +++ b/src/fx/fx.hgr.slow.star.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SLOW.STAR",plain +!to "build/FX.INDEXED/SLOW.STAR",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.slow.star.in.a b/src/fx/fx.hgr.slow.star.in.a index 57aa474..add2bd4 100644 --- a/src/fx/fx.hgr.slow.star.in.a +++ b/src/fx/fx.hgr.slow.star.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SLOW.STAR.IN",plain +!to "build/FX.INDEXED/SLOW.STAR.IN",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.slow.star.ripple.a b/src/fx/fx.hgr.slow.star.ripple.a index 4813cbe..aa34013 100644 --- a/src/fx/fx.hgr.slow.star.ripple.a +++ b/src/fx/fx.hgr.slow.star.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SLOW.STAR.RIP",plain +!to "build/FX.INDEXED/SLOW.STAR.RIP",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.snowflake.a b/src/fx/fx.hgr.snowflake.a index d0c5dfc..7d06a9c 100644 --- a/src/fx/fx.hgr.snowflake.a +++ b/src/fx/fx.hgr.snowflake.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SNOWFLAKE",plain +!to "build/FX.INDEXED/SNOWFLAKE",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.snowflake.in.a b/src/fx/fx.hgr.snowflake.in.a index 15a51a7..425eb26 100644 --- a/src/fx/fx.hgr.snowflake.in.a +++ b/src/fx/fx.hgr.snowflake.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SNOWFLAKE.IN",plain +!to "build/FX.INDEXED/SNOWFLAKE.IN",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.snowflake.ripple.a b/src/fx/fx.hgr.snowflake.ripple.a index 97b3d87..3cc75e0 100644 --- a/src/fx/fx.hgr.snowflake.ripple.a +++ b/src/fx/fx.hgr.snowflake.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SNOWFLAKE.RIP",plain +!to "build/FX.INDEXED/SNOWFLAKE.RIP",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.soft.diagonal.a b/src/fx/fx.hgr.soft.diagonal.a index 3471bee..b0c87ef 100644 --- a/src/fx/fx.hgr.soft.diagonal.a +++ b/src/fx/fx.hgr.soft.diagonal.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/SOFT.DIAGONAL",plain +!to "build/FX.INDEXED/SOFT.DIAGONAL",plain *=$6000 y = $fc diff --git a/src/fx/fx.hgr.soft.iris.a b/src/fx/fx.hgr.soft.iris.a index 01dedf9..bd78ef8 100644 --- a/src/fx/fx.hgr.soft.iris.a +++ b/src/fx/fx.hgr.soft.iris.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SOFT.IRIS",plain +!to "build/FX.INDEXED/SOFT.IRIS",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.soft.iris.in.a b/src/fx/fx.hgr.soft.iris.in.a index c6424ee..9c747dc 100644 --- a/src/fx/fx.hgr.soft.iris.in.a +++ b/src/fx/fx.hgr.soft.iris.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SOFT.IRIS.IN",plain +!to "build/FX.INDEXED/SOFT.IRIS.IN",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.soft.l.a b/src/fx/fx.hgr.soft.l.a index 8928a5a..7d3c06f 100644 --- a/src/fx/fx.hgr.soft.l.a +++ b/src/fx/fx.hgr.soft.l.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/SOFT.L",plain +!to "build/FX.INDEXED/SOFT.L",plain *=$6000 y = $fc diff --git a/src/fx/fx.hgr.soft.r.a b/src/fx/fx.hgr.soft.r.a index 0807982..998b57e 100644 --- a/src/fx/fx.hgr.soft.r.a +++ b/src/fx/fx.hgr.soft.r.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/SOFT.R",plain +!to "build/FX.INDEXED/SOFT.R",plain *=$6000 y = $fc diff --git a/src/fx/fx.hgr.soft.ud.a b/src/fx/fx.hgr.soft.ud.a index 73ec170..b0a0530 100644 --- a/src/fx/fx.hgr.soft.ud.a +++ b/src/fx/fx.hgr.soft.ud.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/SOFT.UD",plain +!to "build/FX.INDEXED/SOFT.UD",plain *=$6000 maskindex = $fc diff --git a/src/fx/fx.hgr.soft.ud.in.a b/src/fx/fx.hgr.soft.ud.in.a index d90cdfc..b478295 100644 --- a/src/fx/fx.hgr.soft.ud.in.a +++ b/src/fx/fx.hgr.soft.ud.in.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/SOFT.UD.IN",plain +!to "build/FX.INDEXED/SOFT.UD.IN",plain *=$6000 maskindex = $fc diff --git a/src/fx/fx.hgr.soft.ud.out.a b/src/fx/fx.hgr.soft.ud.out.a index 75eb4f3..089d963 100644 --- a/src/fx/fx.hgr.soft.ud.out.a +++ b/src/fx/fx.hgr.soft.ud.out.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/SOFT.UD.OUT",plain +!to "build/FX.INDEXED/SOFT.UD.OUT",plain *=$6000 maskindex = $fc diff --git a/src/fx/fx.hgr.spiral.a b/src/fx/fx.hgr.spiral.a index 87e7b1d..dec91fd 100644 --- a/src/fx/fx.hgr.spiral.a +++ b/src/fx/fx.hgr.spiral.a @@ -2,7 +2,7 @@ ;(c) 2018 by 4am ; !cpu 6502 -!to "build/FX/SPIRAL",plain +!to "build/FX.INDEXED/SPIRAL",plain *=$6000 !source "src/constants.a" diff --git a/src/fx/fx.hgr.split.ud.intro.a b/src/fx/fx.hgr.split.ud.intro.a index bf66463..611fd44 100644 --- a/src/fx/fx.hgr.split.ud.intro.a +++ b/src/fx/fx.hgr.split.ud.intro.a @@ -2,7 +2,7 @@ ;(c) 2018 by 4am ; !cpu 6502 -!to "build/FX/SPLIT.UD.INTRO",plain +!to "build/FX.INDEXED/SPLIT.UD.INTRO",plain *=$6000 !source "src/fx/macros.a" diff --git a/src/fx/fx.hgr.stagger.lr.a b/src/fx/fx.hgr.stagger.lr.a index 1a1e303..cc44f03 100644 --- a/src/fx/fx.hgr.stagger.lr.a +++ b/src/fx/fx.hgr.stagger.lr.a @@ -2,7 +2,7 @@ ;(c) 2018 by 4am ; !cpu 6502 -!to "build/FX/STAGGER.LR",plain +!to "build/FX.INDEXED/STAGGER.LR",plain *=$6000 row = $fd diff --git a/src/fx/fx.hgr.stagger.lr.white.a b/src/fx/fx.hgr.stagger.lr.white.a index e4a1b78..42686bb 100644 --- a/src/fx/fx.hgr.stagger.lr.white.a +++ b/src/fx/fx.hgr.stagger.lr.white.a @@ -2,7 +2,7 @@ ;(c) 2018 by 4am ; !cpu 6502 -!to "build/FX/STAGGERWHITE.LR",plain +!to "build/FX.INDEXED/STAGGERWHITE.LR",plain *=$6000 row = $fd diff --git a/src/fx/fx.hgr.stagger.ud.a b/src/fx/fx.hgr.stagger.ud.a index 17e3e07..c10cc83 100644 --- a/src/fx/fx.hgr.stagger.ud.a +++ b/src/fx/fx.hgr.stagger.ud.a @@ -1,5 +1,5 @@ !cpu 6502 -!to "build/FX/STAGGER.UD",plain +!to "build/FX.INDEXED/STAGGER.UD",plain *=$6000 row1 = $fe diff --git a/src/fx/fx.hgr.stagger.ud.white.a b/src/fx/fx.hgr.stagger.ud.white.a index 642fc08..16dc523 100644 --- a/src/fx/fx.hgr.stagger.ud.white.a +++ b/src/fx/fx.hgr.stagger.ud.white.a @@ -2,7 +2,7 @@ ;(c) 2018 by 4am ; !cpu 6502 -!to "build/FX/STAGGERWHITE.UD",plain +!to "build/FX.INDEXED/STAGGERWHITE.UD",plain *=$6000 row1 = $fe diff --git a/src/fx/fx.hgr.star.a b/src/fx/fx.hgr.star.a index 7969607..4a17ee3 100644 --- a/src/fx/fx.hgr.star.a +++ b/src/fx/fx.hgr.star.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/STAR",plain +!to "build/FX.INDEXED/STAR",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.star.bloom.a b/src/fx/fx.hgr.star.bloom.a index 7c6cbdd..0eefc7c 100644 --- a/src/fx/fx.hgr.star.bloom.a +++ b/src/fx/fx.hgr.star.bloom.a @@ -2,7 +2,7 @@ ;(c) 2019 by 4am ; !cpu 6502 -!to "build/FX/STAR.BLOOM",plain +!to "build/FX.INDEXED/STAR.BLOOM",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.star.in.a b/src/fx/fx.hgr.star.in.a index e0eeab1..d0bb60e 100644 --- a/src/fx/fx.hgr.star.in.a +++ b/src/fx/fx.hgr.star.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/STAR.IN",plain +!to "build/FX.INDEXED/STAR.IN",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.star.ripple.a b/src/fx/fx.hgr.star.ripple.a index 2ac2b82..d4410a7 100644 --- a/src/fx/fx.hgr.star.ripple.a +++ b/src/fx/fx.hgr.star.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/STAR.RIPPLE",plain +!to "build/FX.INDEXED/STAR.RIPPLE",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.swirl.a b/src/fx/fx.hgr.swirl.a index 0cf9d92..49410fe 100644 --- a/src/fx/fx.hgr.swirl.a +++ b/src/fx/fx.hgr.swirl.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/SWIRL",plain +!to "build/FX.INDEXED/SWIRL",plain *=$6000 !source "src/fx/fx.hgr.precomputed.1bit.a" diff --git a/src/fx/fx.hgr.tri.fizzle.a b/src/fx/fx.hgr.tri.fizzle.a index f831211..adf4628 100644 --- a/src/fx/fx.hgr.tri.fizzle.a +++ b/src/fx/fx.hgr.tri.fizzle.a @@ -2,7 +2,7 @@ ;(c) 2018 by 4am ; !cpu 6502 -!to "build/FX/TRI.FIZZLE",plain +!to "build/FX.INDEXED/TRI.FIZZLE",plain *=$6000 phase = $FC ; byte, $80 or $00 diff --git a/src/fx/fx.hgr.vertical.blinds.a b/src/fx/fx.hgr.vertical.blinds.a index cb5c9de..b2063d2 100755 --- a/src/fx/fx.hgr.vertical.blinds.a +++ b/src/fx/fx.hgr.vertical.blinds.a @@ -2,7 +2,7 @@ ;(c) 2019 by qkumba ; !cpu 6502 -!to "build/FX/VERTICAL.BLINDS",plain +!to "build/FX.INDEXED/VERTICAL.BLINDS",plain *=$6000 ldx #0 diff --git a/src/fx/fx.hgr.wavy.iris.a b/src/fx/fx.hgr.wavy.iris.a index 3abbbe1..8bcaed9 100644 --- a/src/fx/fx.hgr.wavy.iris.a +++ b/src/fx/fx.hgr.wavy.iris.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/WAVY.IRIS",plain +!to "build/FX.INDEXED/WAVY.IRIS",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.wavy.iris.bloom.a b/src/fx/fx.hgr.wavy.iris.bloom.a index 76d7a7a..1a1fb1a 100644 --- a/src/fx/fx.hgr.wavy.iris.bloom.a +++ b/src/fx/fx.hgr.wavy.iris.bloom.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/W.IRIS.BLOOM",plain +!to "build/FX.INDEXED/W.IRIS.BLOOM",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.wavy.iris.bloom.in.a b/src/fx/fx.hgr.wavy.iris.bloom.in.a index 143bd95..5d8d976 100644 --- a/src/fx/fx.hgr.wavy.iris.bloom.in.a +++ b/src/fx/fx.hgr.wavy.iris.bloom.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/W.IRIS.BLOOM.IN",plain +!to "build/FX.INDEXED/W.IRIS.BLOOM.IN",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.wavy.iris.in.a b/src/fx/fx.hgr.wavy.iris.in.a index e0c9faa..80752ef 100644 --- a/src/fx/fx.hgr.wavy.iris.in.a +++ b/src/fx/fx.hgr.wavy.iris.in.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/WAVY.IRIS.IN",plain +!to "build/FX.INDEXED/WAVY.IRIS.IN",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.wavy.ripple.a b/src/fx/fx.hgr.wavy.ripple.a index 3a10272..67640d3 100644 --- a/src/fx/fx.hgr.wavy.ripple.a +++ b/src/fx/fx.hgr.wavy.ripple.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/WAVY.RIPPLE",plain +!to "build/FX.INDEXED/WAVY.RIPPLE",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.hgr.wavy.ripple.bloom.a b/src/fx/fx.hgr.wavy.ripple.bloom.a index 31c5cbf..6e58880 100644 --- a/src/fx/fx.hgr.wavy.ripple.bloom.a +++ b/src/fx/fx.hgr.wavy.ripple.bloom.a @@ -2,7 +2,7 @@ ;(c) 2019-2020 by 4am/qkumba ; !cpu 6502 -!to "build/FX/W.RIPPLE.BLOOM",plain +!to "build/FX.INDEXED/W.RIPPLE.BLOOM",plain *=$6000 !source "src/fx/fx.hgr.precomputed.2bit.a" diff --git a/src/fx/fx.shr.2pass.lr.a b/src/fx/fx.shr.2pass.lr.a new file mode 100644 index 0000000..8528d13 --- /dev/null +++ b/src/fx/fx.shr.2pass.lr.a @@ -0,0 +1,51 @@ +;license:MIT +;(c) 2021 by 4am + +!cpu 6502 +!to "build/FX.INDEXED/SHR.TWOPASS.LR",plain +*=$A000 + +shrlo = $301 ; $C8 bytes, indexed as shrlo-1,x +shrhi = $38 ; $C8 bytes, indexed as shrhi-1,x + + !source "src/fx/macros.a" + !source "src/fx/fx.shr.common.a" + + +COPY_TO_0 start, end + +BUILD_SHR_LOOKUP_TABLES shrlo, shrhi + ;X=0 + +COPY_SCB_AND_PALETTES + ;WRITEAUXMEM active + + jmp loop1 + +start +!pseudopc 0 { +loop1 ldy #0 +loop2 ldx #1 +loop3 lda shrlo, x + sta $38 { + !error "code is too large: ends at ", end-start +} diff --git a/src/fx/fx.shr.80boxes.a b/src/fx/fx.shr.80boxes.a new file mode 100644 index 0000000..311505b --- /dev/null +++ b/src/fx/fx.shr.80boxes.a @@ -0,0 +1,28 @@ +;license:MIT +;(c) 2021 by 4am & qkumba +; + +!cpu 6502 +!to "build/FX.INDEXED/SHR.80BOXES",plain +*=$A000 + + !source "src/fx/fx.shr.80boxes.common.a" + + !byte $F9,$F8,$F7,$F6,$F5,$F4,$F3,$F2,$F1,$F0 + !byte $FA,$F9,$F8,$F7,$F6,$F5,$F4,$F3,$F2,$F1 + !byte $FB,$FA,$F9,$F8,$F7,$F6,$F5,$F4,$F3,$F2 + !byte $FC,$FB,$FA,$F9,$F8,$F7,$F6,$F5,$F4,$F3 + !byte $FD,$FC,$FB,$FA,$F9,$F8,$F7,$F6,$F5,$F4 + !byte $FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7,$F6,$F5 + !byte $FF,$FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7,$F6 + !byte $00,$FF,$FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7 + +StageInitialIndexes + !byte 1 + !byte 2 + !byte 3 + !byte 4 + !byte 5 + !byte 6 + !byte 7 +EndStageInitialIndexes diff --git a/src/fx/fx.shr.80boxes.arrow.a b/src/fx/fx.shr.80boxes.arrow.a new file mode 100644 index 0000000..242b155 --- /dev/null +++ b/src/fx/fx.shr.80boxes.arrow.a @@ -0,0 +1,28 @@ +;license:MIT +;(c) 2021 by 4am +; + +!cpu 6502 +!to "build/FX.INDEXED/SHR.80.ARROW",plain +*=$A000 + + !source "src/fx/fx.shr.80boxes.common.a" + + !byte $FA,$F8,$F6,$F4,$F2,$F0,$EE,$EC,$EA,$E8 + !byte $FC,$FA,$F8,$F6,$F4,$F2,$F0,$EE,$EC,$EA + !byte $FE,$FC,$FA,$F8,$F6,$F4,$F2,$F0,$EE,$EC + !byte $00,$FE,$FC,$FA,$F8,$F6,$F4,$F2,$F0,$EE + !byte $FF,$FD,$FB,$F9,$F7,$F5,$F3,$F1,$EF,$ED + !byte $FD,$FB,$F9,$F7,$F5,$F3,$F1,$EF,$ED,$EB + !byte $FB,$F9,$F7,$F5,$F3,$F1,$EF,$ED,$EB,$E9 + !byte $F9,$F7,$F5,$F3,$F1,$EF,$ED,$EB,$E9,$E7 + +StageInitialIndexes + !byte 1 + !byte 2 + !byte 3 + !byte 4 + !byte 5 + !byte 6 + !byte 7 +EndStageInitialIndexes diff --git a/src/fx/fx.shr.80boxes.common.a b/src/fx/fx.shr.80boxes.common.a new file mode 100644 index 0000000..f307638 --- /dev/null +++ b/src/fx/fx.shr.80boxes.common.a @@ -0,0 +1,229 @@ +;license:MIT +;(c) 2021 by 4am & qkumba +; +; The SHR screen in 320x200 mode is separated into 80 boxes. +; Boxes are laid out in a grid, left-to-right, top-down: +; +; 0 1 2 3 4 5 6 7 8 9 +; 10 11 12 13 14 15 16 17 18 19 +; 20 21 22 23 24 25 26 27 28 29 +; 30 31 32 33 34 35 36 37 38 39 +; 40 41 42 43 44 45 46 47 48 49 +; 50 51 52 53 54 55 56 57 58 59 +; 60 61 62 63 64 65 66 67 68 69 +; 70 71 72 73 74 75 76 77 78 79 +; +; Each box is 32x25 pixels, so each row of each box is 16 consecutive +; bytes in memory (2 pixels per byte) once you calculate the SHR base +; address for that row. +; +; |BoxInitialStages| defines the initial grid of stages for each box. +; Each stage is used as an index into the |StageInitialIndexes| array +; to find the drawing routine for that stage (if any). +; Each box's stage is incremented after each iteration through the main loop. +; When the main loop iterates through all 80 boxes without drawing anything, +; the program exits. +; +; There are 7 copy routines that copy certain pixels from the source +; image in mainmem to the destination image in auxmem. Technically +; these all have the same entry point, with X = 1..7 on entry. +; We always copy pixels in horizontal pairs, meaning we can just copy +; bytes without having to worry about masking high and low nibbles. +; +; row| pixels +; ---+.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- +; 00 |77777777777777777777777777777777 +; 01 |77777777777777777777777777777777 +; 02 |77666666666666666666666666666677 +; 03 |77666666666666666666666666666677 +; 04 |77665555555555555555555555556677 +; 05 |77665555555555555555555555556677 +; 06 |77665544444444444444444444556677 +; 07 |77665544444444444444444444556677 +; 08 |77665544333333333333333344556677 +; 09 |77665544333333333333333344556677 +; 10 |77665544332222222222223344556677 +; 11 |77665544332222222222223344556677 +; 12 |77665544332211111111223344556677 +; 13 |77665544332222222222223344556677 +; 14 |77665544332222222222223344556677 +; 15 |77665544333333333333333344556677 +; 16 |77665544333333333333333344556677 +; 17 |77665544444444444444444444556677 +; 18 |77665544444444444444444444556677 +; 19 |77665555555555555555555555556677 +; 20 |77665555555555555555555555556677 +; 21 |77666666666666666666666666666677 +; 22 |77666666666666666666666666666677 +; 23 |77777777777777777777777777777777 +; 24 |77777777777777777777777777777777 +; + +!macro SET_ROW_X { +; out: Z=0 because shrhi is never 0 + lda shrlo, x + sta $FF) { + !error "Code is too big to fit on zero page! ", *-start +} + +BoxInitialStages diff --git a/src/fx/fx.shr.80boxes.down.a b/src/fx/fx.shr.80boxes.down.a new file mode 100644 index 0000000..1b44355 --- /dev/null +++ b/src/fx/fx.shr.80boxes.down.a @@ -0,0 +1,28 @@ +;license:MIT +;(c) 2021 by 4am +; + +!cpu 6502 +!to "build/FX.INDEXED/SHR.80.DOWN",plain +*=$A000 + + !source "src/fx/fx.shr.80boxes.common.a" + + !byte $00,$FF,$00,$FF,$00,$FF,$00,$FF,$00,$FF + !byte $FE,$FD,$FE,$FD,$FE,$FD,$FE,$FD,$FE,$FD + !byte $FC,$FB,$FC,$FB,$FC,$FB,$FC,$FB,$FC,$FB + !byte $FA,$F9,$FA,$F9,$FA,$F9,$FA,$F9,$FA,$F9 + !byte $F8,$F7,$F8,$F7,$F8,$F7,$F8,$F7,$F8,$F7 + !byte $F6,$F5,$F6,$F5,$F6,$F5,$F6,$F5,$F6,$F5 + !byte $F4,$F3,$F4,$F3,$F4,$F3,$F4,$F3,$F4,$F3 + !byte $F2,$F1,$F2,$F1,$F2,$F1,$F2,$F1,$F2,$F1 + +StageInitialIndexes + !byte 7,0,0 + !byte 6,0,0 + !byte 5,0,0 + !byte 4,0,0 + !byte 3,0,0 + !byte 2,0,0 + !byte 1 +EndStageInitialIndexes diff --git a/src/fx/fx.shr.80boxes.sidetoside.a b/src/fx/fx.shr.80boxes.sidetoside.a new file mode 100644 index 0000000..96b5877 --- /dev/null +++ b/src/fx/fx.shr.80boxes.sidetoside.a @@ -0,0 +1,28 @@ +;license:MIT +;(c) 2021 by 4am & qkumba +; + +!cpu 6502 +!to "build/FX.INDEXED/SHR.80.SIDE2",plain +*=$A000 + + !source "src/fx/fx.shr.80boxes.common.a" + + !byte $00,$FC,$F8,$F4,$F0,$EC,$E8,$E4,$E0,$DC + !byte $DC,$E0,$E4,$E8,$EC,$F0,$F4,$F8,$FC,$00 + !byte $00,$FC,$F8,$F4,$F0,$EC,$E8,$E4,$E0,$DC + !byte $DC,$E0,$E4,$E8,$EC,$F0,$F4,$F8,$FC,$00 + !byte $00,$FC,$F8,$F4,$F0,$EC,$E8,$E4,$E0,$DC + !byte $DC,$E0,$E4,$E8,$EC,$F0,$F4,$F8,$FC,$00 + !byte $00,$FC,$F8,$F4,$F0,$EC,$E8,$E4,$E0,$DC + !byte $DC,$E0,$E4,$E8,$EC,$F0,$F4,$F8,$FC,$00 + +StageInitialIndexes + !byte 1,1 + !byte 2,1 + !byte 3,1 + !byte 4,1 + !byte 5,1 + !byte 6,1 + !byte 7,1 +EndStageInitialIndexes diff --git a/src/fx/fx.shr.80boxes.snake.a b/src/fx/fx.shr.80boxes.snake.a new file mode 100644 index 0000000..80b1233 --- /dev/null +++ b/src/fx/fx.shr.80boxes.snake.a @@ -0,0 +1,28 @@ +;license:MIT +;(c) 2021 by 4am +; + +!cpu 6502 +!to "build/FX.INDEXED/SHR.80.SNAKE",plain +*=$A000 + + !source "src/fx/fx.shr.80boxes.common.a" + + !byte $00,$FF,$FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7 + !byte $ED,$EE,$EF,$F0,$F1,$F2,$F3,$F4,$F5,$F6 + !byte $EC,$EB,$EA,$E9,$E8,$E7,$E6,$E5,$E4,$E3 + !byte $D9,$DA,$DB,$DC,$DD,$DE,$DF,$E0,$E1,$E2 + !byte $D8,$D7,$D6,$D5,$D4,$D3,$D2,$D1,$D0,$CF + !byte $C5,$C6,$C7,$C8,$C9,$CA,$CB,$CC,$CD,$CE + !byte $C4,$C3,$C2,$C1,$C0,$BF,$BE,$BD,$BC,$BB + !byte $B1,$B2,$B3,$B4,$B5,$B6,$B7,$B8,$B9,$BA + +StageInitialIndexes + !byte 7,7,7 + !byte 6,6,6 + !byte 5,5,5 + !byte 4,4,4 + !byte 3,3,3 + !byte 2,2,2 + !byte 1,1,1 +EndStageInitialIndexes diff --git a/src/fx/fx.shr.80boxes.spiral.a b/src/fx/fx.shr.80boxes.spiral.a new file mode 100644 index 0000000..b16f97d --- /dev/null +++ b/src/fx/fx.shr.80boxes.spiral.a @@ -0,0 +1,28 @@ +;license:MIT +;(c) 2021 by 4am +; + +!cpu 6502 +!to "build/FX.INDEXED/SHR.80.SPIRAL",plain +*=$A000 + + !source "src/fx/fx.shr.80boxes.common.a" + + !byte $E9,$E8,$E7,$E6,$E5,$E4,$E3,$E2,$E1,$00 + !byte $EA,$CF,$CE,$CD,$CC,$CB,$CA,$C9,$E0,$FF + !byte $EB,$D0,$BD,$BC,$BB,$BA,$B9,$C8,$DF,$FE + !byte $EC,$D1,$BE,$B3,$B2,$B1,$B8,$C7,$DE,$FD + !byte $ED,$D2,$BF,$B4,$B5,$B6,$B7,$C6,$DD,$FC + !byte $EE,$D3,$C0,$C1,$C2,$C3,$C4,$C5,$DC,$FB + !byte $EF,$D4,$D5,$D6,$D7,$D8,$D9,$DA,$DB,$FA + !byte $F0,$F1,$F2,$F3,$F4,$F5,$F6,$F7,$F8,$F9 + +StageInitialIndexes + !byte 7,7,0 + !byte 6,6,0 + !byte 5,5,0 + !byte 4,4,0 + !byte 3,3,0 + !byte 2,2,0 + !byte 1,1 +EndStageInitialIndexes diff --git a/src/fx/fx.shr.common.a b/src/fx/fx.shr.common.a new file mode 100644 index 0000000..3aa0799 --- /dev/null +++ b/src/fx/fx.shr.common.a @@ -0,0 +1,231 @@ +;license:MIT +;(c) 2021 by 4am + +!macro BUILD_SHR_LOOKUP_TABLES .lo, .hi { +; in: none +; out: X=0 +; Z=1 + ldx #$C8 + lda #$60 + ldy #$9C +- sta .lo-1, x +!if .hi < $100 { + sty .hi-1, x +} else { + pha + tya + sta .hi-1, x + pla +} + sec + sbc #$A0 + bcs + + dey ++ dex + bne - +} + +!macro BUILD_SHR_REVERSE_LOOKUP_TABLES .lo, .hi { +; in: none +; out: X=0 +; Z=1 + ldx #$C8 + lda #$00 + ldy #$20 +- sta .lo-1, x +!if .hi < $100 { + sty .hi-1, x +} else { + pha + tya + sta .hi-1, x + pla +} + clc + adc #$A0 + bcc + + iny ++ dex + bne - +} + +!macro COPY_SCB_AND_PALETTES { +; in: X=0 /!\ +; out: X=0 +; Z=1 +; WRITEAUXMEM active + sta $C005 +- lda $9D00, x + sta $9D00, x + lda $9E00, x + sta $9E00, x + lda $9F00, x + sta $9F00, x + inx + bne - +} + +!macro BUILD_SHR_MIRROR_ROWS_AND_COLS .mirror_rows, .mirror_cols { +; out: X=0 +; Z=1 + ldx #$C7 + ldy #$00 +- tya + sta .mirror_cols-$28, x + sta .mirror_rows-1, x + iny + dex + bne - +} + +!macro SHR_COPY_TO_STAGE_2 { +; in: X=0 /!\ +; out: X=0 +; Z=1 +; WRITEMAINMEM active + +WRITE_MAIN +- lda $A000, x + sta $9D00, x + lda $A100, x + sta $9E00, x + inx + bne - +} + +!macro SHR_RESTORE_FROM_STAGE_2 { +; out: X=0 +; Z=1 + ldx #$00 +- lda $9D00, x ; copy main code back to $A000 + sta $A000, x ; so it can be called again if necessary + lda $9E00, x + sta $A100, x + inx + bne - +} + +!macro LOAD_SHR_COORDINATES_AT .coords, .filename, .scratch { +; out: WRITEMAINMEM active +; LC RAM2 active and read/write + ldx .filename ; LOAD_FILE_AT macro destroys pathname +- lda .filename, x ; so we need to make a copy + sta .scratch, x + dex + bpl - + + +READ_RAM2_WRITE_RAM2 + +LOAD_FILE_AT .scratch, .coords +} + +!macro SHR_STAGE_1 .shrlo, .shrhi, .mirror_rows, .mirror_cols { + +BUILD_SHR_MIRROR_ROWS_AND_COLS .mirror_rows, .mirror_cols + ;X=0 + +BUILD_SHR_LOOKUP_TABLES .shrlo, .shrhi + ;X=0 + +COPY_SCB_AND_PALETTES + ;X=0 + ;WRITEAUXMEM active + +SHR_COPY_TO_STAGE_2 +} + +!macro SHR_STAGE_2 .startzp, .endzp { + +COPY_TO_0 .startzp, .endzp + + +WRITE_AUX + jsr $0 + +WRITE_MAIN + + +SHR_RESTORE_FROM_STAGE_2 + +READ_RAM1_WRITE_RAM1 +} + +!macro SHR_STAGE_3 .coords, .shrlo, .shrhi, .mirror_rows, .mirror_cols { +input ldx .coords ; first value: SHR row (only 0..99 will be in input array) + bmi exit ; if > 127 then we're done + ldy #1 + lda (.coords + sta $f1 + lda #<(.coords + .length - 2) + sta $f2 + lda #>(.coords + .length - 2) + sta $f3 + clc + !byte $24 +- sec +-- lda ($f0), y + pha + lda ($f2), y + sta ($f0), y + pla + sta ($f2), y + iny + bcc - + ldy #0 + !byte $24 +- clc + inc $f0 + bne + + inc $f1 ++ lda $f1 + eor #>(.coords + .length/2) + bne + + lda $f0 + eor #<(.coords + .length/2) + beq ++ ++ lda $f2 + bne + + dec $f3 ++ dec $f2 + bcs - + bcc -- ; always +++ +} diff --git a/src/fx/fx.shr.diagonal.a b/src/fx/fx.shr.diagonal.a new file mode 100644 index 0000000..52b7998 --- /dev/null +++ b/src/fx/fx.shr.diagonal.a @@ -0,0 +1,63 @@ +;license:MIT +;(c) 2021 by 4am + +!cpu 6502 +!to "build/FX.INDEXED/SHR.DIAGONAL",plain +*=$A000 + +shrlo = $301 ; $C8 bytes, indexed as shrlo-1,x +shrhi = $201 ; $C8 bytes, indexed as shrhi-1,x + + !source "src/fx/macros.a" + !source "src/fx/fx.shr.common.a" + + +COPY_TO_0 start, end + +BUILD_SHR_LOOKUP_TABLES shrlo, shrhi + ;X=0 + +COPY_SCB_AND_PALETTES + ;WRITEAUXMEM active + + jmp colloop + +start +!pseudopc 0 { +colloop + ldx #$C8 +startcollo=*+1 + ldy #$9F ; SMC +startcolhi=*+1 + lda #$00 + sta palettes + sta src+1 + ldx #$0F ; palette counter ($0F -> $00, not used as index) +rb_palette_loop + ldy #$00 ; byte offset within palette (00 -> 1F, used as index) +rb_color_loop + lda #$00 + sta fracv + sta fracv_hi + sta color + lda src + sta dst + lda src+1 + sec + sbc #>(palettes-$4000) + sta dst+1 + lda (src), y ; get final Red or Blue value for this color in this palette + asl ; Red or Blue value is bits 0-3, shift them into bits 4-7 + asl + asl + asl + sta incv +rb_step_loop + lda fracv + clc + adc incv + sta fracv + bcc + + lda fracv_hi + eor #$01 + sta fracv_hi + bne + + inc color ++ lda color + sta (dst), y + inc dst+1 + inc dst+1 + bpl rb_step_loop + iny + cpy #$20 + bcc rb_color_loop + lda src + clc + adc #$20 + sta src + bcc + + inc src+1 ++ dex + bpl rb_palette_loop + + lda #>palettes + sta src+1 + ldx #$0F ; palette counter ($0F -> $00, not used as index) +g_palette_loop + ldy #$00 ; byte offset within palette (00 -> 1E by 2, used as index) +g_color_loop + lda #$00 + sta fracv + sta fracv_hi + sta color + lda src + sta dst + lda src+1 + sec + sbc #>(palettes-$4000) + sta dst+1 + lda (src), y ; get final Green value for this color in this palette + and #$F0 ; Green value is bits 4-7, mask out other bits + sta incv +g_step_loop + lda fracv + clc + adc incv + sta fracv + bcc + + lda fracv_hi + eor #$01 + sta fracv_hi + bne + + lda color + clc + adc #$10 + sta color ++ lda color + ora (dst), y ; keep existing Blue value in bits 0-3 + sta (dst), y + inc dst+1 + inc dst+1 + bpl g_step_loop + iny + iny ; high nibble of second color byte is always 0 so skip it + cpy #$20 + bcc g_color_loop + lda src + clc + adc #$20 + sta src + bcc + + inc src+1 ++ dex + bpl g_palette_loop + + ldx #$44 + stx copy1+2 + inx + stx copy2+2 + lda #$40 + sta incv + ldx #$1D + ldy #$00 +copyloop jsr WaitForVBL + sta $C005 +copy1 lda $4400, y ; SMC + sta $9E00, y +copy2 lda $4500, y ; SMC + sta $9F00, y + iny + bne copy1 + sta $C004 + inc copy1+2 + inc copy1+2 + inc copy2+2 + inc copy2+2 + lda incv + jsr WaitForKeyWithTimeout + bmi exit + dec incv + dec incv + dex + bpl copyloop +exit jmp UnwaitForVBL + + !source "src/wait.a" diff --git a/src/fx/fx.shr.fizzle.a b/src/fx/fx.shr.fizzle.a index d707a64..dc569d1 100644 --- a/src/fx/fx.shr.fizzle.a +++ b/src/fx/fx.shr.fizzle.a @@ -2,11 +2,13 @@ ;(c) 2019-2020 by qkumba/4am/John Brooks !cpu 6502 -!to "build/FX/SHR.FIZZLE",plain +!to "build/FX.INDEXED/SHR.FIZZLE",plain *=$A000 -addrs=$80 ; [128 bytes] -src=addrs-$20 ; [word] + !source "src/fx/macros.a" + !source "src/fx/fx.shr.common.a" + +addrs=$7F ; [128 bytes] lda #$A0 ; create address lookup table tax @@ -15,22 +17,28 @@ src=addrs-$20 ; [word] sty addrs-$21, x dex bne - - sta $C005 -- lda $9D00, y ; pre-copy SHR SCB and palette - sta $9D00, y - lda $9E00, y - sta $9E00, y - lda $9F00, y - sta $9F00, y - iny - bne - + + +OVERCOPY_TO_0 start, end + ;$FF clobbered + ;X=0 + ;Y=0 + + +COPY_SCB_AND_PALETTES + ;WRITEAUXMEM active + + jmp loop + +start +!pseudopc 0 { + ;X=0 + ;Y=0 loop txa loop1 eor #$60 ; LFSR form 0x6000 with period 32767 tax loop2 lda addrs, x - sta src+1 - lda (src), y - sta (src), y + sta shrhi { + !error "code is too large: ends at ", end-start +} diff --git a/src/fx/fx.shr.lr2.a b/src/fx/fx.shr.lr2.a new file mode 100644 index 0000000..a9a95eb --- /dev/null +++ b/src/fx/fx.shr.lr2.a @@ -0,0 +1,50 @@ +;license:MIT +;(c) 2021 by 4am + +!cpu 6502 +!to "build/FX.INDEXED/SHR.LR2",plain +*=$A000 + +shrlo = $301 ; $C8 bytes, indexed as shrlo-1,x +shrhi = $38 ; $C8 bytes, indexed as shrhi-1,x + + !source "src/fx/macros.a" + !source "src/fx/fx.shr.common.a" + + +COPY_TO_0 start, end + +BUILD_SHR_LOOKUP_TABLES shrlo, shrhi + ;X=0 + +COPY_SCB_AND_PALETTES + ;WRITEAUXMEM active + + jmp loop1 + +start +!pseudopc 0 { +loop1 ldy #1 +loop2 ldx #$C8 +loop3 lda shrlo-1, x + sta $38 { + !error "code is too large: ends at ", end-start +} diff --git a/src/fx/fx.shr.radial.a b/src/fx/fx.shr.radial.a new file mode 100644 index 0000000..f438ee1 --- /dev/null +++ b/src/fx/fx.shr.radial.a @@ -0,0 +1,127 @@ +;license:MIT +;(c) 2021 by 4am +; +!cpu 6502 +!to "build/FX.INDEXED/SHR.RADIAL",plain +*=$A000 + +mirror_rows = $106 ; $C8 bytes +shrlo = $200 ; $C8 bytes +shrhi = $300 ; $C8 bytes +coords = $9F00 ; $1F41 bytes +last_coords = coords+$1F3E +CoordinatesFileCopy = $BE42; $11 bytes +mirror_cols = $BE60 ; $A0 bytes but clobbers $27 previous bytes during construction + + !source "src/fx/macros.a" + !source "src/fx/fx.shr.common.a" + + +SHR_STAGE_1 shrlo, shrhi, mirror_rows, mirror_cols + jmp stage2 + +!pseudopc *-$300 { +stage2 + +LOAD_SHR_COORDINATES_AT coords, CoordinatesFile, CoordinatesFileCopy + ;WRITEMAINMEM active + + lda #$80 + sta coords-2 + + +SHR_STAGE_2 startzp, endzp + rts + +startzp +!pseudopc 0 { + ; bottom-left quadrant (opposite row, original column, reverse input order) +LoopBL ldx last_coords ; SMC + bmi LoopTL + lda mirror_rows, x + tax + ldy #1 + lda (LoopBL+1), y + tay + jsr copy + lda $38 { + !error "code is too large: ends at ", end-start +} diff --git a/src/fx/macros.a b/src/fx/macros.a index ee25618..c60890b 100644 --- a/src/fx/macros.a +++ b/src/fx/macros.a @@ -6,12 +6,14 @@ ; posted on comp.sys.apple2 on 2018-07-11 ; https://groups.google.com/d/msg/comp.sys.apple2/v2HOfHOmeNQ/zD76fJg_BAAJ !macro BUILD_HGR_LOOKUP_TABLES .hgrlo, .hgr1hi { +; preserves Y ldx #0 +BUILD_HGR_LOOKUP_TABLES_X_IS_ALREADY_0 .hgrlo, .hgr1hi } ; use this macro instead if you know X is already 0 on entry, to save 2 bytes !macro BUILD_HGR_LOOKUP_TABLES_X_IS_ALREADY_0 .hgrlo, .hgr1hi { +; preserves Y - txa and #$F8 bpl + @@ -159,5 +161,27 @@ + } +!macro COPY_TO_0 .start, .end { +; out: X=0 +; Z=1 + ldx #(.end-.start) +- lda .start-1, x + sta $FF, x + dex + bne - +} + +!macro OVERCOPY_TO_0 .start, .end { +; over-copy region to $00 +; clobbers $FF +; out: X=0 +; Y=last byte before start (e.g. 0 if the last instruction is JMP $0000) + ldx #(.end-.start+1) +- ldy .start-2, x + sty $FE, x + dex + bne - +} + _FX_MACROS_=* } diff --git a/src/glue.decompress.a b/src/glue.decompress.a index 4f781d3..c9fa018 100644 --- a/src/glue.decompress.a +++ b/src/glue.decompress.a @@ -53,12 +53,11 @@ DecompressHGR pha lda auxreq bne + - jmp LoadFile ; load decompression code to $200 -+ jmp LoadAuxFile ; load decompression code to $200/aux + jmp LoadIndexedFile ; load decompression code to $200 ++ jmp LoadAuxIndexedFile ; load decompression code to $200/aux @loaddecrunch - !word kRootDirectory - !word kDecrunchFile !word $200 + !word kDecrunchRecord ldx auxreq sta READMAINMEM,x ; X = 0 or 1, so this will be READMAINMEM or READAUXMEM sta WRITEMAINMEM,x ; X = 0 or 1, so this will be WRITEMAINMEM or WRITEAUXMEM diff --git a/src/glue.launch.a b/src/glue.launch.a index 825a40b..5df13a2 100644 --- a/src/glue.launch.a +++ b/src/glue.launch.a @@ -4,19 +4,20 @@ ; Functions to launch games and self-running demos ; ; Public functions +; - AnyGameSelected ; - GetGameToLaunch ; - FindGame -; - FindGameInActionSlideshow -; - GetGameDisplayName ; - PlayGame ; - Launch ; ; Public variables: -; - gGameToLaunch - 0-based index into gGamesListStore (word) +; - gGameToLaunch - 0-based index into gSearchStore (word) ; gGameToLaunch !word $FFFF +gLastMegaAttractGame + !word $FFFF ;------------------------------------------------------------------------------ ; AnyGameSelected @@ -30,15 +31,15 @@ gGameToLaunch ;------------------------------------------------------------------------------ AnyGameSelected +LD16 gGameToLaunch - +CMP16 $FFFF - bne ForceGoodResult + +CMP16_NE $FFFF, ForceGoodResult rts ; CMP sets carry when equal ;------------------------------------------------------------------------------ ; GetGameToLaunch ; get filename of game that is currently selected in the UI (if any) ; -; in: gGameToLaunch = index into gGamesListStore (word) or #$FFFF if no game selected +; in: gGameToLaunch = index into gSearchStore (word) or #$FFFF if no game selected +; gSearchStore populated ; out: C clear if a game is selected, and ; A/Y points to game filename ; C set if no game is selected @@ -47,7 +48,7 @@ GetGameToLaunch jsr AnyGameSelected bcs _gameToLaunchExit +ST16 WINDEX - +LDADDR gGamesListStore + +LDADDR gSearchStore jsr okvs_nth ForceGoodResult clc @@ -56,130 +57,53 @@ _gameToLaunchExit ;------------------------------------------------------------------------------ ; FindGame -; check if an arbitrary game exists, for some definition of 'exists' -; -; in: A/Y points to game filename -; out: C clear if game exists in gGamesListStore, and -; $WINDEX = game index, or #$FFFF if the game doesn't really -; exist but we want to return a successful result anyway -; C set if game does not exist (this can happen because slideshows -; list games that require a joystick, but the games list parser -; filters them out if the machine doesn't have a joystick) -; all registers clobbered -;------------------------------------------------------------------------------ -FindGame - +ST16 @key - jsr okvs_find - !word gGamesListStore -@key !word $FDFD ; SMC - bcc GlueLaunchRTS -; Hack to allow self-running demos that don't correspond to a game -; filename. If the name ends in a '.', accept it unconditionally. - ldx #$FF - stx WINDEX - stx WINDEX+1 - +LD16 @key - +ST16 PARAM - ldy #0 - lda (PARAM),y - tay - lda (PARAM),y - cmp #"." - beq ForceGoodResult - sec -GlueLaunchRTS - rts - -;------------------------------------------------------------------------------ -; FindGameInActionSlideshow ; check if an arbitrary game exists, for some definition of 'exists', while ; in the middle of a slideshow ; -; /!\ This function assumes that gSlideshowStore exists and is populated, -; which is generally only true during the callback function of a slideshow -; -; in: A/Y points to game filename -; out: C clear if game exists, and -; $WINDEX = game index, and -; A/Y points to game display name + game info bitfield -; C set if game can't be found by any means +; in: A/Y points to a key in gSlideshowStore +; out: C clear if game exists and is playable on current machine, and +; (SAVE) -> game display name, and +; (gLastMegaAttractGame) -> game filename +; C set otherwise +; clobbers $FF, PTR +; all registers clobbered ;------------------------------------------------------------------------------ -FindGameInActionSlideshow - +ST16 @sskey - jsr FindGame - bcc GetGameDisplayName -; if the game was not found, try getting the value of the current record from -; gSlideshowStore (some games have multiple action screenshots, in which case -; the key is only the screenshot filename, and the value is the actual game -; filename) - jsr okvs_get - !word gSlideshowStore -@sskey !word $FDFD ; SMC - jsr FindGame - bcs GlueLaunchRTS - ; /!\ execution falls through here to GetGameDisplayName - -;------------------------------------------------------------------------------ -; GetGameDisplayName -; lookup or construct the display name for a specific game -; -; in: A/Y contains address of a key in gGamesListStore -; out: A/Y contains address of game display name + game info bitfield -; (this might be just the corresponding value in gGamesListStore, -; or it might be a temporary buffer in main memory that we constructed -; out of thin air) -; gValLen possibly clobbered (up to gValLen+MaxInputLength) -; X preserved -; C clear -;------------------------------------------------------------------------------ -GetGameDisplayName - +ST16 SAVE - jsr okvs_get_current ; get value for this key - ; (PTR) -> truncated game display name + info bitfield - ldy #0 - lda (PTR), y ; A = length of truncated game display name + info bitfield - cmp #1 ; 1 means there's no title, just info bitfield (1 byte) +FindGame + +ST16 gLastMegaAttractGame + jsr okvs_next_field ; (PTR) -> OKVS value (filename or empty string) + ; Y=0 + lda (PTR), y beq + +LD16 PTR + +ST16 gLastMegaAttractGame ++ jsr okvs_next_field_PTR_is_already_set ; (PTR) -> game display name + +LD16 PTR ; A/Y -> game display name + +ST16 SAVE ; (SAVE) -> game display name + jsr okvs_next_field ; (PTR) -> game requirements bitfield + ; Y=0 + + ; check if game requires joystick + lda (PTR), y + sta $FF + bpl @check128K + lda MachineStatus + and #HAS_JOYSTICK + beq @failedCheck ; machine doesn't have joystick but game requires it + +@check128K + ; check if game requires 128K + bit $FF + bvc @passedAllChecks + lda MachineStatus + and #HAS_128K + beq @failedCheck ; machine doesn't have 128K but game requires it + +@passedAllChecks clc rts -+ ; game display name is truncated, we must expand it - iny ; Y = 1 - lda (PTR), y ; A = game info bitfield - pha ; save on stack - dey - lda (SAVE), y ; A = length of key - tay - iny - sty @len - sty gValLen - lda #$24 ; BIT opcode - sta @or ; first character remains capitalized - ldy #1 -- lda (SAVE), y - cmp #$49 ; 'I' - bne + - cmp gValLen-1,y - beq ++ ; preserve 'II' casing -+ cmp #$2E - bne @or - lda #$20 ; convert '.' to ' ' -@or ora #$20 ; SMC (opcode) -++ sta gValLen, y - cmp #$20 - bne + - lda #$24 ; first character after ' ' remains capitalized - +HIDE_NEXT_2_BYTES -+ lda #$09 ; OR opcode - sta @or -@next iny -@len=*+1 - cpy #$FD ; SMC - bne - - pla - sta gValLen, y - +LDADDR gValLen - clc + +@failedCheck + sec rts ;------------------------------------------------------------------------------ @@ -194,16 +118,26 @@ GetGameDisplayName PlayGame jsr GetGameToLaunch ; A/Y = address of game filename +PlayGameInAY +ST16 SAVE +ST16 @pfile jsr ClearScreens ; avoid seeing code load into the HGR page ; (clobbers $106, must do now before loading prelaunch code) - jsr LoadFile ; load this game's prelaunch file at $106 - !word kPrelaunchDirectory -@pfile !word $FDFD + jsr LoadIndexedFile ; load prelaunch index file +- !word gSearchCache + !word kPrelaunchIndexRecord + + jsr okvs_find + !word - +@pfile !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadIndexedFile !word $0106 +@indexRecordPtr + !word $FDFD ; SMC ; we start by placing the subdirectory name at gPathname+kGameDirectoryLen ; to leave room for the GameDirectory name as the parent @@ -264,14 +198,16 @@ Launch jmp LaunchInternal Joystick - jsr LoadFile - !word kPrelaunchDirectory - !word kStandardPrelaunch - !word $0106 + jsr LoadStandardPrelaunch - jsr LoadFile - !word kRootDirectory - !word kJoystickFile - !word 0 + jsr LoadIndexedFile + !word $800 + !word kJoystickRecord jmp Launch + +LoadStandardPrelaunch + jsr LoadIndexedFile ; load standard prelaunch code at $0106 + !word $0106 + !word kStandardPrelaunchRecord + rts diff --git a/src/glue.launch.lc2.a b/src/glue.launch.lc2.a index f62863b..700ff73 100644 --- a/src/glue.launch.lc2.a +++ b/src/glue.launch.lc2.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2018-9 by 4am & qkumba +;(c) 2018-2021 by 4am & qkumba ; ; Functions to launch games and self-running demos ; @@ -8,17 +8,18 @@ ; which handle bank switching for you. LaunchInternal - ldy #$F1 -- lda $100,y - sta STACKBASE - $EF,y ; back up stack - iny - bne - tsx ; back up stack pointer stx STACKPTR + 1 - sty RestoreStackNextTime + 1 + inx +- pla + sta STACKBASE - $100 + gStackSize,x + ; back up stack + inx + bne - + stx RestoreStackNextTime + 1 ; tell |Reenter| to restore the stack and stack pointer - tya + txa ldy #$18 - sta $bf57,y dey diff --git a/src/glue.prorwts2.a b/src/glue.prorwts2.a index db33600..97efa23 100644 --- a/src/glue.prorwts2.a +++ b/src/glue.prorwts2.a @@ -1,22 +1,21 @@ ;license:MIT -;(c) 2018-2020 by 4am & qkumba +;(c) 2018-2021 by 4am & qkumba ; ; ProRWTS2 glue functions ; ; Public functions ; - LoadFile -; - LoadDHRFile -; -; Public variables -; - gRootDirectory +; - LoadAuxFile +; - LoadIndexedFile +; - LoadAuxIndexedFile ; ; A general note about paths: ; -; LoadFile, LoadDHRFile, and SaveSmallFile support subdirectories. -; Directories are delimited by '/' like ProDOS. At program startup, we get the -; current directory and save it; that is the PROGRAM ROOT DIRECTORY. All -; pathnames are relative to the PROGRAM ROOT DIRECTORY. There is no concept of -; setting or changing the 'current' directory. +; Load[*]File routines support subdirectories. Directories are delimited by '/' +; like ProDOS. At program startup, we get the current directory and save it; +; that is the PROGRAM ROOT DIRECTORY. All pathnames are relative to the PROGRAM +; ROOT DIRECTORY. There is no concept of setting or changing the 'current' +; directory. ; ; The PROGRAM ROOT DIRECTORY is not guaranteed to be the root directory of the ; underlying ProDOS disk (although it can be). But it doesn't matter, because @@ -33,8 +32,8 @@ ; PROGRAM ROOT DIRECTORY. ;------------------------------------------------------------------------------ -; LoadFile -; Load a file into memory all at once, using ProRWTS2 +; LoadFile/LoadAuxFile +; Load a file into main or auxiliary memory, all at once, using ProRWTS2 ; ; supports paths, see note ; @@ -47,67 +46,131 @@ ; gPathname clobbered ;------------------------------------------------------------------------------ LoadFile - +PARAMS_ON_STACK 6 + ldx #7 + bne .loadcommon +LoadAuxFile + ldx #6 +.loadcommon + pla + sta PARAM + txa + pha + and #6 + clc + adc PARAM + tay + pla + tax + pla + sta PARAM+1 + adc #0 + pha + tya + pha + txa + pha +LDPARAM 1 jsr SetPath +LDPARAM 3 jsr AddToPath + plp + php + bmi + +LDPARAMPTR 5, ldrlo ; set load address - jsr SwitchToBank2 ++ jsr SwitchToBank2 + plp + bcc + jsr LoadFileInternal jmp SwitchToBank1 - -;------------------------------------------------------------------------------ -; LoadAuxFile -; Load a file into aux memory all at once, using ProRWTS2 -; -; supports paths, see note -; -; in: stack contains 6 bytes of parameters: -; +1 [word] address of length-prefixed pathname -; +3 [word] address of length-prefixed filename -; +5 [word] address to load file, or 0 to use file's default address -; out: all flags clobbered -; all registers clobbered -; gPathname clobbered -;------------------------------------------------------------------------------ -LoadAuxFile - +PARAMS_ON_STACK 6 - +LDPARAM 1 - jsr SetPath - +LDPARAM 3 - jsr AddToPath - +LDPARAMPTR 5, ldrlo ; set load address - jsr SwitchToBank2 - lda #1 ; request aux memory ++ ldx #1 ; request aux memory jsr LoadFileAuxInternal jmp SwitchToBank1 ;------------------------------------------------------------------------------ -; LoadDHRFile -; load .A2FC file (uncompressed double hi-res graphics) into memory -; all at once, using ProRWTS2 -; first $2000 bytes of file are loaded into auxiliary memory $4000..$5FFF -; second $2000 bytes of file are loaded into main memory $4000..$4FFF +; LoadIndexedFile/LoadAuxIndexedFile +; Load a file from inside an indexed file, all at once, into main or auxiliary +; memory ; -; supports paths, see note +; To save disk space, some collections of small, related files (e.g. per-game +; help files) are merged into a single data file with an associated index file. +; The index stores the original filename along with an offset (into the merged +; data file) and a length. +; +; Callers are responsible for loading the index file and finding the relevant +; record within the index. Most callers use okvs_find() for this, although some +; have hard-coded records generated at build time. ; ; in: stack contains 4 bytes of parameters: -; +1 [word] address of length-prefixed pathname -; +3 [word] address of length-prefixed filename +; +1 [word] address of load destination +; +3 [word] pointer to index record ; out: all flags clobbered ; all registers clobbered -; stack set to next instruction after parameters ;------------------------------------------------------------------------------ -LoadDHRFile +LoadAuxIndexedFile + lda #$EE ; INC + +HIDE_NEXT_2_BYTES +LoadIndexedFile + lda #$8D ; STA + sta @iauxreq +PARAMS_ON_STACK 4 - +LDPARAM 1 - jsr SetPath - +LDPARAM 3 - jsr AddToPath + +LDPARAMPTR 1, @address + +LDPARAMPTR 3, zpword + inc $BF0E ; disable ROM mapping on return jsr SwitchToBank2 - jsr LoadDHRFileInternal + jsr resetRoot + ldx #2 + ldy #0 + lda (zpword), y + tay +- iny + lda (zpword), y + sta @offset, x + dex + bpl - + dex +- iny + lda (zpword), y + sta @size - $fe, x + inx + bmi - + jsr $bf00 ; yes, ProDOS abstraction + !byte $c8 + !word @c8_parms + jsr $bf00 + !byte $ce + !word @ce_parms +@iauxreq + sta SavedZP + auxreq - first_zp + ; SMC + + jsr $bf00 + !byte $ca + !word @ca_parms + sta auxreq + jsr $bf00 + !byte $cc + !word @cc_parms + jsr swap_zpg ; restore sizelo2/hi2 + dec $BF0E ; re-enable ROM mapping on return + +LD16 @address + sta ldrlo2 ; support Launch of what we just loaded + sty ldrhi2 jmp SwitchToBank1 -gRootDirectory - !word $FDFD +@c8_parms + !byte 3 +@filename + !word kTotalDataFile + !byte 0 +@ce_parms + !byte $d0 + !byte 1 +@offset !byte 0, 0, 0 ; SMC + !byte $ff +@ca_parms + !byte $ff +@cc_parms + !byte 1 +@address !word $DFDF ; SMC +@size !word $DFDF ; SMC + !word $ffff diff --git a/src/glue.prorwts2.lc2.a b/src/glue.prorwts2.lc2.a index c68bfcc..0ca28ec 100644 --- a/src/glue.prorwts2.lc2.a +++ b/src/glue.prorwts2.lc2.a @@ -8,25 +8,19 @@ ; and parse.prefs which handle bank switching for you. LoadFileInternal - lda #0 ; 0 = read into main memory + ldx #0 ; 0 = read into main memory LoadFileAuxInternal - sta @auxreq+1 ; call with A=1 to load directly into aux memory +LDADDR gPathname -!if RELBASE != $2000 { - !ifdef PASS2 { - } else { ;PASS2 - !if * != LoadFileDirect { - !error "LoadFileDirect=",*, ", fix constants.a" - } - } -} +LoadFileDirect +ST16 namlo ; set filename + txa + pha jsr traverse ; go to subdirectory, set up filename for read lda #cmdread ; read (instead of write) sta reqcmd lsr sta auxreq - lda ldrlo+1 + lda ldrhi bne + ; if caller provided a load address, use it sta sizelo ; otherwise query the load address from file metadata sta sizehi ; 0 = query load address @@ -34,43 +28,13 @@ LoadFileAuxInternal +LD16 ldrlo2 +ST16 ldrlo + lda #$FF ; read entire file (ProRWTS2 will figure out exact size) +LoadFileInternal_SizePatch sta sizehi -!if RELBASE != $2000 { - !ifdef PASS2 { - } else { ;PASS2 - !if *+1 != iAuxReq { - !error "iAuxReq=",*+1, ", fix constants.a" - } - } -} -@auxreq - lda #0 + pla sta auxreq JumpOpen jmp hddopendir ; exit via ProRWTS2 -LoadDHRFileInternal - +LDADDR gPathname - +ST16 namlo ; set filename - jsr traverse ; go to subdirectory, set up filename for read - lda #$20 - sta sizehi - asl - sta ldrhi ; into $4000 - lda #cmdread ; read (instead of write) - sta reqcmd - ;;lda #1 ; 1 = read into aux memory - sta auxreq - lsr ; read first $2000 bytes - sta sizelo - sta ldrlo - jsr hddopendir ; call ProRWTS2 - lda #$20 ; read next $2000 bytes - sta sizehi - dec auxreq ; 0 = read into main memory - clc ; not a subdirectory - jmp hddrdwrpart ; call ProRWTS2 - SaveSmallFileInternal +LDADDR gPathname +ST16 namlo ; set filename for ProRWTS2 @@ -80,10 +44,10 @@ SaveSmallFileInternal lda #0 ; 0 = read into main memory sta sizelo ;sta sizehi ; 0 = query load address - ;jsr hddopendir ; call ProRWTS2 + ;jsr hddopendir ; call ProRWTS2 ;lda ldrlo2 sta ldrlo - lda #$80 ;lda ldrhi2 + lda #>kGlobalPrefsBuffer ;lda ldrhi2 sta ldrhi lda #cmdwrite ; write (instead of read) sta reqcmd diff --git a/src/hw.accel.a b/src/hw.accel.a index 9f92c2e..5c8e706 100755 --- a/src/hw.accel.a +++ b/src/hw.accel.a @@ -44,7 +44,7 @@ ; ; WARNING: The memory location to set the accelerator ; speed may overlap existing locations such as: -; annuciators or Apple //c specific hardware +; annunciators or Apple //c specific hardware ; paddle trigger ; ; Known to work: IIGS, //c+ @@ -232,6 +232,7 @@ build_addon ; setspeed must be self-modified before use (setspeed_x and ; setspeed_y). ; +; all return with Z=0 ;----------------------------------------------------------- ; Function #1: Apple IIc+ @@ -250,17 +251,17 @@ iicplus !pseudopc DisableAccelerator { ; cgga calls save X and Y regs but sets $0 to 0 ; (this will get a laugh from C programmers) + php lda $0 pha - php sei ; timing sensitive jsr @jiggerypokery lda gMachineInDHGRMode bne + ; DHGR mode doesn't need fix sta $C05B ; fix HGR-mode colouring -+ plp ; restore interrupt state - pla ++ pla sta $0 + plp ; restore interrupt state rts @jiggerypokery diff --git a/src/hw.accel.lc2.a b/src/hw.accel.lc2.a index 5287d12..de10056 100644 --- a/src/hw.accel.lc2.a +++ b/src/hw.accel.lc2.a @@ -5,13 +5,13 @@ ; Apple II models, cards, and environments ; ; /!\ These live in LC RAM 2 and rely on other code which is also in LC RAM 2. /!\ -; (EnableAccelerator and DisableAccelerator are copied into LC2 in 4sports.init.) +; (EnableAccelerator and DisableAccelerator are copied into LC2 in 4cade.init.) ; You can call these functions directly if and only if you are already in LC2. EnableAcceleratorAndSwitchToBank1 jsr EnableAccelerator - jmp SwitchToBank1 + bne + ; always taken DisableAcceleratorAndSwitchToBank1 jsr DisableAccelerator - jmp SwitchToBank1 ++ jmp SwitchToBank1 diff --git a/src/hw.joystick.a b/src/hw.joystick.a index 1260eee..813c23f 100644 --- a/src/hw.joystick.a +++ b/src/hw.joystick.a @@ -16,7 +16,6 @@ ; Fastchip firmware 0.4b-compatibility fix by Frank M. (0.5b seems unaffected) ;------------------------------------------------------------------------------ HasJoystick - lda $FBB3 cmp #$06 bne ++ diff --git a/src/hw.mockingboard.a b/src/hw.mockingboard.a index 05c36b7..72e3fd1 100644 --- a/src/hw.mockingboard.a +++ b/src/hw.mockingboard.a @@ -18,15 +18,26 @@ ; (zp$81 will contain the slot in form $Cx) ; /!\ ALL ACCELERATORS MUST BE OFF OR SET TO 1 MHZ ; out: if card was found, X = #$?n where n is the slot number of the card, otherwise #$00 -; and bit 6 = 0 if Mockingboard Sound I found -; or bit 6 = 1 if Mockingboard Sound II or "A" found -; and bit 7 = 1 if Mockingboard Sound/Speech I or "C" found +; and bit 5 = 0 if Mockingboard Sound I found +; or bit 5 = 1 if Mockingboard Sound II or "A"-"D" found +; and bit 6 = 1 if SSI-263 speech chip found +; or bit 7 = 1 if SC-01 speech chip found ; flags clobbered ; zp $80-$82 clobbered ; A/Y clobbered ;------------------------------------------------------------------------------ GetMockingboardStuff +ST16 @callback+1 + lda ROM_MACHINEID + cmp #$06 + bne @not_iic + ldx ROM_MACHINE2C + bne @not_iic + dex ; enable Mockingboard 4C support + stx $C403 + stx $C404 + +@not_iic lda #$00 sta $80 sta $82 ; type @@ -127,11 +138,13 @@ GetMockingboardStuff @wait_irq lda $80 - bne @got_irq + bne + iny bne @wait_irq inx bne @wait_irq + clc ++ ror $82 ; detect speech - SC-01 ;based on S/S I demo dsk @@ -159,24 +172,22 @@ GetMockingboardStuff bne - inx bne - - clc ; not found - bcc @got_irq + beq @got_irq @mb_smc21 + sta $c40d ; ifr, clear flag lda #$00 ; turn off cb2 pulse mode to disable false writes to sc01 @mb_smc22 sta $c40c ; pcr - sec ; found, we have an S/S I + sec ; found, we have an SC-01 ror $82 - ldy #$ff - bcc @ssI + bne @ssI @got_irq sei + clc ; not found ror $82 -@onlyI ldy #$ff @mb_smc6 sty $c403 ; 6522#1 ddra @@ -190,16 +201,16 @@ GetMockingboardStuff sta ($80),y ; 6522#1 orb lda #4 sta ($80),y ; 6522#1 orb - dey + @ssI + ldy #$ff @mb_smc8 sty $c483 ; 6522#2 ddra lda #7 @mb_smc9 sta $c482 ; 6522#2 ddrb - iny - tya + lda #0 ldy #$80 sta ($80),y ; 6522#2 orb lda #4 diff --git a/src/hw.vbl.a b/src/hw.vbl.a index d0fa9b6..59aae8d 100644 --- a/src/hw.vbl.a +++ b/src/hw.vbl.a @@ -4,7 +4,7 @@ ; Functions to enable and disable VBL polling on various ; Apple II models -iWaitForVBL +iWaitForVBL sei ; IIc is special sta $C07F ; enable access to VBL register sta $C05B ; enable VBL polling diff --git a/src/index/artwork.idx.a b/src/index/artwork.idx.a new file mode 100644 index 0000000..0744b33 --- /dev/null +++ b/src/index/artwork.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/ARTWORK.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1444524 + !le16 496 diff --git a/src/index/attract.idx.a b/src/index/attract.idx.a new file mode 100644 index 0000000..9676cab --- /dev/null +++ b/src/index/attract.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/ATTRACT.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1434095 + !le16 917 diff --git a/src/index/cache00.idx.a b/src/index/cache00.idx.a new file mode 100644 index 0000000..12478d4 --- /dev/null +++ b/src/index/cache00.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/CACHE00.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1427723 + !le16 214 diff --git a/src/index/cache01.idx.a b/src/index/cache01.idx.a new file mode 100644 index 0000000..07c09e0 --- /dev/null +++ b/src/index/cache01.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/CACHE01.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1428988 + !le16 458 diff --git a/src/index/cache10.idx.a b/src/index/cache10.idx.a new file mode 100644 index 0000000..8f1e420 --- /dev/null +++ b/src/index/cache10.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/CACHE10.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1430525 + !le16 399 diff --git a/src/index/cache11.idx.a b/src/index/cache11.idx.a new file mode 100644 index 0000000..926d9e1 --- /dev/null +++ b/src/index/cache11.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/CACHE11.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1432610 + !le16 688 diff --git a/src/index/count00.a b/src/index/count00.a new file mode 100644 index 0000000..d5fd9b3 --- /dev/null +++ b/src/index/count00.a @@ -0,0 +1,6 @@ +; +; Game count +; +; This file is automatically generated +; +!word 15 diff --git a/src/index/count01.a b/src/index/count01.a new file mode 100644 index 0000000..a734be3 --- /dev/null +++ b/src/index/count01.a @@ -0,0 +1,6 @@ +; +; Game count +; +; This file is automatically generated +; +!word 26 diff --git a/src/index/count10.a b/src/index/count10.a new file mode 100644 index 0000000..27451ad --- /dev/null +++ b/src/index/count10.a @@ -0,0 +1,6 @@ +; +; Game count +; +; This file is automatically generated +; +!word 29 diff --git a/src/index/count11.a b/src/index/count11.a new file mode 100644 index 0000000..27c64ac --- /dev/null +++ b/src/index/count11.a @@ -0,0 +1,6 @@ +; +; Game count +; +; This file is automatically generated +; +!word 43 diff --git a/src/index/coverfade.idx.a b/src/index/coverfade.idx.a new file mode 100644 index 0000000..419530e --- /dev/null +++ b/src/index/coverfade.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/COVERFADE +; +; This file is automatically generated +; + !byte 0 + !be24 1445020 + !le16 410 diff --git a/src/index/credits.idx.a b/src/index/credits.idx.a new file mode 100644 index 0000000..3c7f730 --- /dev/null +++ b/src/index/credits.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/CREDITS +; +; This file is automatically generated +; + !byte 0 + !be24 1445774 + !le16 256 diff --git a/src/index/decrunch.idx.a b/src/index/decrunch.idx.a new file mode 100644 index 0000000..fe2c5fb --- /dev/null +++ b/src/index/decrunch.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/DECRUNCH +; +; This file is automatically generated +; + !byte 0 + !be24 1446030 + !le16 303 diff --git a/src/index/dfx.idx.a b/src/index/dfx.idx.a new file mode 100644 index 0000000..a4f791c --- /dev/null +++ b/src/index/dfx.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/DFX.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1437158 + !le16 1242 diff --git a/src/index/dgr.fizzle.idx.a b/src/index/dgr.fizzle.idx.a new file mode 100644 index 0000000..9b7dd4e --- /dev/null +++ b/src/index/dgr.fizzle.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/DGR.FIZZLE +; +; This file is automatically generated +; + !byte 0 + !be24 1445506 + !le16 67 diff --git a/src/index/dgr.idx.a b/src/index/dgr.idx.a new file mode 100644 index 0000000..6751c2d --- /dev/null +++ b/src/index/dgr.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/DGR.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1444512 + !le16 12 diff --git a/src/index/dhgr.idx.a b/src/index/dhgr.idx.a new file mode 100644 index 0000000..5ca3f31 --- /dev/null +++ b/src/index/dhgr.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/DHGR.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1443721 + !le16 739 diff --git a/src/index/dtitle.idx.a b/src/index/dtitle.idx.a new file mode 100644 index 0000000..41be221 --- /dev/null +++ b/src/index/dtitle.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/DTITLE.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1442057 + !le16 216 diff --git a/src/index/fx.idx.a b/src/index/fx.idx.a new file mode 100644 index 0000000..4f9da1c --- /dev/null +++ b/src/index/fx.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/FX.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1435012 + !le16 2146 diff --git a/src/index/gamehelp.idx.a b/src/index/gamehelp.idx.a new file mode 100644 index 0000000..395baf0 --- /dev/null +++ b/src/index/gamehelp.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/GAMEHELP.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1438758 + !le16 797 diff --git a/src/index/gr.fizzle.idx.a b/src/index/gr.fizzle.idx.a new file mode 100644 index 0000000..801003a --- /dev/null +++ b/src/index/gr.fizzle.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/GR.FIZZLE +; +; This file is automatically generated +; + !byte 0 + !be24 1445430 + !le16 76 diff --git a/src/index/gr.idx.a b/src/index/gr.idx.a new file mode 100644 index 0000000..72d9619 --- /dev/null +++ b/src/index/gr.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/GR.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1444460 + !le16 52 diff --git a/src/index/helptext.idx.a b/src/index/helptext.idx.a new file mode 100644 index 0000000..1d32f4c --- /dev/null +++ b/src/index/helptext.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HELPTEXT +; +; This file is automatically generated +; + !byte 0 + !be24 1445573 + !le16 201 diff --git a/src/index/hgr0.idx.a b/src/index/hgr0.idx.a new file mode 100644 index 0000000..9913c25 --- /dev/null +++ b/src/index/hgr0.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HGR0.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1442273 + !le16 335 diff --git a/src/index/hgr1.idx.a b/src/index/hgr1.idx.a new file mode 100644 index 0000000..710ad9a --- /dev/null +++ b/src/index/hgr1.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HGR1.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1442608 + !le16 69 diff --git a/src/index/hgr2.idx.a b/src/index/hgr2.idx.a new file mode 100644 index 0000000..380f1c8 --- /dev/null +++ b/src/index/hgr2.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HGR2.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1442677 + !le16 81 diff --git a/src/index/hgr3.idx.a b/src/index/hgr3.idx.a new file mode 100644 index 0000000..427d82e --- /dev/null +++ b/src/index/hgr3.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HGR3.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1442758 + !le16 62 diff --git a/src/index/hgr4.idx.a b/src/index/hgr4.idx.a new file mode 100644 index 0000000..1461178 --- /dev/null +++ b/src/index/hgr4.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HGR4.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1442820 + !le16 623 diff --git a/src/index/hgr5.idx.a b/src/index/hgr5.idx.a new file mode 100644 index 0000000..86ea705 --- /dev/null +++ b/src/index/hgr5.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HGR5.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1443443 + !le16 274 diff --git a/src/index/hgr6.idx.a b/src/index/hgr6.idx.a new file mode 100644 index 0000000..2fbb5d6 --- /dev/null +++ b/src/index/hgr6.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/HGR6.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1443717 + !le16 4 diff --git a/src/index/joystick.idx.a b/src/index/joystick.idx.a new file mode 100644 index 0000000..d1ade85 --- /dev/null +++ b/src/index/joystick.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/JOYSTICK +; +; This file is automatically generated +; + !byte 0 + !be24 1446333 + !le16 2370 diff --git a/src/index/miniattract0.idx.a b/src/index/miniattract0.idx.a new file mode 100644 index 0000000..a8c86cc --- /dev/null +++ b/src/index/miniattract0.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/MINIATTRACT0.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1440617 + !le16 381 diff --git a/src/index/miniattract1.idx.a b/src/index/miniattract1.idx.a new file mode 100644 index 0000000..570af86 --- /dev/null +++ b/src/index/miniattract1.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/MINIATTRACT1.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1440998 + !le16 420 diff --git a/src/index/prelaunch.idx.a b/src/index/prelaunch.idx.a new file mode 100644 index 0000000..38891f2 --- /dev/null +++ b/src/index/prelaunch.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/PRELAUNCH.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1433298 + !le16 797 diff --git a/src/index/res.cover.idx.a b/src/index/res.cover.idx.a new file mode 100644 index 0000000..8ffe940 --- /dev/null +++ b/src/index/res.cover.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/COVER +; +; This file is automatically generated +; + !byte 0 + !be24 422443 + !le16 8184 diff --git a/src/index/res.help.idx.a b/src/index/res.help.idx.a new file mode 100644 index 0000000..26d34f5 --- /dev/null +++ b/src/index/res.help.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/HELP +; +; This file is automatically generated +; + !byte 0 + !be24 438819 + !le16 8184 diff --git a/src/index/res.title.idx.a b/src/index/res.title.idx.a new file mode 100644 index 0000000..80f59b5 --- /dev/null +++ b/src/index/res.title.idx.a @@ -0,0 +1,8 @@ +; +; Index record for res/TITLE +; +; This file is automatically generated +; + !byte 0 + !be24 430627 + !le16 8192 diff --git a/src/index/search00.idx.a b/src/index/search00.idx.a new file mode 100644 index 0000000..d214323 --- /dev/null +++ b/src/index/search00.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/SEARCH00.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1427156 + !le16 567 diff --git a/src/index/search01.idx.a b/src/index/search01.idx.a new file mode 100644 index 0000000..ce4f6b4 --- /dev/null +++ b/src/index/search01.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/SEARCH01.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1427937 + !le16 1051 diff --git a/src/index/search10.idx.a b/src/index/search10.idx.a new file mode 100644 index 0000000..2f94281 --- /dev/null +++ b/src/index/search10.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/SEARCH10.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1429446 + !le16 1079 diff --git a/src/index/search11.idx.a b/src/index/search11.idx.a new file mode 100644 index 0000000..b42cbe8 --- /dev/null +++ b/src/index/search11.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/SEARCH11.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1430924 + !le16 1686 diff --git a/src/index/sfx.idx.a b/src/index/sfx.idx.a new file mode 100644 index 0000000..a403c4d --- /dev/null +++ b/src/index/sfx.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/SFX.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1438400 + !le16 358 diff --git a/src/index/slideshow.idx.a b/src/index/slideshow.idx.a new file mode 100644 index 0000000..3d16922 --- /dev/null +++ b/src/index/slideshow.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/SLIDESHOW.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1439555 + !le16 1062 diff --git a/src/index/standard.prelaunch.a b/src/index/standard.prelaunch.a new file mode 100644 index 0000000..65ba825 --- /dev/null +++ b/src/index/standard.prelaunch.a @@ -0,0 +1,8 @@ +; +; Index record for standard prelaunch code +; +; The file is maintained by hand +; + !byte 0 + !be24 0 + !le16 PRELAUNCH_STANDARD_SIZE diff --git a/src/index/title.idx.a b/src/index/title.idx.a new file mode 100644 index 0000000..0c8e584 --- /dev/null +++ b/src/index/title.idx.a @@ -0,0 +1,8 @@ +; +; Index record for build/TITLE.IDX +; +; This file is automatically generated +; + !byte 0 + !be24 1441418 + !le16 639 diff --git a/src/macros.a b/src/macros.a index 6c5a8dd..ee9670d 100755 --- a/src/macros.a +++ b/src/macros.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; common assembler macros (6502 compatible) ; @@ -10,7 +10,8 @@ ; for functions that take parameters on the stack ; set (PARAM) to point to the parameters and ; move the stack pointer to the first byte after the parameters -; clobbers A,X,Y +; clobbers A,Y +; preserves X !macro PARAMS_ON_STACK .bytes { pla sta PARAM @@ -117,37 +118,51 @@ } ; compare a 16-bit value in A (low) and Y (high) to an absolute address +; branch to target if no match ; zeroes A! -!macro CMP16ADDR .addr { +!macro CMP16ADDR_NE .addr, .target { eor .addr - bne + + bne .target cpy .addr+1 -+ + bne .target } ; compare a 16-bit value in X (low) and Y (high) to an absolute address -!macro CPX16ADDR .addr { +; branch to target if no match +!macro CPX16ADDR_NE .addr, .target { cpx .addr - bne + + bne .target cpy .addr+1 + bne .target +} + +; compare a 16-bit value in A (low) and Y (high) to an immediate value +; branch to target if match +!macro CMP16_E .val, .target { + cmp #<.val + bne + + cpy #>.val + beq .target + } ; compare a 16-bit value in A (low) and Y (high) to an immediate value -!macro CMP16 .val { +; branch to target if no match +!macro CMP16_NE .val, .target { cmp #<.val - bne + + bne .target cpy #>.val -+ + bne .target } ; compare a 16-bit value in X (low) and Y (high) against zero +; branch to target if not zero ; requires LDX16 immediately prior, since Y comparison is implicit! ; destroys A! -!macro CPX16_0 { - bne + +!macro CPX16_0_NE .target { + bne .target txa -+ + bne .target } !macro LBPL .target { @@ -194,7 +209,7 @@ ; various language card configurations !macro READ_RAM1_NO_WRITE { - bit $C088 + sta $C088 } !macro READ_RAM1_WRITE_RAM1 { @@ -203,7 +218,7 @@ } !macro READ_RAM2_NO_WRITE { - bit $C080 + sta $C080 } !macro READ_RAM2_WRITE_RAM2 { @@ -222,7 +237,23 @@ } !macro READ_ROM_NO_WRITE { - bit $C082 + sta $C082 +} + +!macro READ_AUX { + sta READMAINMEM +} + +!macro READ_MAIN { + sta READAUXMEM +} + +!macro WRITE_AUX { + sta WRITEAUXMEM +} + +!macro WRITE_MAIN { + sta WRITEMAINMEM } ; requires setting zpCharMask in zero page to #$FF or #$DF before use @@ -283,18 +314,16 @@ +READ_ROM_NO_WRITE } -!macro GET_MOCKINGBOARD_SPEECH { ;carry set if present +!macro GET_MOCKINGBOARD_SPEECH { ;sign set if SC-01, overflow set if SSI-263 +READ_RAM2_NO_WRITE - lda MockingboardStuff - asl + bit MockingboardStuff +READ_ROM_NO_WRITE } -!macro GET_MOCKINGBOARD_SPEECH_AND_MACHINE_STATUS { ;carry set if present +!macro GET_MOCKINGBOARD_SPEECH_AND_MACHINE_STATUS { ;sign set if SC-01, overflow set if SSI-263 +READ_RAM2_NO_WRITE - lda MockingboardStuff - asl lda MachineStatus + bit MockingboardStuff +READ_ROM_NO_WRITE } @@ -302,6 +331,7 @@ +READ_RAM2_NO_WRITE lda MockingboardStuff cmp #1 + and #7 ora #$C0 +READ_ROM_NO_WRITE } @@ -310,11 +340,13 @@ +READ_RAM2_NO_WRITE lda MockingboardStuff cmp #1 + and #7 ora #$C0 tax lda MachineStatus +READ_ROM_NO_WRITE } + !macro USES_TEXT_PAGE_2 { lda ROM_MACHINEID cmp #$06 @@ -330,28 +362,80 @@ !macro RESET_VECTOR .addr { lda #<.addr sta $3F2 + !ifndef .addr { + !set emitted=1 + lda #>.addr + sta $3F3 + eor #$A5 + sta $3F4 + } else { + !ifdef emitted { + lda #>.addr + sta $3F3 + eor #$A5 + sta $3F4 + } else { + !if (>.addr != 1) or (.addr = $100) { + lda #>.addr + sta $3F3 + eor #$A5 + sta $3F4 + } + } + } +} + +!macro RESET_VECTOR_HALF .addr { lda #>.addr sta $3F3 eor #$A5 sta $3F4 } +!macro RESET_AND_IRQ_VECTOR .addr { + lda #<.addr + sta $3F2 + sta $3FE + lda #>.addr + sta $3F3 + sta $3FF + eor #$A5 + sta $3F4 +} ; for games that clobber $100-$105, the prelaunch code constructs a new reset vector ; somewhere else and sets its !macro NEW_RESET_VECTOR .addr { + ldx #5 +- lda $100,x + sta .addr,x + dex + bpl - + +RESET_VECTOR .addr +} + +!macro NEW_RESET_VECTOR_64K .addr { lda #$2C sta .addr - lda #$88 + lda #$89 sta .addr+1 lda #$C0 sta .addr+2 - lda #$6C ; JMP ($FFFC) points to 'Reenter' + lda #$4C ; JMP $FAA6 to reboot sta .addr+3 - lda #$FC + lda #$A6 sta .addr+4 - lda #$FF + lda #$FA sta .addr+5 - +RESET_VECTOR .addr + lda #<.addr + sta $3F2 + sta $FFFC + !if >.addr != 1 { + lda #>.addr + sta $3F3 + sta $FFFD + eor #$A5 + sta $3F4 + } } ; for 64k games on ][+ which either hang or restart @@ -370,23 +454,78 @@ ; load an external file by pathname ; LC RAM 2 MUST BE BANKED IN -; LOW BYTE OF .addr MUST BE $00 +; set .addr to $0000 to load to any aligned addres in main +; LOW BYTE OF .addr MUST BE $00 IN THAT CASE !macro LOAD_FILE_AT .filepath, .addr { - lda #0 - sta iAuxReq ; read to main memory + !if .addr > 0 { lda #>.addr sta ldrhi + } + !if <.addr > 0 { + lda #<.addr + sta ldrlo + } lda iCurBlockLo pha lda iCurBlockHi pha + ldx #0 ; read to main memory + !if <.addr = 0 { + stx ldrlo + } +LDADDR .filepath - jsr LoadFileDirect + jsr iLoadFileDirect pla sta iCurBlockHi pla sta iCurBlockLo } +; load an external file by pathname +; set path to new directory +; LC RAM 2 MUST BE BANKED IN +!macro LOAD_FILE_KEEP_DIR .filepath, .dirlen { + ldx #0 ; read to main memory + stx ldrhi + stx ldrlo + +LDADDR .filepath + jsr iLoadFileDirect + + ldx #.dirlen + stx $BFD0 +- lda .filepath,x + sta $BFD0,x + dex + bne - + +} + +!macro LOAD_FILE_KEEP_DIR .filepath, .addr, .dirlen { + lda #>.addr + sta ldrhi + lda #<.addr + sta ldrlo + ldx #0 ; read to main memory + +LDADDR .filepath + jsr iLoadFileDirect + + ldx #.dirlen + stx $BFD0 +- lda .filepath,x + sta $BFD0,x + dex + bne - +} + +; Macros for demo launchers that need to check whether they should run +; on the current machine. Exit demo if the requirements are not met. +!macro GAME_REQUIRES_JOYSTICK { + +GET_MACHINE_STATUS + and #HAS_JOYSTICK + bne + + jmp $100 ++ +} + _MACROS_=* } diff --git a/src/okvs.a b/src/okvs.a index f9ef0dc..fa446aa 100644 --- a/src/okvs.a +++ b/src/okvs.a @@ -1,12 +1,10 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; Ordered key/value store (6502 compatible)(256+ records compatible) ; ; Public functions -; - okvs_init(address) reset (required) ; - okvs_len(address) get number of keys -; - okvs_append(address, key, value, max_len) add new key/value pair ; - okvs_update(address, key, value) update key/value pair ; - okvs_get(address, key) get value by key lookup ; - okvs_find(address, key) get key by key lookup @@ -18,88 +16,65 @@ ; Call init() once. Call it again to reset the store to 0 records. ; ; Records are maintained in a singly linked list, so most functions are O(n). -; len() and append() are O(1) though. +; len() is always O(1). okvs_nth() can be O(1) if some other code produces +; a key lookup table and stores its address in the 'free space pointer +; after last record' field in the header. ; ; Record count is stored as a word, so a store can hold 65535 records. ; ; Keys and values are length-prefixed strings (Pascal style), so max length -; of any single key or value is 255 bytes. +; of any single key or value is 255 bytes. Record length is stored as a byte +; that includes itself, so the maximum data length of a record is 254 bytes. ; ; Keys are case-sensitive. Lookups are an exact byte-for-byte comparison. ; -; append() has a max_len argument to reserve more space for the value, in case -; you want to update it later. max_len is the total space to reserve, not the -; additional space. One exception: max_len can be 0, and it will be treated as -; length(value) at append time. update() always modifies the value in place. -; There is no range checking because this is assembly. - ; All functions take the starting address of the store's data buffer in -; memory, so there can be multiple independent stores at one time. The next- -; record pointers are actual memory addresses, so stores are not easily -; relocatable. append() will happily extend the store's data buffer without -; limit. There is no overflow protection because this is assembly. +; memory, so there can be multiple independent stores at one time. Only the +; size of a record is stored, so stores are easily relocatable. There is no +; overflow protection because this is assembly. +; +; There is an append() function but it has been separated out of this version +; because it is only used once during program startup, so it does not need +; to persist in LC RAM. ; ; There is no sort() function. ; ; There is no delete() function. ; -; Keys can be duplicated, but get() and find() will always return the one that -; was append()ed first. +; Keys can be duplicated, but get() and find() will always return the first +; match. +; +; Records can technically have more fields than key and value, but callers +; are on their own for navigating inside the record. If you have a pointer +; to one length-prefixed field (including key or value), okvs_next_field() +; will find the start of the next field. ; ; Structures: ; ; Store ; +0 number of records (word) -; +2 free space pointer after last record (word) +; +2 free space pointer after last record (word) or $0000 ; +4 Record ; ...Record... ; ...Record... ; ; Record -; +0 next-record pointer (word) -; +2 key length -; +3 key +; +0 record length (including this field) +; +1 key length +; +2 key ; +K+2 value length (actual length, not max length) ; +K+3 value ; ... filler bytes up to value max length (set at append() time) -;------------------------------------------------------------------------------ -; okvs_init -; -; in: A/Y = handle to storage space -; out: $00/$01 clobbered -; $02/$03 clobbered -; all registers clobbered -;------------------------------------------------------------------------------ -okvs_init - jsr GetStoreAddressFromAY - ; PTR -> store - ; Y = 0 - tya - sta (PTR),y ; set number of keys in store to 0 (word) - iny - sta (PTR),y - - iny ; set next-free-space pointer to store + 4 - ldx PTR+1 - lda PTR - clc - adc #$04 - bcc + - inx -+ sta (PTR),y - iny - txa - sta (PTR),y - rts - ;------------------------------------------------------------------------------ ; okvs_len +; okvs_len_imm ; ; in: A/Y = handle to storage space ; out: $WCOUNT contains number of keys in this store ; X preserved ; A, Y clobbered +; Z set if no keys ; $00/$01 clobbered ; $02/$03 clobbered ;------------------------------------------------------------------------------ @@ -107,119 +82,13 @@ okvs_len jsr GetStoreAddressFromAY ; PTR -> store ; Y = 0 +okvs_len_imm lda (PTR), y ; get number of keys in store (word) sta WCOUNT iny lda (PTR), y sta WCOUNT+1 - rts - -;------------------------------------------------------------------------------ -; okvs_append -; -; in: stack contains 7 bytes of parameters: -; +1 [word] handle to storage space -; +3 [word] address of key -; +5 [word] address of value -; +7 [byte] maximum length of value (or 0 to fit) -; out: (new record count is not returned because no one cares) -; all registers clobbered -; $00/$01 clobbered -; $02/$03 clobbered -; $04/$05 has the address of the next available byte after the new record -; $08/$09 clobbered -;------------------------------------------------------------------------------ -okvs_append - +PARAMS_ON_STACK 7 - jsr GetStoreAddress - ; PTR -> store - ; Y = 0 - lda (PTR),y ; A = number of keys in store - sta WINDEX - iny - lda (PTR), y - sta WINDEX+1 - inc WINDEX - bne + - inc WINDEX+1 -+ - dey - lda WINDEX - sta (PTR),y ; increment number of keys - lda WINDEX+1 - iny - sta (PTR),y - iny - lda (PTR),y ; get address of next free space - tax - iny - lda (PTR),y - sta PTR+1 - sta SAVE+1 - stx PTR - stx SAVE - ; PTR -> new record - ; SAVE -> new record - jsr incptr2 - ; PTR -> space for new key - +LDPARAMPTR 3, SRC ; SRC -> new key to copy - ldy #0 - lda (SRC),y - tay - tax -- lda (SRC),y ; copy new key - sta (PTR),y - dey - cpy #$FF - bne - - - ;;sec - txa - adc PTR ; update PTR to byte after copied key - sta PTR - bcc + - inc PTR+1 -+ ; PTR -> space for new value - +LDPARAMPTR 5, SRC ; SRC -> new value to copy - iny ;;ldy #7 - lda (PARAM),y ; get max length of value - tax - bne + - tay - lda (SRC),y ; no max, use actual length instead - tax - inx -+ tay -- lda (SRC),y - sta (PTR),y - dey - cpy #$FF - bne - - - txa - clc - adc PTR - sta SRC - bcc + - inc PTR+1 -+ lda PTR+1 - sta SRC+1 ; SRC -> byte after this record - +LD16 SAVE - +ST16 PTR ; PTR -> this record again - ldy #0 - lda SRC ; update next-record pointer - sta (PTR),y - iny - lda SRC+1 - sta (PTR),y - jsr GetStoreAddress - ; PTR -> store - ldy #2 - lda SRC-2,y - sta (PTR),y ; update next-free-space pointer in head - iny - lda SRC-2,y - sta (PTR),y + ora WCOUNT rts ;------------------------------------------------------------------------------ @@ -247,16 +116,8 @@ okvs_get jsr GetStoreAddress ; PTR -> store ; Y = 0 - lda (PTR),y ; A = number of keys in store - sta WCOUNT - iny - lda (PTR),y - sta WCOUNT+1 - bne + - dey - lda (PTR),y + jsr okvs_len_imm beq @fail ; no keys, fail immediately -+ jsr incptr4 ; PTR -> first record +LDPARAMPTR 3, SRC ; SRC -> key we want to find @@ -269,11 +130,12 @@ okvs_get sty KEYLEN @matchRecordLoop +LD16 PTR - clc - adc #2 - bcc + - iny ; DEST -> key of this record -+ +ST16 DEST + tax + inx + bne + + iny ++ stx DEST ; DEST -> key of this record + sty DEST+1 ldy #0 @matchKeyLoop lda (SRC),y @@ -287,11 +149,11 @@ KEYLEN = *+1 clc @maybeGetValue brk ; SMC - jsr okvs_get_current + jsr okvs_next_field +LD16 PTR clc rts -@next jsr derefptr ; PTR -> next record +@next jsr stepptr ; PTR -> next record inc WINDEX bne + inc WINDEX+1 @@ -305,17 +167,6 @@ KEYLEN = *+1 @fail sec rts -okvs_get_current - +ST16 PTR - ldy #0 - lda (PTR),y - clc - adc PTR - sta PTR - bcc + - inc PTR+1 -+ jmp incptr - ;------------------------------------------------------------------------------ ; okvs_next ; get (N+1)th key, with wraparound @@ -334,8 +185,7 @@ okvs_next + jsr okvs_len +LD16 WINDEX - +CMP16ADDR WCOUNT - bne + + +CMP16ADDR_NE WCOUNT, + sta WINDEX sta WINDEX+1 + @@ -349,20 +199,46 @@ okvs_next ; $WINDEX = record index ; out: A/Y = lo/hi address of nth key ; $WINDEX preserved -; X = 0 -; Z = 0 ; all other flags clobbered ; $PTR clobbered ;------------------------------------------------------------------------------ okvs_nth - jsr GetStoreAddressFromAY - ; PTR -> store - jsr incptr4 - ; PTR -> first record + jsr GetStoreAddressFromAY ; PTR -> store +LD16 WINDEX +ST16 SAVE - jmp @next -- jsr derefptr + jsr incptr2 ; PTR -> store+2 + ldy #1 + lda (PTR), y + beq @slowpath ; if no key lookup table, iterate through store + pha ; otherwise look up key address and return it + dey + lda (PTR), y + sta PTR + pla + sta PTR+1 ; PTR -> key lookup table + asl SAVE + rol SAVE+1 ; SAVE = WINDEX*2 (16-bit) + lda SAVE + clc + adc PTR + bcc + + clc + inc PTR+1 ++ sta PTR + lda SAVE+1 + adc PTR+1 + sta PTR+1 ; PTR -> nth record key lookup table + lda (PTR), y + pha + iny + lda (PTR), y + tay + pla ; A/Y -> nth key in store + rts +@slowpath + jsr incptr2 ; PTR -> first record + bne @next ; always branches +- jsr stepptr @next lda SAVE dec SAVE @@ -372,9 +248,8 @@ okvs_nth dec SAVE+1 tay bne - - jsr incptr2 + jsr incptr +LD16 PTR - ldx #0 rts ;------------------------------------------------------------------------------ @@ -449,31 +324,22 @@ okvs_iter_values jsr GetStoreAddress ; PTR -> store ; Y = 0 - lda (PTR),y ; get number of keys in store (word) - sta WCOUNT - iny - lda (PTR),y - sta WCOUNT+1 - bne + - dey - lda (PTR),y + jsr okvs_len_imm beq @exit ; no keys, exit immediately -+ - +LDPARAM 3 - +ST16 @callback + +LDPARAMPTR 3, @callback jsr incptr4 ; PTR -> first record lda #0 sta WINDEX sta WINDEX+1 @loop - lda #2 ; for iter, skip length = 2 + lda #1 ; for iter, skip length = 1 @branch bne + ; SMC (iter_values puts a BIT here, so no branch) - ; for iter_values, skip length = length(key) + 2 + 1 - tay ;;ldy #2 + ; for iter_values, skip length = length(key) + 1 + 1 + tay ;;ldy #1 lda (PTR),y ; A = length of key clc - adc #3 ; skip over pointer to next record (2 bytes) + key length (1 byte) + adc #2 ; skip over record length (1 byte) + key length (1 byte) + sta @skiplen lda WCOUNT+1 ; save WCOUNT on stack pha @@ -508,7 +374,7 @@ okvs_iter_values sta WCOUNT pla sta WCOUNT+1 - jsr derefptr ; PTR -> next record + jsr stepptr ; PTR -> next record inc WINDEX bne + inc WINDEX+1 @@ -524,6 +390,16 @@ okvs_iter_values ;------------------------------------------------------------------------------ ; internal functions +okvs_next_field +; out: Y = 0 + +ST16 PTR +okvs_next_field_PTR_is_already_set + jsr stepptr + jmp incptr ; do NOT change this to BNE + ; because if the low byte of PTR is 0 + ; and the value of (PTR) is also 0 + ; then stepptr will return with Z=1 and + ; we will fall through here unexpectedly incptr4 jsr incptr2 incptr2 jsr incptr incptr @@ -560,3 +436,15 @@ derefptr pla sta PTR+1 rts + +stepptr +; out: Y = 0 +; preserves X + ldy #0 + lda (PTR),y + clc + adc PTR + sta PTR + bcc + + inc PTR+1 ++ rts diff --git a/src/parse.common.a b/src/parse.common.a index 353bdcb..d20d8e3 100644 --- a/src/parse.common.a +++ b/src/parse.common.a @@ -31,7 +31,7 @@ ParseKeyValueList +PARAMS_ON_STACK 5 - +LDPARAM 1 + +LDPARAM 1 ; not LDPARAMPTR, SetKeyPtr requires A/Y! +ST16 @store2 jsr SetKeyPtr ldy #5 @@ -135,3 +135,136 @@ IncAndGetChar beq IncAndGetChar .parseKeyValueDone rts + +;------------------------------------------------------------------------------ +; okvs_append +; +; in: stack contains 7 bytes of parameters: +; +1 [word] handle to storage space +; +3 [word] address of key +; +5 [word] address of value +; +7 [byte] maximum length of value (or 0 to fit) +; out: (new record count is not returned because no one cares) +; all registers clobbered +; $00/$01 clobbered +; $02/$03 clobbered +; $04/$05 has the address of the next available byte after the new record +; $08/$09 clobbered +;------------------------------------------------------------------------------ +okvs_append + +PARAMS_ON_STACK 7 + jsr GetStoreAddress + ; PTR -> store + ; Y = 0 + lda (PTR),y ; A = number of keys in store + sta WINDEX + iny + lda (PTR), y + sta WINDEX+1 + inc WINDEX + bne + + inc WINDEX+1 ++ + dey + lda WINDEX + sta (PTR),y ; increment number of keys + lda WINDEX+1 + iny + sta (PTR),y + iny + lda (PTR),y ; get address of next free space + tax + iny + lda (PTR),y + sta PTR+1 + sta SAVE+1 + stx PTR + stx SAVE + ; PTR -> new record + ; SAVE -> new record + jsr incptr + ; PTR -> space for new key + +LDPARAMPTR 3, SRC ; SRC -> new key to copy + ldy #0 + lda (SRC),y + tay + tax +- lda (SRC),y ; copy new key + sta (PTR),y + dey + cpy #$FF + bne - + + ;;sec + txa + adc PTR ; update PTR to byte after copied key + sta PTR + bcc + + inc PTR+1 ++ ; PTR -> space for new value + +LDPARAMPTR 5, SRC ; SRC -> new value to copy + iny ;;ldy #7 + lda (PARAM),y ; get max length of value + tax + bne + + tay + lda (SRC),y ; no max, use actual length instead + tax ++ inx + tay +- lda (SRC),y + sta (PTR),y + dey + cpy #$FF + bne - + + txa + clc + adc PTR + tax + lda PTR+1 + adc #0 + pha ++ jsr GetStoreAddress + ; PTR -> store + pla + ldy #3 + sta (PTR),y ; update next-free-space pointer in head + dey + txa + sta (PTR),y + sec + sbc SAVE + ldy #0 + sta (SAVE),y ; set record length + rts + +;------------------------------------------------------------------------------ +; okvs_init +; +; in: A/Y = handle to storage space +; out: $00/$01 clobbered +; $02/$03 clobbered +; all registers clobbered +;------------------------------------------------------------------------------ +okvs_init + jsr GetStoreAddressFromAY + ; PTR -> store + ; Y = 0 + tya + sta (PTR),y ; set number of keys in store to 0 (word) + iny + sta (PTR),y + + iny ; set next-free-space pointer to store + 4 + ldx PTR+1 + lda PTR + clc + adc #$04 + bcc + + inx ++ sta (PTR),y + iny + txa + sta (PTR),y + rts diff --git a/src/parse.games.a b/src/parse.games.a deleted file mode 100644 index 16becb1..0000000 --- a/src/parse.games.a +++ /dev/null @@ -1,113 +0,0 @@ -;license:MIT -;(c) 2018-2020 by 4am -; -; GAMES.CONF parser -; -; Public functions: -; - ParseGamesList -; - -;------------------------------------------------------------------------------ -; ParseGamesList -; parse buffer with ABC,KEY=VALUE lines of text into an okvs -; keys and values limited to 127 characters, which should be enough for anyone -; '[' character at beginning of line ends the parsing -; (see games.conf file for more format information) -; -; in: stack contains 4 bytes of parameters: -; +1 [word] handle to storage space for okvs -; +3 [word] handle to buffer containing contents of GAMES.CONF -; out: all registers and flags clobbered -; $1F00..$1FFF clobbered -; $00/$01 clobbered -; $02/$03 clobbered -; $04/$05 has the address of the next available byte after the okvs -; $FE/$FF clobbered -;------------------------------------------------------------------------------ -ParseGamesList - +PARAMS_ON_STACK 4 - - +LDPARAM 1 - +ST16 @store2 - jsr SetKeyPtr - - ldy #$00 ; index into ($FE) pointing to current character - beq @newkey ; always branches -@skipLine ; skip to CR - jsr IncAndGetChar - cmp #$0A ; CR - bne @skipLine -@newkey ldx #$00 ; X = index into current key - stx gValLen ; initialize value length (in case this line has no value) -@emptyline - jsr IncAndGetChar ; get first filter character ('1' if game requires joystick) - cmp #$0A ; ignore blank line - beq @emptyline - cmp #$5B ; '[' ends the parsing - beq @exit - cmp #$30 ; '0' -> no filtering on joystick - beq @filterOnMemory - cmp #$31 ; not '0' or '1' or '[' or CR -> ignore entire line (e.g. comment) - bne @skipLine - bit zpMachineStatus - bpl @skipLine ; game requires joystick but we don't have one, so ignore entire line -@filterOnMemory - jsr IncAndGetChar ; get second filter character ('1' if game requires 128K) - cmp #$30 ; '0' -> no filtering on memory - beq @parseDHGRTitle - cmp #$31 ; not '0' or '1' -> ignore entire line - bne @skipLine - bit zpMachineStatus - bvc @skipLine ; game requires 128K but we only have 64K, so ignore entire line -@parseDHGRTitle - jsr IncAndGetChar ; get third character ('1' if game has DHGR title) - and #$01 - pha -@parseCheatsAvailable - jsr IncAndGetChar ; get fourth character (cheat category, int) - and #CHEAT_CATEGORY - pha -@swallowComma - jsr IncAndGetChar -@gatherKey - jsr IncAndGetChar - cmp #$0A ; CR -> finalize key, no value - beq @endKey - cmp #$3D ; '=' ends the key - beq @endKey - sta gKey,x - inx - bpl @gatherKey -@endKey stx gKeyLen - ldx #$00 ; now X = index into the current value - cmp #$0A - beq @endValue -@gatherValue - jsr IncAndGetChar - cmp #$0A ; CR ends the value - beq @endValue - sta gVal,x - inx - bpl @gatherValue -@endValue - pla ; pop cheat category - sta gVal,x ; store after game display name - pla ; pop has-DHGR-title flag - lsr - ror - ora gVal,x - sta gVal,x ; store in bit 7 of same byte as cheat category - inx - stx gValLen - tya - pha ; okvs functions clobber everything but we need Y - jsr okvs_append -@store2 !word $FDFD ; SMC - !word gKeyLen - !word gValLen - !byte 0 - pla ; pop saved Y - tay - jmp @newkey - -@exit rts diff --git a/src/parse.prefs.a b/src/parse.prefs.a index f8a23df..e9e0a43 100644 --- a/src/parse.prefs.a +++ b/src/parse.prefs.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; Parser for global preferences file ; @@ -15,7 +15,7 @@ ; - kCheat ; -kGlobalPrefsBuffer = $8000 +kGlobalPrefsBuffer = $BD00 ; [512 bytes] must be page-aligned ; valid pref keys kNextAttract @@ -27,6 +27,9 @@ kNextFX kNextDFX !byte 7 !raw "NEXTDFX" +kNextSFX + !byte 7 + !raw "NEXTSFX" kCheat !byte 5 !raw "CHEAT" @@ -35,7 +38,7 @@ kCheat !raw "=" .kLF !byte 1,$0A .kFluff1 !byte .kFluff2-*-1 - !raw "# Total Replay II preferences file",$0A + !raw "# Total Replay preferences file",$0A !raw "# Do not edit by hand.",$0A !raw "# Or do. I'm a comment, not a cop.",$0A !byte $0A @@ -46,7 +49,10 @@ kCheat .kFluff3 !byte .kFluff4-*-1 !byte $0A !raw "# value=effect listed in DFX.CONF",$0A -.kFluff4 !byte .kEOF-*-1 +.kFluff4 !byte .kFluff5-*-1 + !byte $0A + !raw "# value=effect listed in SFX.CONF",$0A +.kFluff5 !byte .kEOF-*-1 !byte $0A !raw "# value=0 or 1",$0A .kEOF !byte ._-*-1 @@ -101,11 +107,9 @@ PREFRTS rts ; in: stack contains 4 bytes of parameters: ; +1 [word] address of length-prefixed pref key ; +3 [word] address of OKVS, or 0 -; gGlobalPrefsStore must be initialized (this is done in 4sports.init) +; gGlobalPrefsStore must be initialized (this is done in 4cade.init) ; out: A/Y = address of pref value ; $WINDEX = index of pref value in passed store -; (if OKVS parameter is 0, no validation occurs and X=0 and Z=1 on exit, -; some callers rely on this behavior, so don't change it!) ; PARAM clobbered ; PTR clobbered ; SRC clobbered @@ -113,17 +117,15 @@ PREFRTS rts ;------------------------------------------------------------------------------ pref_get +PARAMS_ON_STACK 4 - +LDPARAMPTR 1, + - +LDPARAMPTR 3, .store1 + jsr .set_store01 - jsr okvs_get ; look up pref key in prefs store + jsr okvs_get ; look up pref key in prefs store, sets PTR to value !word gGlobalPrefsStore -+ !word $FDFD ; SMC +.store0 !word $FDFD ; SMC bcs .useDefaultValue ; if pref key is not found, use default value ldx .store1+1 beq PREFRTS ; if no OKVS to validate against, we're done +ST16 + - +ST16 PTR ldy #0 lda (PTR),y beq .useDefaultValue ; if pref value is empty, use default value @@ -138,6 +140,24 @@ pref_get +LD16 .store1 jmp okvs_nth +.set_store01 + ldx #0 + lda #.store1 - .store0 + +.set_store23 + pha + ldy #1 + jsr + + iny + pla + tax ++ lda (PARAM), y + sta .store0, x + iny + lda (PARAM), y + sta .store0 + 1, x + rts + ;------------------------------------------------------------------------------ ; pref_set ; set pref value by pref key, serialize prefs, and write them to disk @@ -153,13 +173,14 @@ pref_get ;------------------------------------------------------------------------------ pref_set +PARAMS_ON_STACK 4 - +LDPARAMPTR 1, + - +LDPARAMPTR 3, ++ + ldx #.store2 - .store0 + lda #.store3 - .store0 + jsr .set_store23 jsr okvs_update ; save that in prefs store !word gGlobalPrefsStore -+ !word $FDFD ; SMC -++ !word $FDFD ; SMC +.store2 !word $FDFD ; SMC +.store3 !word $FDFD ; SMC +LDADDR kGlobalPrefsBuffer ; clear prefs buffer +ST16 $FE @@ -192,6 +213,11 @@ pref_set +LDADDR .kFluff4 jsr .addString + +LDADDR kNextSFX + jsr .addStringFromStore + + +LDADDR .kFluff5 + jsr .addString +LDADDR kCheat jsr .addStringFromStore @@ -200,13 +226,13 @@ pref_set +LDADDR kGlobalPrefsFilename ; write prefs buffer to file on disk jsr SetPath - +LD16 kGlobalPrefsBuffer ; /!\ execution falls through here to glue.prorwts/SaveSmallFile ;------------------------------------------------------------------------------ ; SaveSmallFile ; Save a file into memory all at once, using ProRWTS2. ; /!\ Only first block (512 bytes) is written. Keep those files small. /!\ ; /!\ All 512 bytes are written to disk. Clear buffer before calling. /!\ +; /!\ Address is hardcoded to kGlobalPrefsBuffer /!\ ; ; supports paths, see note ; @@ -216,7 +242,6 @@ pref_set ; all registers clobbered ;------------------------------------------------------------------------------ SaveSmallFile - +ST16 ldrlo ; set data buffer address for ProRWTS2 jsr SwitchToBank2 jsr SaveSmallFileInternal jmp SwitchToBank1 diff --git a/src/prelaunch/_FileInformation.txt b/src/prelaunch/_FileInformation.txt new file mode 100644 index 0000000..1d9e598 --- /dev/null +++ b/src/prelaunch/_FileInformation.txt @@ -0,0 +1 @@ +# This file is maintained by hand diff --git a/src/prelaunch/battle.chess.a b/src/prelaunch/battle.chess.a index 73a4d66..8d59091 100644 --- a/src/prelaunch/battle.chess.a +++ b/src/prelaunch/battle.chess.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba/Frank M. !cpu 6502 -!to "build/PRELAUNCH/BATTLE.CHESS",plain +!to "build/PRELAUNCH.INDEXED/BATTLE.CHESS",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/bop.n.wrestle.a b/src/prelaunch/bop.n.wrestle.a index 2dab922..1fe2e05 100644 --- a/src/prelaunch/bop.n.wrestle.a +++ b/src/prelaunch/bop.n.wrestle.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba !cpu 6502 -!to "build/PRELAUNCH/BOP.N.WRESTLE",plain +!to "build/PRELAUNCH.INDEXED/BOP.N.WRESTLE",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/computer.foosball.a b/src/prelaunch/computer.foosball.a index 0abe7c3..62e410d 100644 --- a/src/prelaunch/computer.foosball.a +++ b/src/prelaunch/computer.foosball.a @@ -2,7 +2,7 @@ ;(c) 2022 by qkumba !cpu 6502 -!to "build/PRELAUNCH/CMPTR.FOOSBALL",plain +!to "build/PRELAUNCH.INDEXED/CMPTR.FOOSBALL",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/dive.bomber.a b/src/prelaunch/dive.bomber.a index a8901a1..75efb6d 100644 --- a/src/prelaunch/dive.bomber.a +++ b/src/prelaunch/dive.bomber.a @@ -2,7 +2,7 @@ ;(c) 2021 by qkumba !cpu 6502 -!to "build/PRELAUNCH/DIVE.BOMBER",plain +!to "build/PRELAUNCH.INDEXED/DIVE.BOMBER",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/fight.night.a b/src/prelaunch/fight.night.a index 58efe1b..18c5518 100644 --- a/src/prelaunch/fight.night.a +++ b/src/prelaunch/fight.night.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba/Frank M. !cpu 6502 -!to "build/PRELAUNCH/FIGHT.NIGHT",plain +!to "build/PRELAUNCH.INDEXED/FIGHT.NIGHT",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/formula.1.racer.a b/src/prelaunch/formula.1.racer.a index 1118745..90a838d 100755 --- a/src/prelaunch/formula.1.racer.a +++ b/src/prelaunch/formula.1.racer.a @@ -2,7 +2,7 @@ ;(c) 2019 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/FORMULA.1.RACER",plain +!to "build/PRELAUNCH.INDEXED/FORMULA.1.RACER",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/fs2.a b/src/prelaunch/fs2.a index 1a63606..640ff0d 100755 --- a/src/prelaunch/fs2.a +++ b/src/prelaunch/fs2.a @@ -2,7 +2,7 @@ ;(c) 2019 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/FS2",plain +!to "build/PRELAUNCH.INDEXED/FS2",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/hardball.a b/src/prelaunch/hardball.a index daf1f1f..a5cdf96 100644 --- a/src/prelaunch/hardball.a +++ b/src/prelaunch/hardball.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba/Frank M. !cpu 6502 -!to "build/PRELAUNCH/HARDBALL",plain +!to "build/PRELAUNCH.INDEXED/HARDBALL",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/intl.gran.prix.a b/src/prelaunch/intl.gran.prix.a index 396b7ba..b69d910 100755 --- a/src/prelaunch/intl.gran.prix.a +++ b/src/prelaunch/intl.gran.prix.a @@ -2,7 +2,7 @@ ;(c) 2019 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/INTL.GRAN.PRIX",plain +!to "build/PRELAUNCH.INDEXED/INTL.GRAN.PRIX",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/one.on.one.a b/src/prelaunch/one.on.one.a index 5baaf0f..12c3203 100644 --- a/src/prelaunch/one.on.one.a +++ b/src/prelaunch/one.on.one.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba !cpu 6502 -!to "build/PRELAUNCH/ONE.ON.ONE",plain +!to "build/PRELAUNCH.INDEXED/ONE.ON.ONE",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/pool.a b/src/prelaunch/pool.a index 8e261cb..9247223 100644 --- a/src/prelaunch/pool.a +++ b/src/prelaunch/pool.a @@ -2,7 +2,7 @@ ;(c) 2022 by qkumba !cpu 6502 -!to "build/PRELAUNCH/POOL",plain +!to "build/PRELAUNCH.INDEXED/POOL",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/shuffleboard.a b/src/prelaunch/shuffleboard.a index ea65fba..543f2ec 100755 --- a/src/prelaunch/shuffleboard.a +++ b/src/prelaunch/shuffleboard.a @@ -2,7 +2,7 @@ ;(c) 2019 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/SHUFFLEBOARD",plain +!to "build/PRELAUNCH.INDEXED/SHUFFLEBOARD",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/ski.crazed.a b/src/prelaunch/ski.crazed.a index b5e96f4..1a66cf1 100644 --- a/src/prelaunch/ski.crazed.a +++ b/src/prelaunch/ski.crazed.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba !cpu 6502 -!to "build/PRELAUNCH/SKI.CRAZED",plain +!to "build/PRELAUNCH.INDEXED/SKI.CRAZED",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/spdway.classic.a b/src/prelaunch/spdway.classic.a index e460772..c3e1394 100755 --- a/src/prelaunch/spdway.classic.a +++ b/src/prelaunch/spdway.classic.a @@ -2,7 +2,7 @@ ;(c) 2019 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/SPDWAY.CLASSIC",plain +!to "build/PRELAUNCH.INDEXED/SPDWAY.CLASSIC",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/ss.baseball.a b/src/prelaunch/ss.baseball.a index 88d0e9b..5da0d8e 100755 --- a/src/prelaunch/ss.baseball.a +++ b/src/prelaunch/ss.baseball.a @@ -2,7 +2,7 @@ ;(c) 2020 by Frank M., qkumba !cpu 6502 -!to "build/PRELAUNCH/SS.BASEBALL",plain +!to "build/PRELAUNCH.INDEXED/SS.BASEBALL",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/ss.basketball.a b/src/prelaunch/ss.basketball.a index a500135..c8e94bb 100755 --- a/src/prelaunch/ss.basketball.a +++ b/src/prelaunch/ss.basketball.a @@ -2,7 +2,7 @@ ;(c) 2020 by Frank M., qkumba !cpu 6502 -!to "build/PRELAUNCH/SS.BASKETBALL",plain +!to "build/PRELAUNCH.INDEXED/SS.BASKETBALL",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/standard.a b/src/prelaunch/standard.a index 2e118ed..505881f 100644 --- a/src/prelaunch/standard.a +++ b/src/prelaunch/standard.a @@ -2,7 +2,7 @@ ;(c) 2021 by qkumba !cpu 6502 -!to "build/PRELAUNCH/STANDARD",plain +!to "build/PRELAUNCH.INDEXED/STANDARD",plain *=$106 !source "src/constants.a" diff --git a/src/prelaunch/summer.games.a b/src/prelaunch/summer.games.a index aaba2cb..aa8b301 100755 --- a/src/prelaunch/summer.games.a +++ b/src/prelaunch/summer.games.a @@ -2,7 +2,7 @@ ;(c) 2020 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/SUMMER.GAMES",plain +!to "build/PRELAUNCH.INDEXED/SUMMER.GAMES",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/summer.games.ii.a b/src/prelaunch/summer.games.ii.a index aa64fce..9aad1c4 100755 --- a/src/prelaunch/summer.games.ii.a +++ b/src/prelaunch/summer.games.ii.a @@ -2,7 +2,7 @@ ;(c) 2020 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/SUMMER.GAMES.II",plain +!to "build/PRELAUNCH.INDEXED/SUMMER.GAMES.II",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/super.huey.a b/src/prelaunch/super.huey.a index f6cbd63..b9221b3 100644 --- a/src/prelaunch/super.huey.a +++ b/src/prelaunch/super.huey.a @@ -2,7 +2,7 @@ ;(c) 2021 by qkumba !cpu 6502 -!to "build/PRELAUNCH/SUPER.HUEY",plain +!to "build/PRELAUNCH.INDEXED/SUPER.HUEY",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/tag.team.a b/src/prelaunch/tag.team.a index a1f08c6..38c5f13 100755 --- a/src/prelaunch/tag.team.a +++ b/src/prelaunch/tag.team.a @@ -2,7 +2,7 @@ ;(c) 2019 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/TAG.TEAM",plain +!to "build/PRELAUNCH.INDEXED/TAG.TEAM",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/test.drive.a b/src/prelaunch/test.drive.a index fea82cd..b0094d7 100644 --- a/src/prelaunch/test.drive.a +++ b/src/prelaunch/test.drive.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba/Frank M. !cpu 6502 -!to "build/PRELAUNCH/TEST.DRIVE",plain +!to "build/PRELAUNCH.INDEXED/TEST.DRIVE",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/the.dam.busters.a b/src/prelaunch/the.dam.busters.a index cd1d8c0..3e3b86f 100644 --- a/src/prelaunch/the.dam.busters.a +++ b/src/prelaunch/the.dam.busters.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba !cpu 6502 -!to "build/PRELAUNCH/THE.DAM.BUSTERS",plain +!to "build/PRELAUNCH.INDEXED/THE.DAM.BUSTERS",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/tomahawk.a b/src/prelaunch/tomahawk.a index 2128ed9..6d914a2 100755 --- a/src/prelaunch/tomahawk.a +++ b/src/prelaunch/tomahawk.a @@ -2,7 +2,7 @@ ;(c) 2019 by qkumba/Frank M. !cpu 6502 -!to "build/PRELAUNCH/TOMAHAWK",plain +!to "build/PRELAUNCH.INDEXED/TOMAHAWK",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/winter.games.a b/src/prelaunch/winter.games.a index 63b3ae0..11969eb 100755 --- a/src/prelaunch/winter.games.a +++ b/src/prelaunch/winter.games.a @@ -2,7 +2,7 @@ ;(c) 2020 by Frank M. !cpu 6502 -!to "build/PRELAUNCH/WINTER.GAMES",plain +!to "build/PRELAUNCH.INDEXED/WINTER.GAMES",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/world.games.a b/src/prelaunch/world.games.a index 5a11bed..3df3905 100644 --- a/src/prelaunch/world.games.a +++ b/src/prelaunch/world.games.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba/Frank M. !cpu 6502 -!to "build/PRELAUNCH/WORLD.GAMES",plain +!to "build/PRELAUNCH.INDEXED/WORLD.GAMES",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/prelaunch/world.karate.a b/src/prelaunch/world.karate.a index 8f9fbf2..1f533e1 100644 --- a/src/prelaunch/world.karate.a +++ b/src/prelaunch/world.karate.a @@ -2,7 +2,7 @@ ;(c) 2020 by qkumba !cpu 6502 -!to "build/PRELAUNCH/WORLD.KARATE",plain +!to "build/PRELAUNCH.INDEXED/WORLD.KARATE",plain *=$106 !source "src/prelaunch/common.a" diff --git a/src/proboothd/proboothd.a b/src/proboothd/proboothd.a index 7ccd4b3..9a19a6c 100644 --- a/src/proboothd/proboothd.a +++ b/src/proboothd/proboothd.a @@ -5,147 +5,203 @@ !to "build/proboothd",plain *=$800 - ;zpage usage, arbitrary selection except for the "ProDOS constant" ones - command = $42 ;ProDOS constant - unit = $43 ;ProDOS constant - adrlo = $44 ;ProDOS constant - adrhi = $45 ;ProDOS constant - bloklo = $46 ;ProDOS constant - blokhi = $47 ;ProDOS constant + ;zpage usage, arbitrary selection except for the "ProDOS constant" ones + command = $42 ;ProDOS constant + unit = $43 ;ProDOS constant + adrlo = $44 ;ProDOS constant + adrhi = $45 ;ProDOS constant + bloklo = $46 ;ProDOS constant + blokhi = $47 ;ProDOS constant - A2L = $3e - A2H = $3f - sizehi = $53 + A2L = $3e + A2H = $3f + sizehi = $53 - ;constants - scrn2p2 = $f87b - dirbuf = $1e00 ;for size-optimisation + ;constants + scrn2p2 = $f87b + dirbuf = $1e00 ;for size-optimisation - !byte 1 - stx unit - ldy #0 ;Yellowstone support -- txa - jsr scrn2p2 - and #7 - ora #$c0 - sta $be30, y - sta slot+2 - sta entry+2 -slot lda $cfff - sta entry+1 + !byte 1 + txa + pha - lda fakeMLI_e-$100, y - sta $be00+fakeMLI_e-fakeMLI, y - iny - bne - - sty adrlo - stx $bf30 - sty $200 + ; put machine in a known state, clear screen + + cld + bit $c082 + sta $c00e + sta $c00c + sta $c000 + sta $c002 + sta $c004 + jsr $fb2f + jsr $fc58 + jsr $fe84 + jsr $fe89 + jsr $fe93 + + ; print title + lda $fbb3 + cmp #$A0 + beq + ; Spectrum ED + cmp #$06 + beq + + lda #$DF + sta @mask+1 ++ ldy #15 +- lda II-1,y + cmp #$E1 + bcc + +@mask and #$FF ; SMC ++ sta $070C-1,y + dey + bne - + ldy #13 +- lda INSTANT-1,y + sta $04B5-1,y + lda REPLAY-1,y + sta $0535-1,y + dey + bne - + + pla + sta unit + tax + ; X = boot slot x16 + ; Y = 0 + + ; set up ProDOS shim + +- txa + jsr scrn2p2 + and #7 + ora #$c0 + sta $be30, y + sta slot+2 + sta entry+2 +slot lda $cfff + sta entry+1 + lda fakeMLI_e-$100, y + sta $be00+fakeMLI_e-fakeMLI, y + iny + bne - + sty adrlo + stx $bf30 + sty $200 opendir ;read volume directory key block - ldx #2 + ldx #2 - ;include volume directory header in count + ;include volume directory header in count -firstent lda #>dirbuf - sta adrhi - sta A2H - jsr seekread - lda #4 - sta A2L -nextent ldy #0 +firstent lda #>dirbuf + sta adrhi + sta A2H + jsr seekread + lda #4 + sta A2L +nextent ldy #0 - ;match name lengths before attempting to match names + ;match name lengths before attempting to match names - lda (A2L), y - and #$0f - tax - inx -- cmp filename, y - beq foundname + lda (A2L), y + and #$0f + tax + inx +- cmp filename, y + beq foundname - ;move to next directory in this block + ;move to next directory in this block - clc - lda A2L - adc #$27 - sta A2L - bcc + + clc + lda A2L + adc #$27 + sta A2L + bcc + - ;there can be only one page crossed, so we can increment instead of adc + ;there can be only one page crossed, so we can increment instead of adc - inc A2H -+ cmp #$ff ;4+($27*$0d) - bne nextent + inc A2H ++ cmp #$ff ;4+($27*$0d) + bne nextent - ;read next directory block when we reach the end of this block + ;read next directory block when we reach the end of this block - ldx dirbuf+2 - ldy dirbuf+3 - bcs firstent + ldx dirbuf+2 + ldy dirbuf+3 + bcs firstent -foundname iny - lda (A2L), y - dex - bne - - stx $ff +foundname + iny + lda (A2L), y + dex + bne - + stx $ff - ;cache KEY_POINTER + ;cache KEY_POINTER - ldy #$11 - lda (A2L), y - tax - iny - lda (A2L), y - tay - -readfile jsr seekread - inc adrhi - inc adrhi + ldy #$11 + lda (A2L), y + tax + iny + lda (A2L), y + tay - ;fetch data block and read it +readfile jsr seekread + inc adrhi + inc adrhi -blockind ldy $ff - inc $ff - ldx dirbuf, y - lda dirbuf+256, y - tay - bne readfile - txa - bne readfile + ;fetch data block and read it -readdone jmp $2000 +blockind ldy $ff + inc $ff + ldx dirbuf, y + lda dirbuf+256, y + tay + bne readfile + txa + bne readfile -seekread stx bloklo - sty blokhi - lda #1 - sta command - lda adrhi - pha -entry jsr $d1d1 - pla - sta adrhi - rts +readdone jmp $2060 -fakeMLI bne retcall -readblk dey - dey - sty adrhi - tay - jsr $bf00+seekread-fakeMLI -retcall pla - tax - inx - inx - inx - txa - pha - rts +seekread stx bloklo + sty blokhi + lda #1 + sta command + lda adrhi + pha +entry jsr $d1d1 + pla + sta adrhi + rts + +fakeMLI bne retcall +readblk dey + dey + sty adrhi + tay + jsr $bf00+seekread-fakeMLI +retcall pla + tax + inx + inx + inx + txa + pha +- rts fakeMLI_e -filename !byte filename_e - filename_b -filename_b !text "LAUNCHER.SYSTEM" ;your start-up file, file is max 40kb +filename + !byte filename_e - filename_b +filename_b + !text "LAUNCHER.SYSTEM" ;your start-up file, file is max 40kb filename_e +II + !byte $D4,$EF,$F4,$E1,$EC,$A0,$D2,$E5,$F0,$EC,$E1,$F9,$A0,$C9,$C9 +INSTANT + !byte $C9,$A0,$CE,$A0,$D3,$A0,$D4,$A0,$C1,$A0,$CE,$A0,$D4 +REPLAY + !byte $A0,$D2,$A0,$C5,$A0,$D0,$A0,$CC,$A0,$C1,$A0,$D9,$A0 *=$9f8 !byte $D3,$C1,$CE,$A0,$C9,$CE,$C3,$AE diff --git a/src/prodos.impl.lc2.a b/src/prodos.impl.lc2.a index 5237fcd..870eb88 100644 --- a/src/prodos.impl.lc2.a +++ b/src/prodos.impl.lc2.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2019-2020 by 4am & qkumba +;(c) 2019-2022 by 4am & qkumba ; ; Pseudo-ProDOS environment ; @@ -18,16 +18,10 @@ ipacket = first_zp ;word buffer = first_zp+2 ;word -!if RELBASE != $2000 { - !ifdef PASS2 { - } else { ;PASS2 - !if * != iProDOS_enter { - !error "iProDOS_enter=",*, ", fix constants.a" - } - } -} ProDOS_enter !set CloseHandles = @imp_close +!set swap_zpg = @swap_zp +!set SavedZP = @saved_zp stx ProDOS_savedX+1 sty ProDOS_savedY+1 jsr @swap_zp @@ -224,42 +218,44 @@ ProDOS_enter resetval=$f0 @imp_seek jsr @set_rdwrbuff - ldx #0 - stx blkidx - stx blkofflo - stx blkoffhi - stx reqcmd jsr @reset - ldx sizelo - bne @seek64 - cmp ldrhi - bcc @seek64 - bne @seek32 - ldx ldrlo - beq @seek32 - -@seek64 - sta sizehi - sta sizelo - jsr @seekreset + lda sizelo + lsr + tay lda ldrhi - sbc #resetval - sta ldrhi + ror + sta blkidx + ldx istree + beq @sametree + tax + beq @skiptree + iny + cpy treeidx -@seek32 - lda ldrhi - sta sizehi +@skiptree + sty treeidx + beq @sametree + ldx hddtreebuf - 1, y + lda hddtreebuf + 255, y + jsr hddreaddirsel + +@sametree + jsr @close_reset lda ldrlo sta sizelo - jsr @seekreset lda ldrhi - ora ldrlo - bne @jmp_zp - dec blkidx + and #1 + sta sizehi + ora sizelo + beq @link_jmpzp + jsr @seekreset + @link_jmpzp - beq @jmp_zp ;always + jmp @restore_zp @seekreset + lda #cmdseek + sta reqcmd jsr hddrdwrpart @reset lda #resetval @@ -306,7 +302,7 @@ resetval=$f0 lda @handles+1 beq @close_ret dec @handles+1 - bne @close_ret + bne @close_reset lda #>hddencbuf @patch_buffer @@ -323,12 +319,24 @@ resetval=$f0 stx dirbufpatch7+2 stx dirbufpatch9+2 stx dirbufpatch10+1 + stx dirbufpatch11+1 inx stx dirbufpatch5+2 stx dirbufpatch8+2 + inx + stx treebufpatch1+1 + stx treebufpatch2+2 + inx + stx treebufpatch3+2 @close_ret rts +@close_reset + lda #0 + sta blkofflo + sta blkoffhi + rts + @fetchbyte inc @fetchaddr+1 bne @fetchaddr @@ -391,6 +399,13 @@ resetval=$f0 @saved_zp !fill (last_zp - first_zp) + 1 +resetRoot +gRootDirectory + +LDADDR 0 ; SMC + sta (reloc + unrhddblocklo - unrelochdd) + 1 + sty (reloc + unrhddblockhi - unrelochdd) + 1 + rts + ;------------------------------------------------------------------------------ ; traverse [private] ; @@ -401,15 +416,11 @@ resetval=$f0 !ifdef PASS2 { } else { ;PASS2 !if * != itraverse { - !error "itraverse=",*, ", fix constants.a" + !error "itraverse=",*, ", fix constants.a, rebuild prelaunch" } } traverse - +LD16 gRootDirectory - sta (reloc + unrhddblocklo - unrelochdd) + 1 - sty (reloc + unrhddblockhi - unrelochdd) + 1 - sta @myreadblock+1 - sty @myreadblock+3 ; reset 'root' directory (saved at program start) + jsr resetRoot ;search for '/' character in filename @@ -419,71 +430,33 @@ traverse tay - inx dey - bmi @go ; no '/', just do the read + beq @go ; no '/', just do the read lda (namlo), y cmp #'/' bne - sty sizelo txa pha + lda #$B1 ; LDA (), y + sta pathpatch1 + lda #$68 ; PLA + sta pathpatch2 + lda #$60 ; RTS + sta pathpatch2 + 1 @myreadblock -@myx80_parms - ldx #2 - lda #0 - jsr hddreaddirsel - lda #NAME_LENGTH - sta bloklo - lda #>(hdddirbuf - 1) - sta blokhi - - ;there can be only one page crossed, so we can increment here - -@mynextent1 - inc blokhi -@mynextent - ldy #0 - lda (bloklo), y - pha - and #$0f - tax --- iny - lda (bloklo), y - cmp (namlo), y - beq @myfoundname - - ;match failed, move to next directory in this block, if possible - -- pla - -@myskiphdr - clc - lda bloklo - adc #ENTRY_SIZE - sta bloklo - bcs @mynextent1 - cmp #$ff ;4 + ($27 * $0d) - bne @mynextent - - ;read next directory block when we reach the end of this block - - lda hdddirbuf + NEXT_BLOCK_LO - ldx hdddirbuf + NEXT_BLOCK_HI - bcs + - -@myfoundname - dex - bne -- + jsr hddopendir +- tax ;parse path until last directory is seen - iny lda (namlo), y cmp #'/' - bne - - pla - and #$20 ;Volume Directory Header XOR subdirectory - bne @myskiphdr + beq + +-- jsr pathresume + bne - ; always taken ++ txa + bmi -- tya eor #$ff adc sizelo @@ -492,23 +465,31 @@ traverse tya adc namlo sta namlo + bcc + + inc namhi ++ ;cache block number of current directory ;as starting position for subsequent searches ldy #(KEY_POINTER + 1) - lda (bloklo), y + lda (scratchlo), y tax dey - lda (bloklo), y + lda (scratchlo), y sta (reloc + unrhddblocklo - unrelochdd) + 1 stx (reloc + unrhddblockhi - unrelochdd) + 1 -+ sta @myx80_parms + 1 - stx @myx80_parms + 3 -++ lda sizelo + lda sizelo bne @myreadblock tay + lda #$D1 ; CMP (), y + sta pathpatch1 + lda #$86 ; STX + sta pathpatch2 + lda #$5A + sta pathpatch2 + 1 + pla sta (namlo), y @go diff --git a/src/prodos.path.a b/src/prodos.path.a index 09bf9a7..d215200 100644 --- a/src/prodos.path.a +++ b/src/prodos.path.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am ; ; ProDOS - functions for constructing and passing around ProDOS pathnames ; @@ -24,14 +24,7 @@ kRootDirectory=*+1 ldx #0 stx gPathname ; execution falls through here -!if RELBASE != $2000 { - !ifdef PASS2 { - } else { ;PASS2 - !if * != iAddToPath { - !error "iAddToPath=",*, ", fix constants.a" - } - } -} + AddToPath +ST16 PTR ldy #0 @@ -53,42 +46,117 @@ AddToPath @done rts -kHGRTitleDirectory - !byte 10 - !raw "TITLE.HGR/" +kSearchIndexRecord + !byte 0 + !be24 0 ; SMC in 4cade.init + !le16 0 ; SMC in 4cade.init -kDHGRTitleDirectory - !byte 11 - !raw "TITLE.DHGR/" +kSearchCacheRecord + !byte 0 + !be24 0 ; SMC in 4cade.init + !le16 0 ; SMC in 4cade.init + +kPrelaunchIndexRecord + !source "src/index/prelaunch.idx.a" + +kAttractModeIndexRecord + !source "src/index/attract.idx.a" + +kMiniAttractIndexLo + !byte kMiniAttractIndexRecord0 + !byte >kMiniAttractIndexRecord1 +kMiniAttractIndexRecord0 + !source "src/index/miniattract0.idx.a" +kMiniAttractIndexRecord1 + !source "src/index/miniattract1.idx.a" + +kAttractModeSlideshowIndexRecord + !source "src/index/slideshow.idx.a" + +kFXIndexRecord + !source "src/index/fx.idx.a" + +kDFXIndexRecord + !source "src/index/dfx.idx.a" + +kSFXIndexRecord + !source "src/index/sfx.idx.a" + +kGameHelpIndexRecord + !source "src/index/gamehelp.idx.a" + +kHGRTitleIndexRecord + !source "src/index/title.idx.a" + +kDHGRTitleIndexRecord + !source "src/index/dtitle.idx.a" + +kSHRArtworkIndexRecord + !source "src/index/artwork.idx.a" + +kDHGRActionIndexRecord + !source "src/index/dhgr.idx.a" + +kGRActionIndexRecord + !source "src/index/gr.idx.a" + +kDGRActionIndexRecord + !source "src/index/dgr.idx.a" + +kHGRActionIndexLo + !byte kHGRActionIndexRecord0 + !byte >kHGRActionIndexRecord1 + !byte >kHGRActionIndexRecord2 + !byte >kHGRActionIndexRecord3 + !byte >kHGRActionIndexRecord4 + !byte >kHGRActionIndexRecord5 + !byte >kHGRActionIndexRecord6 +kHGRActionIndexRecord0 + !source "src/index/hgr0.idx.a" +kHGRActionIndexRecord1 + !source "src/index/hgr1.idx.a" +kHGRActionIndexRecord2 + !source "src/index/hgr2.idx.a" +kHGRActionIndexRecord3 + !source "src/index/hgr3.idx.a" +kHGRActionIndexRecord4 + !source "src/index/hgr4.idx.a" +kHGRActionIndexRecord5 + !source "src/index/hgr5.idx.a" +kHGRActionIndexRecord6 + !source "src/index/hgr6.idx.a" + +kCreditsRecord + !source "src/index/credits.idx.a" + +kHelpTextRecord + !source "src/index/helptext.idx.a" + +kDecrunchRecord + !source "src/index/decrunch.idx.a" + +kJoystickRecord + !source "src/index/joystick.idx.a" + +kTotalDataFile + !byte 10 + !raw "TOTAL.DATA" kAnimatedTitleDirectory !byte 15 !raw "TITLE.ANIMATED/" -kHGRActionDirectory - !byte 11 - !raw "ACTION.HGR/" - -kDHGRActionDirectory - !byte 12 - !raw "ACTION.DHGR/" - -kGRActionDirectory - !byte 10 - !raw "ACTION.GR/" - -kSHRArtworkDirectory - !byte 12 - !raw "ARTWORK.SHR/" - -kMiniAttractDirectory - !byte 8 - !raw "ATTRACT/" - -kAttractModeSlideshowDirectory - !byte 3 - !raw "SS/" - kDemoDirectory !byte 5 !raw "DEMO/" @@ -102,70 +170,27 @@ kFXDirectory !byte 3 !raw "FX/" -kPrelaunchDirectory - !byte 10 - !raw "PRELAUNCH/" - -kGameHelpDirectory - !byte 9 - !raw "GAMEHELP/" - -kStandardPrelaunch - !byte 8 - !raw "STANDARD" - kGlobalPrefsFilename !byte 10 !raw "PREFS.CONF" -kAttractModeConfFile - !byte 12 - !raw "ATTRACT.CONF" +kStandardPrelaunchRecord + !source "src/index/standard.prelaunch.a" -kFXConfFile - !byte 7 - !raw "FX.CONF" +kCoverFadeRecord + !source "src/index/coverfade.idx.a" -kDFXConfFile - !byte 8 - !raw "DFX.CONF" +kGRFizzleRecord + !source "src/index/gr.fizzle.idx.a" -kCreditsFile - !byte 7 - !raw "CREDITS" +kDGRFizzleRecord + !source "src/index/dgr.fizzle.idx.a" -kHelpBackgroundFile - !byte 4 - !raw "HELP" +kHelpBackgroundRecord + !source "src/index/res.help.idx.a" -kHelpTextFile - !byte 8 - !raw "HELPTEXT" +kTitleRecord + !source "src/index/res.title.idx.a" -kTitleFile - !byte 5 - !raw "TITLE" - -kCoverFile - !byte 5 - !raw "COVER" - -kCoverFadeFile - !byte 9 - !raw "COVERFADE" - -kGRFizzleFile - !byte 9 - !raw "GR.FIZZLE" - -kSFXFizzleFile - !byte 10 - !raw "SHR.FIZZLE" - -kDecrunchFile - !byte 8 - !raw "DECRUNCH" - -kJoystickFile - !byte 8 - !raw "JOYSTICK" +kCoverRecord + !source "src/index/res.cover.idx.a" diff --git a/src/prorwts2.a b/src/prorwts2.a index e8f3bce..10405a0 100644 --- a/src/prorwts2.a +++ b/src/prorwts2.a @@ -1,6 +1,7 @@ ;license:BSD-3-Clause ;extended open/read/write binary file in ProDOS filesystem, with random access -;copyright (c) Peter Ferrie 2013-2020 +;copyright (c) Peter Ferrie 2013-2021 +;assemble using ACME ver_02 = 1 @@ -21,6 +22,8 @@ ver_02 = 1 aligned_read = 0 ;set to 1 if all reads can be a multiple of block size enable_readseq=0 ;set to 1 to enable reading multiple sequential times from the same file without seek ;(exposes a fixed address that can be called for either floppy or hard disk support) + ;requires fast_subindex + ;can also be used for sequential writes, but size must be 512-aligned enable_write = 1 ;set to 1 to enable write support ;file must exist already and its size cannot be altered ;writes occur in multiples of block size @@ -34,22 +37,24 @@ ver_02 = 1 might_exist = 0 ;set to 1 if file is not known to always exist already ;makes use of status to indicate success or failure many_files = 0 ;set to 1 to support more than 256 files in a directory + detect_wp = 0 ;detect write-protected floppy during writes allow_aux = 1 ;set to 1 to allow read/write directly to/from aux memory ;requires load_high to be set for arbitrary memory access ;else driver must be running from same memory target ;i.e. running from main if accessing main, running from aux if accessing aux allow_saplings=1 ;enable support for saplings - allow_trees = 0 ;enable support for tree files, as opposed to only seedlings and saplings + allow_trees = 1 ;enable support for tree files, as opposed to only seedlings and saplings ;required in RWTS mode if file > 128kb - fast_trees = 0 ;keep tree block in memory, requires an additional 512 bytes of RAM + fast_trees = 1 ;keep tree block in memory, requires an additional 512 bytes of RAM always_trees = 0 ;set to 1 if the only file access involves tree files ;not compatible with allow_subdir, allow_saplings ;required in RWTS mode if allow_trees is enabled detect_treof = 0 ;detect EOF during read of tree files - fast_subindex= 0 ;keep subindex block in memory, requires an additional 512 bytes of RAM + fast_subindex= 1 ;keep subindex block in memory, requires an additional 512 bytes of RAM ;halves the disk access for double the speed (ideal for RWTS mode) allow_sparse = 1 ;enable support for reading sparse files - ;recommended if enable_write is enabled, to prevent writing to sparse blocks + write_sparse = 0 ;enable support for writing to sparse files (blocks are allocated even if empty) + ;used only by RWTS mode, writing to sparse files in non-RWTS mode will corrupt the file! bounds_check = 1 ;set to 1 to prevent access beyond the end of the file ;but limits file size to 64k-2 bytes. return_size = 0 ;set to 1 to receive file size on open in read-only mode @@ -59,22 +64,26 @@ ver_02 = 1 swap_zp = 0 ;set to 1 to include code to preserve zpage ;used only by RWTS mode swap_scrn = 1 ;set to 1 to preserve screen hole contents across SmartPort calls - ;reading directly into screen memory that includes holes (either main or aux) is not recommended - ;because SCSI firmware writes there (i.e. whichever bank is active) on exit, which will damage read content ;recommended if allow_aux is used, to avoid device reset ;requires 64 bytes to save all holes + read_scrn = 0 ;set to 1 to support reading into screen memory + ;requires swap_scrn rwts_mode = 0 ;set to 1 to enable emulation of DOS RWTS when running from hard disk ;uses a one-time open of a tree file, no other file access allowed ;use unique volume numbers to distinguish between images in the same file ;requires override_adr, allow_trees, always_trees + ;or fast_subindex if file is smaller than a tree ;not compatible with enable_floppy, allow_subdir, might_exist, bounds_check mem_swap = 0 ;set to 1 if zpage can be swapped between main and aux, and swap_zp is unsuitable ;(caches index registers in code instead of zpage) + write_ffff = 0 ;set to 1 if there might be reads to $FFxx and allow_sparse=1 load_high = 0 ;set to 1 to load to top of RAM (either main or banked, enables a himem check) load_aux = 0 ;load to aux memory load_banked = 1 ;set to 1 to load into banked RAM instead of main RAM (can be combined with load_aux for aux banked) lc_bank = 2 ;load into specified bank (1 or 2) if load_banked=1 one_page = 0 ;set to 1 if verbose mode says that you should (smaller code) + two_pages = 0 ;default size + three_pages = 1 ;set to 1 if verbose mode says that you should (code is larger than two pages) ;user-defined driver load address !if load_banked = 1 { @@ -84,7 +93,7 @@ ver_02 = 1 reloc = $fe00 ;page-aligned, as high as possible, the ideal value will be shown on mismatch } ;PASS2 } else { ;load_high = 0 - reloc = $d400 ;page-aligned, but otherwise wherever you want + reloc = $d600 ;page-aligned, but otherwise wherever you want } ;load_high = 1 } else { ;load_banked = 0 !if load_high = 1 { @@ -123,11 +132,11 @@ ver_02 = 1 ldrhi = $56 ;set to load address if override_adr=1 namlo = $57 ;name of file to access namhi = $58 ;name of file to access - ldrlo2 = $59 ;original load address read from filesystem - ldrhi2 = $5a ;original load address read from filesystem - sizelo2 = $5b ;original file size read from filesystem - sizehi2 = $5c ;original file size read from filesystem - !set last_zp = $5c ;highest address to save if swap_zp enabled (max 127 entries later) + !set last_zp = $58 ;highest address to save if swap_zp enabled (max 127 entries later) +!if write_sparse = 1 { + sparseblk = $59 ;(internal) last-read block was sparse if zero + !set last_zp = $59 ;highest address to save if swap_zp enabled (max 127 entries later) +} ;write_sparse = 1 !if enable_floppy = 1 { tmpsec = $3c ;(internal) sector number read from disk @@ -171,13 +180,13 @@ ver_02 = 1 lastblk = $5f ;(internal) previous index into sapling block list !set last_zp = $5f ;highest address to save if swap_zp enabled (max 127 entries later) } ;rwts_mode = 1 - !if (bounds_check + return_size + one_shot) > 0 { + !if ((bounds_check or return_size) > 0) and ((rwts_mode or one_shot) = 0) { bleftlo = $60 ;(internal) bytes left in file - } ;bounds_check = 1 or return_size = 1 or one_shot = 1 - !if (bounds_check + return_size + aligned_read + one_shot) > 0 { + } ;(bounds_check = 1 or return_size = 1) and (rwts_mode = 0 and one_shot = 0) + !if ((bounds_check or return_size or aligned_read) > 0) and ((rwts_mode or one_shot) = 0) { blefthi = $61 ;(internal) bytes left in file !set last_zp = $61 ;highest address to save if swap_zp enabled (max 127 entries later) - } ;bounds_check = 1 or return_size = 1 or aligned_read = 1 or one_shot = 1 + } ;(bounds_check = 1 or return_size = 1 or aligned_read = 1) and (rwts_mode and one_shot = 0) !if aligned_read = 0 { blkofflo = $62 ;(internal) offset within cache block blkoffhi = $63 ;(internal) offset within cache block @@ -185,6 +194,12 @@ ver_02 = 1 } ;aligned_read = 0 } ;mem_swap = 0 + ldrlo2 = $64 ;original load address read from filesystem + ldrhi2 = $65 ;original load address read from filesystem + sizelo2 = $66 ;original file size read from filesystem + sizehi2 = $67 ;original file size read from filesystem + !set last_zp = $67 ;highest address to save if swap_zp enabled (max 127 entries later) + !if enable_floppy = 1 { step = $64 ;(internal) state for stepper motor tmptrk = $65 ;(internal) temporary copy of current track @@ -200,6 +215,7 @@ ver_02 = 1 SETVID = $fe93 DEVNUM = $bf30 PHASEOFF = $c080 + PHASEON = $c081 MOTOROFF = $c088 MOTORON = $c089 DRV0EN = $c08a @@ -214,6 +230,7 @@ ver_02 = 1 KEY_POINTER = $11 ;ProDOS constant EOF_LO = $15 ;ProDOS constant EOF_HI = $16 ;ProDOS constant + EOF_HI2 = $17 ;ProDOS constant AUX_TYPE = $1f ;ProDOS constant ENTRY_SIZE = $27 ;ProDOS constant NEXT_BLOCK_LO = $2 ;ProDOS constant @@ -222,7 +239,7 @@ ver_02 = 1 FILE_COUNT = $25 ;ProDOS constant DEVADR01HI = $bf11 ;ProDOS constant ROMIN = $c081 - LCBANK2 = $c089 + LCBANK2 = $c08b CLRAUXRD = $c002 CLRAUXWR = $c004 SETAUXWR = $c005 @@ -249,40 +266,33 @@ init lda DEVNUM ora # 0 { + !if no_interrupts = 1 { sta unrdrvoff2 + 1 - } ;might_exist = 1 or poll_drive = 1 - !if (aligned_read + allow_aux) = 0 { - sta unrdrvoff3 + 1 - } ;aligned_read = 0 and allow_aux = 0 + } else { ;no_interrupts = 0 sta unrdrvoff4 + 1 + !if ((aligned_read xor 1) and one_shot) = 1 { + sta unrdrvoff5 + 1 + } ;aligned_read = 0 and one_shot = 1 + } ;no_interrupts = 1 + !if (might_exist + poll_drive) > 0 { + sta unrdrvoff3 + 1 + } ;might_exist = 1 or poll_drive = 1 tax inx ;MOTORON - !if allow_multi = 1 { stx unrdrvon1 + 1 - } ;allow_multi = 1 stx unrdrvon2 + 1 - !if aligned_read = 0 { - stx unrdrvon3 + 1 - } ;aligned_read = 0 - stx unrdrvon4 + 1 inx ;DRV0EN !if allow_multi = 1 { + stx unrdrvsel1 + 1 stx unrdrvsel2 + 1 + stx unrdrvsel3 + 1 } ;allow_multi = 1 inx - !if allow_multi = 1 { - stx unrdrvsel1 + 1 - } ;allow_multi = 1 inx ;Q6L stx unrread1 + 1 - !if (poll_drive + allow_multi) > 0 { stx unrread2 + 1 stx unrread3 + 1 - } ;poll_drive = 1 or allow_multi = 1 stx unrread4 + 1 stx unrread5 + 1 !if check_chksum = 1 { @@ -402,25 +412,24 @@ adjpath tya pla ;unit to slot for ProDOS interface + ;accept if slot code matches unit number +++ pla lsr lsr lsr tay - ldx DEVADR01HI, y - cpx #$c8 - bcc set_slot1 -!if use_smartport = 1 { - php -} ;use_smartport = 1 + lsr + ora #$c0 + tax + cmp DEVADR01HI, y + clc + beq set_slot + !if enable_floppy = 1 { ;check if current device is floppy - lsr - ora #$c0 - tax stx scratchhi ldy #0 sty scratchlo @@ -443,10 +452,14 @@ adjpath tya not_floppy } ;enable_floppy = 1 - - ;find SmartPort device for basic MicroDrive support - ldx #$c8 + + ;find SmartPort device for basic MicroDrive, BOOTi support + ;the BOOTi can load floppy .po images via the SmartPort interface + ;but the virtual slot behaviour differs slightly from regular ProDOS + ;so we scan for the SmartPort interface in all cases + +iterdevice - dex stx scratchhi ldy #0 @@ -468,10 +481,7 @@ not_floppy lda (scratchlo), y beq - -!if use_smartport = 1 { -set_slot plp -} ;use_smartport = 1 -set_slot1 stx slot + 2 +set_slot stx slot + 2 stx unrentry + 2 slot ldx $cfff stx unrentry + 1 @@ -481,15 +491,20 @@ slot ldx $cfff !if use_smartport = 1 { !if enable_floppy = 1 { beq + - } ;enable_floppy = 1 bcs ++ + jmp bankram +++ + } else { ;enable_floppy = 0 + bcs + + jmp bankram ++ + } ;enable_floppy = 1 -++ lda #$8c ;STY + ldy #$8c ;STY !if (rwts_mode + enable_write) > 1 { - sta unrcommand1 + sty unrcommand1 } ;rwts_mode = 1 and enable_write = 1 - sta unrcommand3 + sty unrcommand3 lda # 1 { sta unrcommand1 + 1 @@ -506,31 +521,62 @@ slot ldx $cfff sta unrcommand2 + 2 } ;rwts_mode = 0 and aligned_read = 0 and enable_write = 1 sta unrcommand3 + 2 - lda #$8e ;STX + sta unrgetreq + 2 + iny ;STA + sty unrblokhi1 + sty unrunit1 + 2 + iny ;STX !if (rwts_mode + aligned_read + (enable_write xor 1)) = 0 { - sta unrcommand2 + sty unrcommand2 } ;rwts_mode = 0 and aligned_read = 0 and enable_write = 1 - sta unrbloklo - lda #pblock - sta unrbloklo + 2 - lda #$8d ;STA - sta unrblokhi - lda #<(pblock + 1) - sta unrblokhi + 1 - lda #>(pblock + 1) - sta unrblokhi + 2 + sty unrbloklo1 + ;;lda #>pblock + ;;pblock_enabled=1 + sta unrbloklo1 + 2 + !if (rwts_mode + write_sparse) > 1 { + sta unrbloklo2 + 2 + } ;rwts_mode = 1 and write_sparse = 1 + ;;lda #>(pblock + 1) + ;;pblock1_enabled=1 + sta unrblokhi1 + 2 + !if (rwts_mode + write_sparse) > 1 { + sta unrblokhi2 + 2 + sta unrblokhi3 + 2 + } ;rwts_mode = 1 and write_sparse = 1 + ;;lda #>paddr + sta unrunit1 + 4 + ldy # 1 { + sty unrbloklo2 + 1 + } ;rwts_mode = 1 and write_sparse = 1 + iny + sty unrblokhi1 + 1 + !if (rwts_mode + write_sparse) > 1 { + sty unrblokhi2 + 1 + sty unrblokhi3 + 1 + } ;rwts_mode = 1 and write_sparse = 1 lda #$a5 ;LDA sta unrunit1 + !if (rwts_mode + write_sparse) > 1 { + lda #$ee ;INC + sta unrblokhi2 + ldy #$ad ;LDA + sty unrblokhi3 + sty unrgetreq + iny ;LDX + sty unrbloklo2 + } ;rwts_mode = 1 and write_sparse = 1 lda #adrlo sta unrunit1 + 1 - lda #$8d ;STA - sta unrunit1 + 2 lda #paddr - sta unrunit1 + 4 + !if (rwts_mode and write_sparse) = 0 { + lda #$ad ;LDA + sta unrgetreq + } ;if rwts_mode = 0 or write_sparse = 0 + lda #unrelocdsk ldy #((codeend - rdwrpart) + $ff) ldy #0 + !if (load_aux and (load_banked xor 1)) = 1 { + sta SETAUXWR + } ;load_aux = 1 and load_banked = 0 - lda (scratchlo), y + !if (load_aux + load_banked) > 1 { + sta SETAUXZP + } ;load_aux = 1 and load_banked = 1 reladr sta reloc, y + !if (load_aux + load_banked) > 1 { + sta CLRAUXZP + } ;load_aux = 1 and load_banked = 1 iny bne - inc scratchhi + !if (load_aux and (load_banked xor 1)) = 1 { + sta CLRAUXWR + } ;load_aux = 1 and load_banked = 0 inc reladr + 2 + !if (load_aux and (load_banked xor 1)) = 1 { + sta SETAUXWR + } ;load_aux = 1 and load_banked = 0 dex bne - plp + !if (load_aux + load_banked) > 1 { + sta SETAUXZP + } ;load_aux = 1 and load_banked = 1 + !if swap_scrn = 1 { + beq + + jsr saveslot + lda #$91 + sta initpatch + } ;swap_scrn = 1 bne ++ ++ ;build 6-and-2 denibbilisation table @@ -633,46 +703,83 @@ unrdrvon1 lda MOTORON sta trackd1 !if allow_multi = 1 { -unrdrvsel1 lda DRV0EN + 1 + lda unrunit1 + 1 + asl + lda #0 + rol + sta driveind + 1 + pha + eor #1 + tay +unrdrvsel1 lda DRV0EN, y jsr spinup jsr poll - bcs + - lda #$c8 ;iny - sta twodrives - inc driveind + 1 - jsr readadr - lda curtrk - sta trackd2 -+ + beq + + inc twodrives + 1 + lda #0 + sta phase + ldx #$22 + jsr seek ++ pla + tay +unrdrvsel2 lda DRV0EN, y } ;allow_multi = 1 unrdrvoff1 lda MOTOROFF ++ } else { ;enable_floppy = 0 + !ifdef PASS2 { + !if >(hddcodeend - reloc) > 0 { + !if one_page = 1 { + !error "one_page must be 0" + } ;one_page = 0 + !if >(hddcodeend - reloc) > 1 { + !if three_pages = 0 { + !error "three_pages must be 1" + } ;three_pages = 0 + } ;hddcodeend + } ;hddcodeend + } ;PASS2 + !if three_pages = 1 { + ldx #>(hddcodeend + $ff - reloc) + } ;three_pages = 1 ldy #0 + !if load_aux = 1 { + sta SETAUXWR + (load_banked * 4) ;SETAUXWR or SETAUXZP + } ;load_aux = 1 +multicopy - lda unrelochdd, y sta reloc, y - !if one_page = 0 { - ;hack to avoid address overflow when load_high and load_banked - ;and code is less than two pages long (e.g. aligned_read, no write) - ;can't insert code during pass two because it breaks existing offsets - + !if three_pages = 0 { + !if two_pages = 1 { lda unrelochdd + $100, y sta reloc + $100, y - lda unrelochdd + $200, y - sta reloc + $200, y - } ;one_page = 0 + } ;two_pages = 1 + } ;three_pages = 0 iny bne - -} ;enable_floppy = 1 -!if swap_scrn = 1 { + !if three_pages = 1 { + !if (load_aux and (load_banked xor 1)) = 1 { + sta CLRAUXWR + } ;load_aux = 1 and load_banked = 0 + inc multicopy + 2 + inc multicopy + 5 + !if (load_aux and (load_banked xor 1)) = 1 { + sta SETAUXWR + } ;load_aux = 1 and load_banked = 0 + dex + bne multicopy + } ;three_pages = 1 + !if (fast_subindex + swap_zp) > 1 { + sty zp_array + adrlo - first_zp + } ;fast_subindex = 1 and swap_zp = 1 + + !if swap_scrn = 1 { jsr saveslot lda #$91 sta initpatch -} ;swap_scrn = 1 -!if load_aux = 1 { - sta CLRAUXWR + (load_banked * 4) ;CLRAUXWR or CLRAUXZP -} ;load_aux = 1 + } ;swap_scrn = 1 +} ;enable_floppy = 1 !if rwts_mode = 1 { ;read volume directory key block @@ -741,12 +848,12 @@ hddfoundname iny sty zp_array + lastblk - first_zp ;guarantee no match } ;swap_zp = 0 or mem_swap = 1 - !if allow_trees = 1 { + !if (allow_trees + fast_subindex) > 0 { ;fetch KEY_POINTER ldy #KEY_POINTER lda (scratchlo), y - !if fast_trees = 0 { + !if (fast_trees + fast_subindex) = 0 { !if ((swap_zp xor 1) + mem_swap) > 0 { sta treeblklo } else { ;swap_zp = 1 and mem_swap = 0 @@ -754,20 +861,22 @@ hddfoundname iny } ;swap_zp = 0 or mem_swap = 1 } else { ;fast_trees = 1 tax - } ;fast_trees = 0 + } ;fast_trees = 0 and fast_subindex = 0 iny lda (scratchlo), y - !if fast_trees = 0 { + !if (fast_trees + fast_subindex) = 0 { !if ((swap_zp xor 1) + mem_swap) > 0 { sta treeblkhi } else { ;swap_zp = 1 and mem_swap = 0 sta zp_array + treeblkhi - first_zp } ;swap_zp = 0 or mem_swap = 1 } else { ;fast_trees = 1 + !if fast_trees = 1 { ldy #>hddtreebuf + } ;fast_trees = 1; jsr hddreaddirsect - } ;fast_trees = 0 - } ;allow_trees = 1 + } ;fast_trees = 0 and fast_subindex = 0 + } ;allow_trees = 1 or fast_subindex = 1 lda #>iob ldy #(dirbuf - 1) - sta scratchhi - +readdir + !if allow_subdir = 1 { + jsr prepdrive + } ;allow_subdir = 1 !if might_exist = 1 { lda dirbuf + FILE_COUNT ;assuming only 256 files per subdirectory sta entries @@ -847,14 +964,18 @@ firstent sta scratchlo } ;many_files = 1 } ;might_exist = 1 + lda #NAME_LENGTH + ENTRY_SIZE +firstent sta scratchlo + lda #>(dirbuf - 1) + sta scratchhi + ;there can be only one page crossed, so we can increment here nextent1 inc scratchhi nextent ldy #0 - !if (might_exist + allow_subdir + allow_saplings + (always_trees xor 1)) > 0 { + !if (might_exist + allow_subdir + allow_saplings + (allow_trees xor always_trees)) > 0 { lda (scratchlo), y !if might_exist = 1 { - sty status ;skip deleted entries without counting @@ -862,7 +983,7 @@ nextent ldy #0 beq + } ;might_exist = 1 - !if (allow_subdir + allow_saplings + (always_trees xor 1)) > 0 { + !if (allow_subdir + allow_saplings + (allow_trees xor always_trees)) > 0 { ;remember type ;now bits 5-4 are represented by carry (subdirectory), sign (sapling) @@ -877,8 +998,8 @@ nextent ldy #0 bit treeidx } ;allow_trees = 1 php - } ;allow_subdir = 1 or allow_saplings = 1 or always_trees = 0 - } ;might_exist = 1 or allow_subdir = 1 or allow_saplings = 1 or always_trees = 0 + } ;allow_subdir = 1 or allow_saplings = 1 or (allow_trees = 1 and always_trees = 0) + } ;might_exist = 1 or allow_subdir = 1 or allow_saplings = 1 or (allows_trees = 1 and always_trees = 0) ;match name lengths before attempting to match names @@ -891,9 +1012,9 @@ nextent ldy #0 ;match failed, check if any directory entries remain - !if (allow_subdir + allow_saplings + (always_trees xor 1)) > 0 { + !if (allow_subdir + allow_saplings + (allow_trees xor always_trees)) > 0 { plp - } ;allow_subdir = 1 or allow_saplings = 1 or always_trees = 0 + } ;allow_subdir = 1 or allow_saplings = 1 or (allow_trees = 1 and always_trees = 0) !if might_exist = 1 { dec entries bne + @@ -903,10 +1024,14 @@ nextent ldy #0 } ;many_files = 1 } ;might_exist = 1 !if (might_exist + poll_drive) > 0 { -nodisk -unrdrvoff2 = unrelocdsk + (* - reloc) +nodisk inc status + !if detect_err = 1 { + sec + } ;detect_err = 1 + !if no_interrupts = 0 { +unrdrvoff3 = unrelocdsk + (* - reloc) lda MOTOROFF - inc status + } ;no_interrupts = 0 rts } ;might_exist = 1 or poll_drive = 1 @@ -954,7 +1079,9 @@ foundname iny !if aligned_read = 0 { ldy reqcmd cpy #cmdwrite ;control carry instead of zero + !if one_shot = 0 { bne + + } ;one_shot = 0 } ;aligned_read = 0 !if one_shot = 0 { @@ -1032,24 +1159,37 @@ foundname iny } ;one_shot = 0 } ;enable_write = 1 or aligned_read = 1 } ;bounds_check = 1 or return_size = 1 or one_shot = 1 + ;cache AUX_TYPE (load offset for binary files) !if override_adr = 0 { ldy #AUX_TYPE - jsr fetchscratch - stx ldrlo + lda (scratchlo), y + !if (allow_subdir + allow_saplings + allow_trees + (aligned_read xor 1)) > 0 { + sta ldrlo + iny + lda (scratchlo), y sta ldrhi + } else { ;allow_subdir = 0 and allow_saplings = 0 and allow_trees = 0 and aligned_read = 1 + pha + iny + lda (scratchlo), y + pha + } ;allow_subdir = 1 or allow_saplings = 1 or allow_trees = 1 or aligned_read = 0 } ;override_adr = 0 ;cache KEY_POINTER ldy #KEY_POINTER - jsr fetchscratch + lda (scratchlo), y + tax !if (allow_subdir + allow_saplings + allow_trees) > 0 { - stx dirbuf + sta dirbuf !if (allow_trees + (fast_trees xor 1)) > 1 { - stx treeblklo + sta treeblklo } ;allow_trees = 1 and fast_trees = 0 + iny + lda (scratchlo), y sta dirbuf + 256 !if (allow_trees + (fast_trees xor 1)) > 1 { sta treeblkhi @@ -1093,8 +1233,6 @@ foundname iny jmp rdwrfilei rdwrfile -unrdrvon2 = unrelocdsk + (* - reloc) - lda MOTORON !if allow_subdir = 1 { clc } ;allow_subdir = 1 @@ -1113,10 +1251,14 @@ unrdrvon2 = unrelocdsk + (* - reloc) pha } ;detect_err = 1 plp +unrdrvoff3 = unrelocdsk + (* - reloc) + lda MOTOROFF rts + } ;no_interrupts = 1 + jsr prepdrive + rdwrfilei !if (override_adr + allow_subdir + allow_saplings + allow_trees + (aligned_read xor 1)) > 0 { ;restore load offset @@ -1214,8 +1356,6 @@ copyblock ldy sizehi } ;enable_seek = 1 jsr copycache -unrdrvon3 = unrelocdsk + (* - reloc) - lda MOTORON ;copycache turns it off ;align to next block and resume read @@ -1244,11 +1384,9 @@ unrdrvon3 = unrelocdsk + (* - reloc) bne rdwrfilei } ;allow_subdir = 1 !if allow_aux = 0 { -unrdrvoff3 = unrelocdsk + (* - reloc) - lda MOTOROFF rts } else { ;allow_aux = 1 - beq rdwrdonedrv + beq rdwrdone } ;allow_aux = 0 } ;one_shot = 0 } else { ;aligned_read = 1 @@ -1326,9 +1464,6 @@ rdwrloop !if aligned_read = 0 { php } ;aligned_read = 0 - lda #>dirbuf - sta adrhi - sty adrlo ;fetch tree data block and read it @@ -1363,6 +1498,8 @@ noteof1 } ;detect_treof = 1 !if fast_trees = 0 { + lda #>dirbuf + sta adrhi jsr seekrd } else { ;fast_trees = 1 jsr readdirsel @@ -1414,16 +1551,8 @@ noteof2 !if allow_sparse = 1 { pha ora dirbuf, y - tay - pla - dey - iny ;don't affect carry - } ;allow_sparse = 1 - !if aligned_read = 0 { - php - } ;aligned_read = 0 - !if allow_sparse = 1 { beq issparse + pla } ;allow_sparse = 1 !if (aligned_read and (enable_write or enable_seek)) = 1 { ldy reqcmd @@ -1431,15 +1560,20 @@ noteof2 beq + } ;enable_seek = 1 } ;aligned_read = 1 and (enable_write = 1 or enable_seek = 1) + !if aligned_read = 0 { + php + } ;aligned_read = 0 !if enable_write = 1 { jsr seekrdwr } else { ;enable_write = 0 jsr seekrd } ;enable_write = 1 + !if aligned_read = 0 { + plp + } ;aligned_read = 0 resparse !if aligned_read = 0 { - plp + bcc + !if bounds_check = 1 { dec blefthi @@ -1450,14 +1584,15 @@ resparse dec sizehi bne rdwrloop -rdwrdonedrv -unrdrvoff4 = unrelocdsk + (* - reloc) - lda MOTOROFF !if aligned_read = 0 { lda sizelo bne rdwrloop } ;aligned_read = 0 rdwrdone + !if no_interrupts = 0 { +unrdrvoff4 = unrelocdsk + (* - reloc) + lda MOTOROFF + } ;no_interrupts = 0 !if allow_aux = 1 { ldx #0 setaux sta CLRAUXRD, x @@ -1466,7 +1601,8 @@ setaux sta CLRAUXRD, x rts !if allow_sparse = 1 { -issparse +issparse pla + tay - sta (adrlo), y iny bne - @@ -1474,8 +1610,12 @@ issparse - sta (adrlo), y iny bne - - dec adrhi + inc adrhi + !if write_ffff = 0 { bne resparse + } else { + jmp resparse + } ;write_ffff } ;allow_sparse = 1 !if aligned_read = 0 { @@ -1541,10 +1681,107 @@ copycache sta blkoffhi bcc rdwrdone ;always } else { ;one_shot = 1 + !if no_interrupts = 0 { +unrdrvoff5 = unrelocdsk + (* - reloc) + lda MOTOROFF + } ;no_interrupts = 0 rts } ;one_shot = 0 } ;aligned_read = 0 + ;no tricks here, just the regular stuff + +seek ldy #0 + sty step + asl phase + txa + asl + sta tmptrk + +copy_cur lda tmptrk + sta tmpsec + sec + sbc phase + beq +++ + bcs + + eor #$ff + inc tmptrk + bcc ++ ++ sbc #1 + dec tmptrk +++ cmp step + bcc + + lda step ++ cmp #8 + bcs + + tay + sec ++ jsr ++++ + lda step1, y + jsr delay + lda tmpsec + clc + jsr +++++ + lda step2, y + jsr delay + inc step + bne copy_cur ++++ jsr delay + clc +++++ lda tmptrk ++++++ and #3 + rol + tax + +unrseek = unrelocdsk + (* - reloc) + lda PHASEOFF, x + rts + +prepdrive + !if poll_drive = 1 { + tsx + stx callstack + 1 + } ;poll_drive = 1 + !if allow_multi = 1 { + ldy driveind + 1 + } ;allow_multi = 1 + !if (might_exist + poll_drive + detect_wp) > 0 { + !if ver_02 = 1 { + lda #0 + sta status + } else { ;ver_02 = 0 + stz status + } ;ver_02 = 1 + } ;might_exist = 1 or poll_drive = 1 or detect_wp = 1 + !if allow_multi = 1 { + asl reqcmd + bcc seldrive + tya +twodrives eor #0 ;replaced with 1 if drive exists + tay +seldrive lsr reqcmd +driveind cpy #0 + sty driveind + 1 + clc + bne newdrive + } ;allow_multi = 1 + jsr poll + !if allow_multi = 1 { + cpx #1 + } ;allow_multi = 1 + +newdrive +unrdrvon2 = unrelocdsk + (* - reloc) + sta MOTORON + + !if allow_multi = 1 { +unrdrvsel3 = unrelocdsk + (* - reloc) + sta DRV0EN, y + bcs seekret + } else { ;allow_multi = 0 + bne seekret + } ;allow_multi = 1 + spinup ldy #6 - jsr delay dey @@ -1554,77 +1791,14 @@ delay -- ldx #$11 - dex bne - - sec + inc scratchlo + bne + + inc scratchhi ++ sec sbc #1 bne -- rts - ;no tricks here, just the regular stuff - -seek ldy #0 - sty step - asl phase - txa - asl -copy_cur tax - sta tmptrk - sec - sbc phase - beq +++ - bcs + - !if ver_02 = 1 { - eor #$ff - } else { ;ver_02 = 0 - inc - } ;ver_02 = 1 - inx - bcc ++ -+ - !if ver_02 = 1 { - sbc #1 - } else { ;ver_02 = 0 - dec - } ;ver_02 = 1 - dex -++ cmp step - bcc + - lda step -+ cmp #8 - bcs + - tay - sec -+ - !if ver_02 = 1 { - txa - pha - } else { ;ver_02 = 0 - phx - } ;ver_02 = 1 - ldx step1, y -+++ php - bne + ---- clc - lda tmptrk - ldx step2, y -+ stx tmpsec - and #3 - rol - tax - lsr -unrseek = unrelocdsk + (* - reloc) - lda PHASEOFF, x --- ldx #$12 -- dex - bpl - - dec tmpsec - bne -- - bcs --- - plp - beq seekret - pla - inc step - bne copy_cur - step1 !byte 1, $30, $28, $24, $20, $1e, $1d, $1c step2 !byte $70, $2c, $26, $22, $1f, $1e, $1d, $1c @@ -1644,13 +1818,21 @@ readadr seekret rts readd5aa + !if poll_drive = 1 { + ldx #0 + ldy #0 + } ;poll_drive = 1 +-- + !if poll_drive = 1 { + inx + beq + + } ;poll_drive = 1 -- jsr readnib - cmp #$d5 bne -- jsr readnib cmp #$aa bne - - tay ;we need Y=#$AA later readnib unrread1 = unrelocdsk + (* - reloc) @@ -1658,79 +1840,37 @@ unrread1 = unrelocdsk + (* - reloc) bpl - rts - !if (poll_drive + allow_multi) > 0 { -poll ldy #0 + !if poll_drive = 1 { ++ iny + bne --- + +callstack ldx #0 + inx + inx + txs + jmp nodisk + } ;poll_drive = 1 + +poll ldx #$ff unrread2 = unrelocdsk + (* - reloc) - lda Q6L jsr seekret pha pla unrread3 = unrelocdsk + (* - reloc) - cmp Q6L - clc + eor Q6L bne + - dey + dex bne - - sec + rts - } ;poll_drive = 1 or allow_multi = 1 readdirsel - !if ver_02 = 1 { - pha - txa - pha - } else { ;ver_02 - pha - phx - } ;ver_02 = 1 - -unrdrvon4 = unrelocdsk + (* - reloc) - lda MOTORON !if (ver_02 + allow_multi) > 0 { ldy #0 sty adrlo - !if poll_drive = 1 { - sty status - } ;poll_drive = 1 } else { ;ver_02 = 0 and allow_multi = 0 stz adrlo - !if poll_drive = 1 { - stz status - } ;poll_drive = 1 } ;ver_02 = 1 or allow_multi = 1 - !if allow_multi = 1 { - asl reqcmd - bcc seldrive -twodrives nop ;replace with INY if drive exists -seldrive lsr reqcmd -unrdrvsel2 = unrelocdsk + (* - reloc) - lda DRV0EN, y - cpy driveind + 1 - sty driveind + 1 - beq nodelay - jsr spinup - -nodelay - } ;allow_multi = 1 - !if poll_drive = 1 { - jsr poll - bcc + - pla - pla - pla - pla - jmp nodisk -+ - } ;poll_drive = 1 - !if ver_02 = 1 { - pla - tax - pla - } else { ;ver_02 - plx - pla - } ;ver_02 = 1 readdirsec !if allow_trees = 0 { @@ -1764,15 +1904,24 @@ seekrdwr rol sta reqsec -driveind ldy #0 + !if allow_multi = 1 { + ldy driveind + 1 ldx trackd1, y + } else { ;allow_multi = 0 +trackd1 = * + 1 + ldx #$d1 + } ;allow_multi = 1 ;if track does not match, then seek cpx phase beq checksec lda phase + !if allow_multi = 1 { sta trackd1, y + } else { ;allow_multi = 0 + sta trackd1 + } ;allow_multi = 1 jsr seek ;match or read/write sector @@ -1796,6 +1945,7 @@ cmpsecrd jsr readadr jsr readd5aa eor #$ad ;zero A if match bne cmpsecrd + ldy #$aa unrread4 = unrelocdsk + (* - reloc) - ldx Q6L bpl - @@ -1855,9 +2005,8 @@ cmpsecwr jsr readadr ;skip tail #$DE #$AA #$EB some #$FFs ... - ldy #6 -- jsr readnib - dey + ldy #$24 +- dey bpl - ;write sector data @@ -1866,12 +2015,13 @@ unrslot1 = unrelocdsk + (* - reloc) ldx #$d1 lda Q6H, x ;prime drive lda Q7L, x ;required by Unidisk + !if detect_wp = 1 { + asl + ror status + } ;detect_wp = 1 tya sta Q7H, x ora Q6L, x - pha ;3 cycles - pla ;4 cycles - nop ;2 cycles ;40 cycles @@ -1989,7 +2139,7 @@ loopchk7 writenib1 jsr writeret ;6 cycles writenib2 -unrslot4=unrelocdsk+(*-reloc) +unrslot4 = unrelocdsk + (* - reloc) ldx #$d1 ;2 cycles sta Q6H, x ;5 cycles ora Q6L, x ;4 cycles @@ -1997,19 +2147,20 @@ writeret rts ;6 cycles prolog !byte $ad, $aa, $d5 prolog_e - !if >(prolog - 1) != >prolog_e { + !if >(prolog - 1) != >(prolog_e - 1) { !serious "prologue crosses a page" } epilog !byte $ff, $eb, $aa, $de epilog_e - !if >(epilog - 1) != >epilog_e { + !if >(epilog - 1) != >(epilog_e - 1) { !serious "epilogue crosses a page" } } ;enable_write = 1 codeend + !if allow_multi = 1 { trackd1 !byte 0 trackd2 !byte 0 - + } ;allow_multi = 1 bit2tbl = (* + 255) & -256 nibtbl = bit2tbl + 86 !if enable_write = 1 { @@ -2024,19 +2175,16 @@ dataend = nibtbl + 106 unrelochdd !pseudopc reloc { !if rwts_mode = 1 { - !if no_interrupts = 1 { - php - sei - jsr + - plp - rts -+ - } ;no_interrupts = 1 !if swap_zp = 1 { + sta zp_array + namhi - first_zp + sty zp_array + namlo - first_zp jsr swap_zpg - } ;swap_zp = 1 + } else { ;swap_zp = 0 sta namhi sty namlo + } ;swap_zp = 1 + +loopsect !if ver_02 = 1 { lda #0 sta sizehi @@ -2051,11 +2199,11 @@ unrelochdd bcc skipinit ;read beq skipinit ;write ldy #5 ;sector - !if ver_02 = 1 { + !if ver_02 = 1 { txa - } else { ;ver_02 + } else { ;ver_02 lda #0 - } ;ver_02 = 1 + } ;ver_02 = 1 sta (namlo),y dey ;track sta (namlo),y @@ -2141,6 +2289,13 @@ lastvol = * + 1 !if enable_write = 1 { ldy #$0c ;command lda (namlo),y + !if enable_seek = 1 { + !if swap_zp = 0 { + beq + + } else { ;swap_zp = 1 + beq swap_zpg + } ;swap_zp = 0 + } ;enable_seek ldy #0 lsr bne runinit @@ -2167,28 +2322,32 @@ runinit !if enable_format = 1 { bne format } ;enable_format = 1 + !if write_sparse = 1 { + lda sparseblk + beq writesparse + } ;write_sparse = 1 - lda (scratchlo),y sta (adrlo),y iny bne - - lda adrhi - and #$fe + !if write_sparse = 0 { + lda #>hddencbuf sta adrhi ldy #cmdwrite unrcommand1 = unrelochdd + (* - reloc) sty command - !if use_smartport = 1 { + !if use_smartport = 1 { nop ;allow replacing "sty command" with "sty pcommand" in extended SmartPort mode - } ;use_smartport = 1 - !if swap_zp = 1 { + } ;use_smartport = 1 + !if swap_zp = 1 { jsr hddwriteimm - !if enable_format = 1 { + !if enable_format = 1 { bcc swap_zpg ;always - } ;enable_format = 1 - } else { ;swap_zp = 0 + } ;enable_format = 1 + } else { ;swap_zp = 0 jmp hddwriteimm - } ;swap_zp = 1 - !if enable_format = 1 { + } ;swap_zp = 1 + !if enable_format = 1 { clrcarry clc inc adrhi format lda blanksec,x @@ -2206,8 +2365,7 @@ format lda blanksec,x lda #$18 ;blocks sta namlo sty namhi - lda adrhi - and #$fe + lda #>hddencbuf sta adrhi lda #cmdwrite sta reqcmd @@ -2220,29 +2378,28 @@ format lda blanksec,x bne - dec namhi bpl - - } ;enable_format = 1 + } ;enable_format = 1 + } else { ;write_sparse = 1 + !if swap_zp = 1 { + jsr hddwriteenc + } else { ;swap_zp = 0 + jmp hddwriteenc + } ;swap_zp = 1 + } ;write_sparse = 0 } ;enable_write = 1 !if swap_zp = 1 { -swap_zpg pha - tya - pha - ldx #(last_zp - first_zp) +swap_zpg ldx #(last_zp - first_zp) - lda first_zp,x ldy zp_array,x sta zp_array,x sty first_zp,x dex bpl - - pla - tay - pla } ;swap_zp = 1 !if (enable_write + swap_zp) > 0 { - !if no_interrupts = 0 { clc - } ;no_interrupts = 0 rts } ;enable_write = 1 or swap_zp = 1 @@ -2250,53 +2407,155 @@ swap_zpg pha blanksec !text "SAN INC." } ;enable_format = 1 + !if write_sparse = 1 { +writesparse ldx #2 + tya + !if fast_subindex = 0 { + jsr hddreaddirsec + } else { ;fast_subindex = 1 + ldy #>hddencbuf + jsr hddreaddirsect + } ;fast_subindex = 0 + !if ver_02 = 1 { + lda #0 + sta sizelo + sta sizehi + } else { ;ver_02 = 0 + stz sizelo + stz sizehi + } ;ver_02 = 1 + + ;round up to block count + + lda hddencbuf + $29 + adc #$ff + lda hddencbuf + $2A + adc #1 + lsr + sta ldrhi + ldx hddencbuf + $27 + lda hddencbuf + $28 +--- ldy #>hddencbuf + sty adrhi + jsr hddseekrd + ldy #0 + + ;scan for a free block + +-- lda #$80 + sta ldrlo +- lda (adrlo), y + and ldrlo + bne foundbit + inc sizelo + lsr ldrlo + bcc - + lda sizelo + bne + + inc sizehi ++ iny + bne -- + inc adrhi + lda adrhi + cmp #(>hddencbuf) + 2 + bne -- +unrbloklo2 = unrelochdd + (* - reloc) + ldx bloklo + !if use_smartport = 1 { + nop ;allow replacing "ldx bloklo" with "ldx pblock" in extended SmartPort mode + } ;use_smartport = 1 + + inx + bne + +unrblokhi2 = unrelochdd + (* - reloc) + inc blokhi + !if use_smartport = 1 { + nop ;allow replacing "inc blokhi" with "inc pblock + 1" in extended SmartPort mode + } ;use_smartport = 1 ++ +unrblokhi3 = unrelochdd + (* - reloc) + lda blokhi + !if use_smartport = 1 { + nop ;allow replacing "lda blokhi" with "lda pblock + 1" in extended SmartPort mode + } ;use_smartport = 1 + dec ldrhi + bne --- + + ;disk full + + !if swap_zp = 0 { + clc + rts + } else { ;swap_zp = 1 + beq swap_zpg + } ;swap_zp = 0 + + ;allocate block and update bitmap + +foundbit lda (adrlo), y + eor ldrlo + sta (adrlo), y + jsr hddwriteenc + inc lasttree + lda #$60 ;RTS + sta hddskiptree + 2 + jsr hddrdfile + lda #$be ;LDX ,Y + sta hddskiptree + 2 + lda sizelo + sta hdddirbuf, y + lda sizehi + sta hdddirbuf + 256, y + jsr hddwritedir + lda #0 + jsr savebyte + ldx sizelo + lda sizehi + ldy #cmdwrite + jsr hddseekrdwr + jmp loopsect + +hddwriteenc lda #>hddencbuf + sta adrhi +hddwritedir ldy #cmdwrite + +unrcommand1 = unrelochdd + (* - reloc) + sty command + !if use_smartport = 1 { + nop ;allow replacing "sty command" with "sty pcommand" in extended SmartPort mode + } ;use_smartport = 1 + bne hddwriteimm + } ;write_sparse = 1 + seek1 sta blkidx !if enable_write = 1 { lda #cmdread sta reqcmd } ;enable_write = 1 } else { ;rwts_mode = 0 -hddopendir - !if no_interrupts = 1 { - !if detect_err = 1 { - clc - } ;detect_err = 1 - php - sei - jsr + - !if detect_err = 1 { - pla - adc #0 - pha - } ;detect_err = 1 - plp - rts -+ - } ;no_interrupts = 1 - ;read volume directory key block ;self-modified by init code +hddopendir unrhddblocklo = unrelochdd + (* - reloc) +!ifdef PASS2 { +} else { ;PASS2 + !if (* + 1) != iCurBlockLo { + !error "iCurBlockLo=",* + 1, ", fix constants.a, rebuild prelaunch" + } +} ldx #2 unrhddblockhi = unrelochdd + (* - reloc) +!ifdef PASS2 { +} else { ;PASS2 + !if (* + 1) != iCurBlockHi { + !error "iCurBlockHi=",* + 1, ", fix constants.a, rebuild prelaunch" + } +} lda #0 jsr hddreaddirsel - !if enable_floppy = 1 { - !if (* - hddopendir) < (readdir - opendir) { - ;essential padding to match offset with floppy version - !fill (readdir - opendir) - (* - hddopendir), $ea - } - } ;enable_floppy = 1 - -hddreaddir ;note that calling this location directly limits subdirectories to 14 entries! - lda #NAME_LENGTH + ENTRY_SIZE -hddfirstent sta scratchlo -dirbufpatch1 - lda #>(hdddirbuf - 1) - sta scratchhi - +hddreaddir !if might_exist = 1 { lda hdddirbuf + FILE_COUNT ;assuming only 256 files per subdirectory sta entries @@ -2306,6 +2565,12 @@ dirbufpatch1 } ;many_files = 1 } ;might_exist = 1 + lda #NAME_LENGTH + ENTRY_SIZE +hddfirstent sta scratchlo +dirbufpatch1 + lda #>(hdddirbuf - 1) + sta scratchhi + ;there can be only one page crossed, so we can increment here hddnextent1 inc scratchhi @@ -2345,6 +2610,12 @@ hddnextent ldy #0 and #$0f tax inx + + ;placeholder instructions for path patching + +pathpatch1 + cmp (namlo), y + - eor (namlo), y asl beq hddfoundname @@ -2371,6 +2642,7 @@ hddnextent ldy #0 ;move to next entry in this block, if possible +pathresume + clc lda scratchlo adc #ENTRY_SIZE @@ -2394,6 +2666,7 @@ hddfoundname iny dex bne - +pathpatch2 ;initialise essential variables !if allow_trees = 1 { @@ -2411,7 +2684,9 @@ hddfoundname iny !if aligned_read = 0 { ldy reqcmd cpy #cmdwrite ;control carry instead of zero + !if one_shot = 0 { bne + + } ;one_shot = 0 } ;aligned_read = 0 !if one_shot = 0 { @@ -2436,7 +2711,15 @@ hddfoundname iny !if (bounds_check + return_size + one_shot) > 0 { ;cache EOF (file size, loaded backwards) - ldy #EOF_HI + ldy #EOF_HI2 + lda (scratchlo), y + beq not48 + lda #$ff + tax + bne + + +not48 + dey lda (scratchlo), y !if (enable_write + aligned_read) > 0 { tax @@ -2449,9 +2732,9 @@ hddfoundname iny !if aligned_read = 0 { bcc + } else { ;aligned_read = 1 - !if enable_write = 1 { + !if (enable_write + (one_shot xor 1)) > 1 { sec - } ;enable_write = 1 + } ;enable_write = 1 and one_shot = 0 } ;aligned_read = 0 adc #$fe txa @@ -2489,50 +2772,38 @@ hddfoundname iny } ;one_shot = 0 } ;enable_write = 1 or aligned_read = 1 } ;bounds_check = 1 or return_size = 1 or one_shot = 1 + ;cache AUX_TYPE (load offset for binary files) !if override_adr = 0 { ldy #AUX_TYPE - lda (scratchlo), y - !if (allow_subdir + allow_saplings + allow_trees + (aligned_read xor 1)) > 0 { - sta ldrlo - iny - lda (scratchlo), y + jsr fetchscratch + stx ldrlo sta ldrhi - } else { ;allow_subdir = 0 and allow_saplings = 0 and allow_trees = 0 and aligned_read = 1 - pha - iny - lda (scratchlo), y - pha - } ;allow_subdir = 1 or allow_saplings = 1 or allow_trees = 1 or aligned_read = 0 } ;override_adr = 0 ;;allow query even in override mode ldy #AUX_TYPE - lda (scratchlo), y - sta ldrlo2 - iny - lda (scratchlo), y + jsr fetchscratch + stx ldrlo2 sta ldrhi2 ;cache KEY_POINTER ldy #KEY_POINTER - lda (scratchlo), y - tax + jsr fetchscratch !if (allow_subdir + allow_saplings + allow_trees) > 0 { dirbufpatch4 - sta hdddirbuf + stx hdddirbuf !if (allow_trees + (fast_trees xor 1)) > 1 { - sta treeblklo + stx treeblklo } ;allow_trees = 1 and fast_trees = 0 - iny - lda (scratchlo), y dirbufpatch5 sta hdddirbuf + 256 !if (allow_trees + (fast_trees xor 1)) > 1 { sta treeblkhi } ;allow_trees = 1 and fast_trees = 0 + !if always_trees = 0 { plp attribpatch @@ -2541,9 +2812,11 @@ attribpatch php } ;allow_subdir = 1 !if allow_trees = 1 { +dirbufpatch11 ldy #>hdddirbuf bvc + !if fast_trees = 1 { +treebufpatch1 ldy #>hddtreebuf } ;fast_trees = 1 sty istree @@ -2577,24 +2850,6 @@ hddrdwrfilex !if allow_subdir = 1 { clc } ;allow_subdir = 1 -!if (no_interrupts + (rwts_mode xor 1)) > 1 { - !if detect_err = 1 { - !if allow_subdir = 0 { - clc - } ;allow_subdir = 0 - } ;detect_err = 1 - php - sei - jsr + - !if detect_err = 1 { - pla - adc #0 - pha - } ;detect_err = 1 - plp - rts -+ -} ;no_interrupts = 1 and rwts_mode = 0 hddrdwrfilei !if rwts_mode = 0 { @@ -2700,6 +2955,9 @@ encbufpatch1 + !if enable_seek = 1 { lda sizehi + !if read_scrn = 1 { + clv + } ;read_scrn = 1 } else { ;enable_seek = 0 ldy sizehi } ;enable_seek = 1 @@ -2726,11 +2984,10 @@ encbufpatch1 clc bne hddrdwrfilei } else { ;no_interrupts = 0 - beq hddrdwrdone + beq + jmp hddrdwrfilex ++ jmp hddrdwrdone } ;no_interrupts = 1 - } else { ;allow_subdir = 0 - bne hddrdwrfilei } ;allow_subdir = 1 !if allow_aux = 0 { rts @@ -2761,7 +3018,29 @@ hddrdwrloop lda sizehi cmp #2 + !if read_scrn = 1 { + clv + bcc redirect + !if (enable_write + enable_seek) > 0 { + txa + beq + + } ;enable_write = 1 or enable_seek = 1 + ldy ldrhi + cpy #8 bcs + + bit knownrts ;set O flag + lda sizehi + pha + lda sizelo + pha + lda #0 + sta sizelo + lda #1 + +redirect + } else { ;read_scrn = 0 + bcs + + } ;read_scrn = 1 pha ;redirect read to private buffer for partial copy @@ -2814,9 +3093,6 @@ encbufpatch2 !if aligned_read = 0 { php } ;aligned_read = 0 - lda #>hdddirbuf - sta adrhi - sty adrlo } else { ;rwts_mode = 1 !if fast_subindex = 0 { ;read whenever block index changes @@ -2829,8 +3105,8 @@ blkidx = * + 1 ldy #$d1 lastblk = * + 1 cpy #$d1 - } ;mem_swap = 0 sty lastblk + } ;mem_swap = 0 php pla !if mem_swap = 0 { @@ -2849,6 +3125,11 @@ lasttree = * + 1 bne readtree pha plp + !if enable_write = 1 { + bne readtree + lda reqcmd + lsr + } ;enable_write = 1 beq skipblk readtree @@ -2893,7 +3174,9 @@ blkidx = * + 1 !if rwts_mode = 0 { inc treeidx } ;rwts_mode = 0 +treebufpatch2 ldx hddtreebuf, y +treebufpatch3 lda hddtreebuf + 256, y } ;fast_trees = 0 !if detect_treof = 1 { @@ -2918,6 +3201,9 @@ hddnoteof1 } ;detect_treof = 1 !if fast_trees = 0 { +dirbufpatch12 + lda #>hdddirbuf + sta adrhi jsr hddseekrd } else { ;fast_trees = 1 jsr hddreaddirsel @@ -2973,7 +3259,15 @@ unrcommand2 = unrelochdd + (* - reloc) lastblk = * + 1 cpy #$d1 } ;mem_swap = 0 + !if enable_write = 0 { beq skipblk + } else { ;enable_write = 1 + bne + + lda reqcmd + lsr + beq skipblk ++ + } ;enable_write = 0 sty lastblk } ;fast_subindex = 1 } ;rwts_mode = 0 @@ -2998,37 +3292,41 @@ hddnoteof2 jmp hddseekrd } else { ;enable_write = 1 ldy reqcmd + !if enable_seek = 1 { jmp hddseekrdwr + } else { ;enable_seek = 0 + bne hddseekrdwr + } ;enable_seek = 1 } ;enable_write = 0 } ;rwts_mode = 1 } else { ;allow_sparse = 1 pha dirbufpatch9 ora hdddirbuf, y - tay - pla - !if rwts_mode = 0 { - dey - iny ;don't affect carry - } else { ;rwts_mode = 1 + !if write_sparse = 1 { + sta sparseblk + } ;write_sparse = 1 + !if rwts_mode = 1 { !if enable_write = 1 { - cpy #1 + cmp #1 + pla ldy reqcmd bcs hddseekrdwr +savebyte tay } else { ;enable_write = 0 + tay + pla dey iny ;don't affect carry bne hddseekrd } ;enable_write = 1 - } ;rwts_mode = 0 + } ;rwts_mode = 1 } ;allow_sparse = 0 !if rwts_mode = 0 { - !if aligned_read = 0 { - php - } ;aligned_read = 0 !if allow_sparse = 1 { beq hddissparse + pla } ;allow_sparse = 1 !if (aligned_read and (enable_write or enable_seek)) = 1 { ldy reqcmd @@ -3036,23 +3334,31 @@ dirbufpatch9 beq + } ;enable_seek = 1 } ;aligned_read = 1 and (enable_write = 1 or enable_seek = 1) + !if aligned_read = 0 { + php + } ;aligned_read = 0 !if enable_write = 1 { jsr hddseekrdwr } else { ;enable_write = 0 jsr hddseekrd } ;enable_write = 1 + !if aligned_read = 0 { + plp + } ;aligned_read = 0 hddresparse !if aligned_read = 0 { - plp + bcc + + } ;aligned_read = 0 + inc adrhi + inc adrhi + !if aligned_read = 0 { +resumescrn !if bounds_check = 1 { dec blefthi dec blefthi } ;bounds_check = 1 } ;aligned_read = 0 - inc adrhi - inc adrhi dec sizehi dec sizehi bne hddrdwrloop @@ -3071,6 +3377,10 @@ hddsetaux sta CLRAUXRD, x !if allow_sparse = 1 { hddissparse + !if rwts_mode = 0 { + pla + } ;rwts_mode = 0 + tay - sta (adrlo), y inc adrhi sta (adrlo), y @@ -3114,12 +3424,29 @@ hddcopycache bne - inc scratchhi inc adrhi + !if read_scrn = 1 { + bvs copyhalf + } ;read_scrn = 1 bne + +copyhalf - lda (adrlo), y sta (scratchlo), y iny + cpy sizelo bne - + !if read_scrn = 1 { + bvc ++ + pla + sta sizelo + pla + sta sizehi + ldx scratchhi + inx + stx adrhi + lda scratchlo + sta adrlo + bvs resumescrn + } ;read_scrn = 1 ++ !if one_shot = 0 { !if bounds_check = 1 { @@ -3152,24 +3479,14 @@ hddcopycache } ;allow_aux = 1 } ;one_shot = 0 } ;aligned_read = 0 -} else { ;rwts_mode = 1 - !if allow_sparse = 0 { -skipblk rts - } ;allow_sparse = 0 } ;rwts_mode = 0 hddreaddirsel !if ver_02 = 1 { ldy #0 sty adrlo - !if might_exist = 1 { - sty status - } ;might_exist = 1 } else { ;ver_02 = 0 stz adrlo - !if might_exist = 1 { - stz status - } ;might_exist = 1 } ;ver_02 = 1 !if (enable_floppy + allow_multi) > 1 { @@ -3179,9 +3496,9 @@ hddreaddirsel hddreaddirsec !if allow_trees = 0 { -dirbufpatch10 hddreaddirsect ldy #>hdddirbuf } else { ;allow_trees = 1 +dirbufpatch10 ldy #>hdddirbuf hddreaddirsect } ;allow_trees = 0 @@ -3199,12 +3516,12 @@ unrcommand3 = unrelochdd + (* - reloc) hddseekrdwr } ;aligned_read = 0 or enable_write = 0 -unrbloklo = unrelochdd + (* - reloc) +unrbloklo1 = unrelochdd + (* - reloc) stx bloklo !if use_smartport = 1 { nop ;allow replacing "stx bloklo" with "stx pblock" in extended SmartPort mode } ;use_smartport = 1 -unrblokhi = unrelochdd + (* - reloc) +unrblokhi1 = unrelochdd + (* - reloc) sta blokhi !if use_smartport = 1 { nop ;allow replacing "sta blokhi" with "sta pblock + 1" in extended SmartPort mode @@ -3225,8 +3542,11 @@ hddwriteimm lda adrhi ;for Trackstar support } ;swap_scrn = 1 unrentrysei = unrelochdd + (* - reloc) +!if no_interrupts = 1 { php sei +} ;no_interrupts = 1 +retry unrentry = unrelochdd + (* - reloc) jsr $d1d1 !if use_smartport = 1 { @@ -3235,7 +3555,23 @@ pcommand !byte $2c ;hide packet in non-SmartPort mode unrppacket = unrelochdd + (* - reloc) !word unrelochdd + (packet - reloc) } ;use_smartport = 1 + bcc goodread +unrgetreq = unrelochdd + (* - reloc) + lda reqcmd +!if use_smartport = 1 { + nop ;allow replacing "lda reqcmd" with "lda pcommand" in extended SmartPort mode +} ;use_smartport = 1 + + ;read failures are assumed to be transient + ;write failures are assumed to be permanent + + cmp #cmdread + beq retry + +goodread +!if no_interrupts = 1 { plp +} ;no_interrupts = 1 hackstar = unrelochdd + (* - reloc) pla sta adrhi ;Trackstar does not preserve adrhi @@ -3272,6 +3608,9 @@ initpatch lda ($48), y dec $4a bne -- } ;swap_scrn = 1 +!if (rwts_mode + (allow_sparse xor 1)) > 1 { +skipblk +} ;rwts_mode = 1 and allow_sparse = 0 rts fetchscratch @@ -3288,6 +3627,27 @@ unrunit2 = unrelochdd + (* - reloc) !byte 0 paddr !word readbuff + $200 pblock !byte 2, 0, 0 + !if >pcommand != >(pblock + 1) { + !if >pcommand != >pblock { + !ifdef pblock_enabled { + } else { + !ifdef PASS2 { + !warn "uncomment ';;lda #>pblock'" + !warn "uncomment ';;pblock_enabled=1'" + !warn "uncomment ';;lda #>paddr'" + } + } + } else { + !ifdef pblock1_enabled { + } else { + !ifdef PASS2 { + !warn "uncomment ';;lda #>(pblock + 1)'" + !warn "uncomment ';;pblock1_enabled=1'" + !warn "uncomment ';;lda #>paddr'" + } + } + } + } } ;use_smartport = 1 !if (rwts_mode + allow_multi) > 1 { @@ -3369,6 +3729,9 @@ hdddataend } ;aligned_read = 0 or enable_write = 1 !if allow_trees = 1 { !if fast_trees = 1 { + !if enable_write = 0 { + encbuf = dirbuf ;there is no encbuf + } ;enable_write = 0 !if ((aligned_read xor 1) + rwts_mode) > 0 { !if encbuf < reloc { treebuf = encbuf - $200 @@ -3426,7 +3789,7 @@ hdddataend !pseudopc ((dataend + $ff) & -256) { dirbuf = * } - !if aligned_read = 0 { + !if ((aligned_read xor 1) + enable_write) > 0 { encbuf = dirbuf + $200 } ;aligned_read !if allow_trees = 1 { @@ -3564,13 +3927,17 @@ hdddataend !pseudopc ((hdddataend + $ff) & -256) { hdddirbuf = $d200 } - !if aligned_read = 0 { - hddencbuf = hdddirbuf - $200 - } ;aligned_read + !if ((aligned_read xor 1) + rwts_mode) > 0 { + !if fast_subindex = 0 { + hddencbuf = hdddirbuf ;writes come from cache + } else { ;fast_subindex = 1 + hddencbuf = hdddirbuf - $200 + } ;fast_subindex + } ;aligned_read = 0 or rwts_mode = 1 !if allow_trees = 1 { !if fast_trees = 1 { !if ((aligned_read xor 1) + enable_write) > 0 { - hddtreebuf = hddencbuf + $200 + hddtreebuf = hddencbuf + $400 } else { ;aligned_read = 1 and enable_write = 0 hddtreebuf = hdddirbuf + $200 } ;aligned_read = 0 or enable_write = 1 diff --git a/src/textrank.a b/src/textrank.a index 61ebe76..f510bf3 100644 --- a/src/textrank.a +++ b/src/textrank.a @@ -4,8 +4,9 @@ ; text rank - an implementation of the Quicksilver search rank algorithm ; ; Public functions -; - BuildSearchStore +; - ReloadSearchIndex ; - ResetTextRank +; - FindTitleInCache ; - TextRankCallback (as okvs_iter_values callback) ; ; Public variables @@ -25,43 +26,61 @@ InputBuffer !text " " ;------------------------------------------------------------------------------ -; BuildSearchStore -; Build a temporary data structure in main memory to support search UI. -; Now that gGamesListStore no longer contains full game display names, we call -; this to build a store that does. It's built in main memory and will be -; clobbered as soon as we enter attract mode (mega- or mini-), run a game, -; run a demo, or sneeze. +; ReloadSearchIndex +; +; Load indexes to support search UI ; ; in: none ; out: gSearchStore populated ;------------------------------------------------------------------------------ -BuildSearchStore - jsr SwitchToBank2 - jsr EnableAcceleratorAndSwitchToBank1 - +LDADDR gSearchStore - jsr okvs_init +ReloadSearchIndex + jsr LoadIndexedFile ; load appropriate search index into $8200 + !word gSearchIndex + !word kSearchIndexRecord + jsr LoadIndexedFile ; load appropriate search cache into $B000 + !word gSearchCache + !word kSearchCacheRecord + rts - jsr okvs_iter - !word gGamesListStore - !word @callback - - jsr SwitchToBank2 - jmp DisableAcceleratorAndSwitchToBank1 -@callback -; callback called by okvs_iter on gGamesListStore - -; in: A/Y contains address of filename -; $WINDEX contains 0-based index of the current record in gGamesListStore (word) -; out: all registers and flags clobbered - +ST16 @key - jsr GetGameDisplayName - +ST16 @value -@append - jsr okvs_append - !word gSearchStore -@key !word $FDFD ; SMC -@value !word $FDFD ; SMC - !byte 0 +FindTitleInCache + ldx InputLength + cpx #5 + bcs @nomatch + lda #$20 + sta InputBuffer, x + +LDADDR gSearchCache + +ST16 PTR + ldx #$FF +-- inx + ldy #0 +- lda (PTR), y + beq @nomatch + cmp InputBuffer, x + beq @matchchar + iny + iny + iny + bne - ; always branches +@matchchar + iny + lda (PTR), y + pha + iny + lda (PTR), y + bpl @foundindex + sta PTR+1 + pla + sta PTR + cpx InputLength + bcc -- +@nomatch + sec + rts +@foundindex + sta BestMatchIndex+1 + pla + sta BestMatchIndex + clc rts ;------------------------------------------------------------------------------ diff --git a/src/ui.animation.a b/src/ui.animation.a index 67b3caa..071c960 100644 --- a/src/ui.animation.a +++ b/src/ui.animation.a @@ -13,7 +13,7 @@ ; slow down to 1 Mhz (always), then check if there is an animation for the ; title screenshot we just displayed, and if so, load it and call it ; -; in: none +; in: gSearchStore is populated ; out: C clear ; all other flags clobbered ; all registers clobbered @@ -61,7 +61,7 @@ MaybeAnimateTitle bit $c050 ; turn on graphics mode (Home set text mode) jsr Launch ; execute the animation - jsr BuildSearchStore + jsr ReloadSearchIndex jsr ResyncPage ; we don't know which HGR page is showing ; when the animation returns, so resync ; the current one with our OffscreenPage diff --git a/src/ui.attract.dgr.a b/src/ui.attract.dgr.a new file mode 100644 index 0000000..91f9603 --- /dev/null +++ b/src/ui.attract.dgr.a @@ -0,0 +1,124 @@ +;license:MIT +;(c) 2021 by 4am +; +; DGR action slideshows +; +; Public functions +; - DGRActionSlideshow +; - DGRSingle +; - BlankDGR +; - LoadIndexedDGRFile +; + +;------------------------------------------------------------------------------ +; DGRActionSlideshow +; display a slideshow of double lo-res action screenshots +; +; safe to call if machine only has 64K (does nothing and exits) +; +; in: none +; out: everything clobbered +; graphics mode set to display hi-res screen, which is blank +;------------------------------------------------------------------------------ +DGRActionSlideshow + bit MachineStatus ; only run DGR slideshow if we have 128K + bvc DGRRTS + jsr LoadDGRTransition ; load transition effect code at $6000 + jsr BlankDGR ; switch to DGR mode with initial blank screen + jsr okvs_iter ; cycle through all listed DGR files + !word gSlideshowStore + !word DGRActionCallback ; address of callback (called on each file) + jmp BlankHGRNoHome ; switch back to HGR mode with initial blank screen on exit + +;------------------------------------------------------------------------------ +; DGRSingle +; display a single lo-res screenshot, with transition effect +; +; in: none +; out: everything clobbered +; graphics mode set to display hi-res screen +;------------------------------------------------------------------------------ +DGRSingle + +ST16 IndexedDGRFilename + jsr BlankDGR ; switch to DGR mode with initial blank screen + jsr LoadIndexedDGRFile ; load DGR screen at $4000 + jsr LoadDGRTransition ; load transition effect code at $6000 + jsr ExecuteTransitionAt6000AndWait + jmp BlankHGRNoHome ; switch back to HGR mode with initial blank screen on exit + +;------------------------------------------------------------------------------ +; LoadDGRTransition [private] +; +; in: none +; out: all registers and flags clobbered +; $6000..$BFFF/main contains transition effect code (probably not all +; of that, but no promises) +;------------------------------------------------------------------------------ +LoadDGRTransition + jsr LoadIndexedFile + !word $6000 + !word kDGRFizzleRecord +DGRRTS rts + +;------------------------------------------------------------------------------ +; DGRActionCallback [private] +; callback called by okvs_iter on gSlideshowStore +; to load and display a single DGR action screenshot + +; in: A/Y contains address of filename (name only, path is always /ACTION.DGR/) +; $WINDEX contains 0-based index of the current record in gSlideshowStore (word) +; out: all registers and flags clobbered +; $0800..$1EFF preserved (this contains the gSlideshowStore OKVS data) +; $2000..$BFFF clobbered by graphics data and transition code +;------------------------------------------------------------------------------ +DGRActionCallback + bit KBD + bmi DGRRTS + + +ST16 IndexedDGRFilename + + jsr FindGame + ; if game name is not found (C will be set here), it means the game + ; can't be played due to memory or joystick requirements, so we hide + ; it from slideshows + bcs DGRRTS + + jsr LoadIndexedDGRFile + jmp ExecuteTransitionAt6000AndWait + +BlankDGR + jsr BlankDHGR ; clear and display DHGR screen + ldy #$2C ; BIT + sty PageFrom ; now clear DGR screen + ldx #$04 + stx PageTo+2 + jsr ClearToBlack + sta WRITEAUXMEM + ldx #$04 + stx PageTo+2 + jsr ClearToBlack + sta WRITEMAINMEM + lda #1 + sta OffscreenPage + bit $C056 ; display DGR screen + rts + +LoadIndexedDGRFile +; in: caller has set IndexedDGRFilename +; out: all flags & registers clobbered + jsr LoadIndexedFile ; load index file into $4000 +- !word $4000 + !word kDGRActionIndexRecord + + jsr okvs_find + !word - +IndexedDGRFilename + !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadIndexedFile ; load entire DGR screenshot at $7C00 + !word $7C00 ; because that's where the transition code expects to find it + ; auxmem half is first, mainmem second +@indexRecordPtr + !word $FDFD ; SMC + rts diff --git a/src/ui.attract.dhgr.a b/src/ui.attract.dhgr.a index 29306f7..3e034a1 100644 --- a/src/ui.attract.dhgr.a +++ b/src/ui.attract.dhgr.a @@ -1,5 +1,4 @@ -;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; Double hi-res slideshows ; @@ -27,7 +26,7 @@ ;------------------------------------------------------------------------------ DHGRTitleSlideshow bit MachineStatus ; only run DHGR slideshow if we have 128K - bvc DHGRRTS + bvc DHGRRTS0 jsr LoadDHGRTransition ; load transition effect code at $6000 jsr BlankDHGR ; switch to DHGR mode with initial blank screen jsr okvs_iter ; cycle through all listed DHGR files @@ -48,7 +47,7 @@ DHGRTitleSlideshow ;------------------------------------------------------------------------------ DHGRActionSlideshow bit MachineStatus ; only run DHGR slideshow if we have 128K - bvc DHGRRTS + bvc DHGRRTS0 jsr LoadDHGRTransition ; load transition effect code at $6000 jsr BlankDHGR ; switch to DHGR mode with initial blank screen jsr okvs_iter ; cycle through all listed DHGR files @@ -69,13 +68,10 @@ DHGRActionSlideshow ;------------------------------------------------------------------------------ DHGRSingle bit MachineStatus ; only show DHGR screenshots if we have 128K - bvc DHGRRTS - +ST16 @fname + bvc DHGRRTS0 + +ST16 IndexedDHGRFilename jsr BlankDHGR ; switch to DHGR mode with initial blank screen - jsr LoadAuxFile ; load compressed DHGR screenshot at aux $3FF8 - !word kRootDirectory -@fname !word $FDFD ; SMC - !word $3FF8 + jsr LoadIndexedDHGRFile ; load compressed DHGR screenshot at aux $3FF8 jsr DecompressDHGR jsr LoadDHGRTransition ; load transition effect code at $6000 jsr ExecuteTransitionAt6000AndWait @@ -86,12 +82,13 @@ DHGRSingle ; clear and show HGR page 1 without flickering ; ; in: none -; out: text page clobbered (but screen holes preserved) +; out: text page clobbered ; A/X/Y=0 (guaranteed by ClearHGR1) ; $2000..$3FFF cleared ;------------------------------------------------------------------------------ BlankHGR jsr Home +BlankHGRNoHome jsr ClearHGR1 ; clear hi-res screen 1 bit PAGE1 ; show hi-res screen 1 (now blank) lda #1 @@ -109,7 +106,7 @@ HGRMode GRMode bit $C052 bit $C050 -DHGRRTS rts +DHGRRTS0 rts ;------------------------------------------------------------------------------ ; ForceHGRMode @@ -123,7 +120,7 @@ ForceHGRMode gMachineInDHGRMode=*+1 lda #$00 ; SMC bne BlankHGR - beq DHGRRTS + rts ;------------------------------------------------------------------------------ ; LoadDHGRTransition [private] @@ -136,21 +133,16 @@ gMachineInDHGRMode=*+1 ; $6000..$BFFF/main contains transition effect code ;------------------------------------------------------------------------------ LoadDHGRTransition - jsr LoadFile ; load DHGR transition effects list into $8000 - !word kRootDirectory - !word kDFXConfFile -- !word $8000 - jsr ParseKeyValueList ; parse DHGR transition effects list into $6000 - !word gDFXStore - !word - - !byte 0 + jsr LoadIndexedFile ; load DHGR transition effects list into $6000 +- !word $6000 + !word kDFXIndexRecord jsr pref_get ; get DHGR transition effect from prefs !word kNextDFX - !word gDFXStore - +ST16 ++ ; A/Y = filename (don't load file yet) + !word - + +ST16 @indexRecordPtr ; A/Y = filename (don't load file yet) ; $WINDEX = index of the transition in DFX store - +LDADDR gDFXStore + +LDADDR - jsr okvs_next ; get transition after this one +ST16 + @@ -158,11 +150,11 @@ LoadDHGRTransition !word kNextDFX + !word $FDFD ; SMC - jsr LoadFile ; now load transition effect code into $6000 - !word kFXDirectory -++ !word $FDFD ; SMC + jsr LoadIndexedFile !word $6000 - rts +@indexRecordPtr + !word $FDFD ; SMC +DHGRRTS1 rts ;------------------------------------------------------------------------------ ; DHGRTitleCallback [private] @@ -178,24 +170,35 @@ LoadDHGRTransition ;------------------------------------------------------------------------------ DHGRTitleCallback bit KBD - bmi DHGRRTS + bmi DHGRRTS1 +ST16 + + +ST16 gLastMegaAttractGame jsr FindGame ; if game is not found (C will be set here), it means it can't be played on ; this machine due to memory or joystick requirements, so we don't display ; it in slideshows - bcs DHGRRTS + bcs DHGRRTS1 +LD16 WINDEX ; save game index in case user hits RETURN +ST16 gGameToLaunch ; while it's visible (we'll launch it) - ; load DHGR screenshot at $4000/main and $4000/aux - jsr LoadDHRFile - !word kDHGRTitleDirectory -+ !word $FDFD + jsr LoadIndexedFile ; load index file into $4000 +- !word $4000 + !word kDHGRTitleIndexRecord + jsr okvs_get + !word - ++ !word $FDFD ; SMC + + jsr SwitchToBank2 + ldy #4 +- lda (PTR), y + sta OKVS_CACHE + 1, y + dey + bpl - + jsr LoadIndexedDHRFile jmp ExecuteTransitionAt6000AndWait ;------------------------------------------------------------------------------ @@ -212,24 +215,17 @@ DHGRTitleCallback ;------------------------------------------------------------------------------ DHGRActionCallback bit KBD - bmi DHGRRTS + bmi DHGRRTS1 - +ST16 + + +ST16 IndexedDHGRFilename - jsr FindGameInActionSlideshow + jsr FindGame ; if game name is not found (C will be set here), it means the game ; can't be played due to memory or joystick requirements, so we hide ; it from slideshows - bcs DHGRRTS - +ST16 SAVE ; (SAVE) -> game display name + game info bitfield + bcs DHGRRTS1 - +LD16 WINDEX ; save game index in case user hits RETURN - +ST16 gGameToLaunch ; while it's visible (we'll launch it) - - jsr LoadAuxFile ; load compressed DHGR screenshot at aux $3FF8 - !word kDHGRActionDirectory -+ !word $FDFD - !word $3FF8 + jsr LoadIndexedDHGRFile jsr DecompressDHGR lda #$EA ; NOP @@ -254,19 +250,17 @@ DrawGameTitleInActionSlideshow sta VTAB lda #0 ; solid horizontal bar character jsr @resetline - lda (SAVE),y ; (SAVE) -> game display name, Y = 0, so A = display length + 1 + lda (SAVE),y ; (SAVE) -> game display name, Y = 0, so A = display length clc - adc #$02 + adc #$03 sta gPathname lda #7 ; top-right rounded corner character jsr @drawline - inc VTAB lda #" " jsr @resetline - lda (SAVE),y ; A = display length + 1 + lda (SAVE),y ; A = display length tay - dey - lda (SAVE),y sta gPathname+1,y dey @@ -298,7 +292,7 @@ DrawGameTitleInActionSlideshow ; to display properly on the DHGR screen. ; ; /!\ must be called immediately after calling one of the font drawing routines -; (Draw40Chars, DrawCenteredString, DrawString, DrawBuffer) +; (Draw40Chars, DrawCenteredString, DrawString) ; ; in: gPathname contains number of bytes to transform ; DBIRow0/LC2 contains address of first byte of first row to transform @@ -330,3 +324,22 @@ RedrawForDHGR dec i bne -- jmp SwitchToBank1 + +LoadIndexedDHGRFile +; in: caller has set IndexedDHGRFilename +; out: all flags & registers clobbered + jsr LoadIndexedFile ; load index file into $4000 +- !word $4000 + !word kDHGRActionIndexRecord + + jsr okvs_find + !word - +IndexedDHGRFilename + !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadAuxIndexedFile ; load compressed DHGR screenshot at aux $3FF8 + !word $3FF8 +@indexRecordPtr + !word $FDFD ; SMC + rts diff --git a/src/ui.attract.gr.a b/src/ui.attract.gr.a index bfdbeff..6dca4f6 100644 --- a/src/ui.attract.gr.a +++ b/src/ui.attract.gr.a @@ -33,14 +33,11 @@ GRActionSlideshow ; graphics mode set to display hi-res screen ;------------------------------------------------------------------------------ GRSingle - +ST16 @fname + +ST16 IndexedGRFilename jsr BlankGR ; switch to GR mode with initial blank screen - jsr LoadFile ; load GR screenshot into $6000 - !word kRootDirectory -@fname !word $FDFD ; SMC - !word $6000 - jsr LoadGRTransition ; load transition effect code at $6400 - jsr ExecuteTransitionAt6400AndWait + jsr LoadIndexedGRFile ; load GR screen at $4000 + jsr LoadGRTransition ; load transition effect code at $6000 + jsr ExecuteTransitionAt6000AndWait jmp BlankHGR ; switch back to HGR mode with initial blank screen on exit ;------------------------------------------------------------------------------ @@ -67,14 +64,13 @@ BlankGR ; ; in: none ; out: all registers and flags clobbered -; $6400..$BFFF/main contains transition effect code (probably not all +; $6000..$BFFF/main contains transition effect code (probably not all ; of that, but no promises) ;------------------------------------------------------------------------------ LoadGRTransition - jsr LoadFile - !word kFXDirectory - !word kGRFizzleFile - !word $6400 + jsr LoadIndexedFile + !word $6000 + !word kGRFizzleRecord GRRTS rts ;------------------------------------------------------------------------------ @@ -84,7 +80,6 @@ GRRTS rts ; in: A/Y contains address of filename (name only, path is always /ACTION.GR/) ; $WINDEX contains 0-based index of the current record in gSlideshowStore (word) -; gGamesListStore must be initialized ; out: all registers and flags clobbered ; $0800..$1EFF preserved (this contains the gSlideshowStore OKVS data) ; $2000..$BFFF clobbered by graphics data and transition code @@ -93,20 +88,32 @@ GRActionCallback bit KBD bmi GRRTS - +ST16 + + +ST16 IndexedGRFilename - jsr FindGameInActionSlideshow + jsr FindGame ; if game name is not found (C will be set here), it means the game ; can't be played due to memory or joystick requirements, so we hide ; it from slideshows bcs GRRTS - +LD16 WINDEX ; save game index in case user hits RETURN - +ST16 gGameToLaunch ; while it's visible (we'll launch it) + jsr LoadIndexedGRFile + jmp ExecuteTransitionAt6000AndWait - jsr LoadFile ; load GR screenshot into $6000 - !word kGRActionDirectory -+ !word $FDFD ; SMC - !word $6000 +LoadIndexedGRFile +; in: caller has set IndexedGRFilename +; out: all flags & registers clobbered + jsr LoadIndexedFile ; load index file into $4600 +- !word $4600 + !word kGRActionIndexRecord - jmp ExecuteTransitionAt6400AndWait + jsr okvs_find + !word - +IndexedGRFilename + !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadIndexedFile ; load GR screenshot at $4000 + !word $4000 ; because that's where the transition code expects to find it +@indexRecordPtr + !word $FDFD ; SMC + rts diff --git a/src/ui.attract.hgr.a b/src/ui.attract.hgr.a index b177dd6..7d6acd7 100644 --- a/src/ui.attract.hgr.a +++ b/src/ui.attract.hgr.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; HGR title and action slideshows ; @@ -48,11 +48,8 @@ HGRActionSlideshow ; graphics mode still displaying hi-res screen with last picture visible ;------------------------------------------------------------------------------ HGRSingle - +ST16 @fname - jsr LoadFile ; load compressed HGR screenshot at $3FF8 - !word kRootDirectory -@fname !word $FDFD ; SMC - !word $3FF8 + +ST16 IndexedHGRFilename + jsr LoadIndexedHGRFile jsr DecompressHGR jsr LoadHGRTransition ; load transition effect code at $6000 jmp ExecuteTransitionAt6000AndWait @@ -67,21 +64,16 @@ HGRSingle ; $6000..$BFFF contains transition effect code ;------------------------------------------------------------------------------ LoadHGRTransition - jsr LoadFile ; load HGR transition effects list into $8000 - !word kRootDirectory - !word kFXConfFile -- !word $8000 - jsr ParseKeyValueList ; parse HGR transition effects list into $6000 - !word gFXStore - !word - - !byte 0 + jsr LoadIndexedFile ; load HGR transition effects list into $6000 +- !word $6000 + !word kFXIndexRecord jsr pref_get ; get HGR transition effect from prefs !word kNextFX - !word gFXStore - +ST16 ++ ; A/Y = filename (don't load file yet) + !word - + +ST16 @indexRecordPtr ; A/Y = filename (don't load file yet) ; $WINDEX = index of the transition in FX store - +LDADDR gFXStore + +LDADDR - jsr okvs_next ; get transition after this one +ST16 + @@ -89,10 +81,10 @@ LoadHGRTransition !word kNextFX + !word $FDFD ; SMC - jsr LoadFile ; now load transition effect code into $6000 - !word kFXDirectory -++ !word $FDFD ; SMC + jsr LoadIndexedFile !word $6000 +@indexRecordPtr + !word $FDFD ; SMC HGRRTS rts ;------------------------------------------------------------------------------ @@ -110,7 +102,8 @@ HGRTitleCallback bit KBD bmi HGRRTS - +ST16 + + +ST16 @fname + +ST16 gLastMegaAttractGame jsr FindGame ; if game is not found (C will be set here), it means it can't be played on @@ -121,11 +114,27 @@ HGRTitleCallback +LD16 WINDEX ; save game index in case user hits RETURN +ST16 gGameToLaunch ; while it's visible (we'll launch it) - jsr LoadFile ; load HGR screenshot at $4000 - !word kHGRTitleDirectory -+ !word $FDFD ; SMC - !word $4000 + jsr LoadIndexedFile ; load index file into $4000 +- !word $4000 + !word kHGRTitleIndexRecord + jsr okvs_find + !word - +@fname !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadIndexedFile ; load HGR graphic at $4000 + !word $4000 +@indexRecordPtr + !word $FDFD ; SMC + + lda $5FFD + stx $5FFD ; ensure that we won't find it again if next + ; file is really compressed + cmp #$4C ; Check if screen hole now contains a JMP + beq @noUnpack ; if so, file was not packed, so skip unpack + jsr UnpackHGRTitle +@noUnpack jmp ExecuteTransitionAt6000AndWait ;------------------------------------------------------------------------------ @@ -135,7 +144,6 @@ HGRTitleCallback ; in: A/Y contains address of filename (name only, path is always /ACTION.HGR/) ; $WINDEX contains 0-based index of the current record in gSlideshowStore (word) -; gGamesListStore must be initialized ; out: all registers and flags clobbered ; $0800..$1EFF preserved (this contains the gSlideshowStore OKVS data) ; $2000..$BFFF clobbered by graphics data and transition code @@ -144,23 +152,49 @@ HGRActionCallback bit KBD bmi HGRRTS - +ST16 + + +ST16 IndexedHGRFilename - jsr FindGameInActionSlideshow + jsr FindGame ; if game name is not found (C will be set here), it means the game ; can't be played due to memory or joystick requirements, so we hide ; it from slideshows bcs HGRRTS - ; found the game - +ST16 SAVE ; (SAVE) -> game display name + game info bitfield - - +LD16 WINDEX ; save game index in case user hits RETURN - +ST16 gGameToLaunch ; while it's visible (we'll launch it) - - jsr LoadFile ; load compressed HGR screenshot at $3FF8 - !word kHGRActionDirectory -+ !word $FDFD ; SMC - !word $3FF8 + jsr LoadIndexedHGRFile jsr DecompressHGR jmp DrawGameTitleInActionSlideshow + +LoadIndexedHGRFile +; in: caller has set IndexedHGRFilename +; out: all flags & registers clobbered + +LD16 IndexedHGRFilename + +ST16 PTR + ldy #1 + lda (PTR), y + sec + sbc #$41 ; A in [0..25] + lsr ; A in [0..15] + lsr ; A in [0..7] + tax + lda kHGRActionIndexLo, x + sta HGRActionIndexRecord + lda kHGRActionIndexHi, x + sta HGRActionIndexRecord+1 + + jsr LoadIndexedFile ; load index file into $4000 +HGRActionIndexPtr + !word $4000 +HGRActionIndexRecord + !word $FDFD ; SMC + + jsr okvs_find + !word HGRActionIndexPtr +IndexedHGRFilename + !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadIndexedFile ; load compressed HGR screenshot at $3FF8 + !word $3FF8 +@indexRecordPtr + !word $FDFD ; SMC + rts diff --git a/src/ui.attract.mode.a b/src/ui.attract.mode.a index 923bb0b..0508d56 100644 --- a/src/ui.attract.mode.a +++ b/src/ui.attract.mode.a @@ -1,5 +1,5 @@ ;license:MIT -;(c) 2018-9 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; Attract Mode - cycle through slideshows and self-running demos ; @@ -8,6 +8,16 @@ ; - MiniAttractMode ; - RunAttractModule +kAttractModeFilters + !byte ATTRACT_DEMO + !byte ATTRACT_HGR_TITLE + !byte ATTRACT_HGR_ACTION + !byte ATTRACT_DHGR_TITLE + !byte ATTRACT_DHGR_ACTION + !byte ATTRACT_SHR + !byte ATTRACT_GR + !byte ATTRACT_DGR + ;------------------------------------------------------------------------------ ; MegaAttractMode ; main entry point for Mega Attract Mode, which endlessly cycles through @@ -24,21 +34,17 @@ MegaAttractMode jsr BlankHGR ; switch to HGR page 1 (once cleared) - jsr LoadFile ; load attract-mode configuration file into $8000 - !word kRootDirectory - !word kAttractModeConfFile -- !word $8000 - jsr ParseKeyValueList ; parse attract-mode configuration into OKVS data structure at $6000 - !word gAttractModeStore - !word - - !byte 0 + jsr LoadIndexedFile ; load pre-parsed attract mode configuration data into $6000 +- !word $6000 + !word kAttractModeIndexRecord +@next jsr pref_get ; get attract mode module from prefs !word kNextAttract - !word gAttractModeStore + !word - +ST16 @mname ; A/Y = module name ; $WINDEX = index of module in attract store - +LDADDR gAttractModeStore + +LDADDR - jsr okvs_next ; get module after this one +ST16 + @@ -46,79 +52,127 @@ MegaAttractMode !word kNextAttract + !word $FDFD ; SMC - jsr okvs_get - !word gAttractModeStore + jsr okvs_get ; sets PTR + !word - @mname !word $FDFD ; SMC - +ST16 PTR ldy #1 lda (PTR),y - tax ; X = module type + tax ; X = module type as ASCII digit + + and #$0F ; do we want to display this module type + tay + lda gMegaAttractModeFilter + and kAttractModeFilters, y + beq @next + +LD16 @mname ; A/Y = address of module name jsr RunAttractModule lda KBD bpl MegaAttractMode cmp #$8D ; Enter plays the game shown on screen. bne + ; Any other key switches to Search Mode. - jsr PlayGame ; (might return if user hits Ctrl-Reset) + +LD16 gLastMegaAttractGame + jsr PlayGameInAY ; (might return if user hits Ctrl-Reset) + jmp SearchMode ;------------------------------------------------------------------------------ ; MiniAttractMode ; run attract modules related to one game ; -; in: gGameToLaunch = index in gGamesListStore (word) +; in: gGameToLaunch = index in gSearchStore (word) +; gSearchStore populated ; out: all flags and registers clobbered -; assume all of main memory has been clobbered +; assume all of main memory has been clobbered (including gSearchStore) ;------------------------------------------------------------------------------ MiniAttractMode jsr GetGameToLaunch - +ST16 + + +ST16 @GameToLaunch + +; We want to load the mini attract index into $800 so we can get the +; index record for this game, but we now have so many games that the +; entire index is larger than $1800 bytes and loading it all at once +; would visibly overwrite bytes in HGR page 1. So the index is now +; split into 2 halves based on the first letter of the game's +; directory name, and we figure out which half we want and load it. + + +ST16 PTR + ldy #1 + lda (PTR), y + sec + sbc #$41 ; A in [0..25] + lsr ; A in [0..15] + lsr ; A in [0..7] + lsr ; A in [0..3] + lsr ; A in [0..1] + tax + lda kMiniAttractIndexLo, x + sta @MiniAttractIndexRecord + lda kMiniAttractIndexHi, x + sta @MiniAttractIndexRecord+1 + + jsr LoadIndexedFile +- !word $0800 +@MiniAttractIndexRecord + !word $FDFD ; SMC + +; Find the index record for this game and copy it into LC RAM so we +; can reuse it without reloading the mini attract index over and over +; during attract mode. + + jsr okvs_find + !word - +@GameToLaunch + !word $FDFD ; SMC + jsr okvs_next_field + jsr SwitchToBank2 + sty OKVS_CACHE + ldy #4 ; length of index record (-1) +- lda (PTR), y + sta OKVS_CACHE + 1, y + dey + bpl - + +; Now, finally, start the mini attract mode jsr BlankHGR ; X = 0 - stx MiniAttractIndex - stx MiniAttractIndex+1 + stx @MiniAttractIndex+1 + stx @MiniAttractIndex+3 @loop - jsr LoadFile ; load mini attract mode configuration file into $8000 - !word kMiniAttractDirectory -+ !word $FDFD ; SMC -- !word $8000 + jsr LoadIndexedFile +- !word $6000 + !word OKVS_CACHE - jsr ParseKeyValueList ; parse configuration into OKVS data structure at $6000 - !word gAttractModeStore - !word - - !byte 0 - - +LDADDR gAttractModeStore + +LDADDR - jsr okvs_len lda WCOUNT - cmp MiniAttractIndex + cmp @MiniAttractIndex+1 bne + lda WCOUNT+1 - cmp MiniAttractIndex+1 + cmp @MiniAttractIndex+3 beq ATTRTS ; we've run through all modules, so exit to caller + - +LD16 MiniAttractIndex +@MiniAttractIndex + +LDADDR 0 ; SMC +ST16 WINDEX - +LDADDR gAttractModeStore + +LDADDR - jsr okvs_nth ; get the next module on the list +ST16 SAVE - jsr okvs_get_current ; get module type - ldy #1 + jsr okvs_next_field ; get module type + ; Y = 0 + iny lda (PTR),y tax ; X = module type +LD16 SAVE ; A/Y = address of module name jsr RunAttractModule ; execute the module - inc MiniAttractIndex + inc @MiniAttractIndex+1 bne + - inc MiniAttractIndex+1 + inc @MiniAttractIndex+3 + lda KBD bpl @loop ATTRTS rts -MiniAttractIndex - !word 0 ; SMC ;------------------------------------------------------------------------------ ; RunAttractModule @@ -141,33 +195,31 @@ RunAttractModule bne @NotDemo ; Self-running demos are loaded into main memory and executed. -; Each binary has been patched to quit on any key and jump back -; to the |Reenter| entry point. +; Each demo has been patched to check joystick and memory requirements, +; so a demo won't run if the actual game wouldn't be playable. +; Demos are also patched to jump back to the |Reenter| entry point +; on any key, or at the natural end of the demo cycle. ; All demos are strictly 48K / main memory. No demo uses the ; language card or auxiliary memory. - +LD16 @key - jsr FindGame - bcs ATTRTS ; if game doesn't exist, skip the demo - +LD16 WINDEX - +CMP16 $FFFF - beq + - +ST16 gGameToLaunch ; if this demo corresponds to a game, save its index - ; in case user presses RETURN during the demo (we will launch the game) -+ + +ST16 PTR + ldy #0 + lda (PTR), y + tay +- lda (PTR), y + sta DemoFilename, y + dey + bpl - + +LDADDR DemoFilename + +ST16 gLastMegaAttractGame ; save game filename in LC in case user hits Return to launch + jsr ClearScreens ; avoid seeing code load into the HGR page ; (clobbers $106, must do now before loading prelaunch code) - - jsr LoadFile ; load standard prelaunch code (|Launch| will call it) - !word kPrelaunchDirectory - !word kStandardPrelaunch - !word $0106 - + jsr LoadStandardPrelaunch ; load standard prelaunch code (|Launch| will call it) jsr LoadFile ; load self-running demo into its default address (varies) !word kDemoDirectory @key !word $FDFD !word 0 - jmp Launch ; will return to caller via |Reenter| ; not a demo, so maybe a slideshow or single screenshot @@ -176,17 +228,22 @@ RunAttractModule cmp #$41 ; numbers are slideshow modules, bcs @dispatchSingle ; letters are single files -; it's a slideshow, so load and parse slideshow configuration file +; it's a slideshow, so load slideshow configuration file pha ; save module type - jsr LoadFile ; load slideshow configuration file into $4000 - !word kAttractModeSlideshowDirectory -@key2 !word $FDFD ; SMC + jsr LoadIndexedFile ; load slideshow configuration file into $4000 - !word $4000 - jsr ParseKeyValueList ; parse into an OKVS data structure at $0800 - !word gSlideshowStore + !word kAttractModeSlideshowIndexRecord + jsr okvs_find !word - - !byte 0 +@key2 !word $FDFD ; SMC + +ST16 + + jsr LoadIndexedFile + !word $800 ++ !word $FDFD ; SMC pla ; restore module type + +HIDE_NEXT_2_BYTES +@dispatchSingle + adc #(@singleslo-@slideshowslo)-1 - and #$0F ; convert ASCII digit to int tax @@ -197,10 +254,6 @@ RunAttractModule +LD16 @key ; pass in module name @jmp jmp $FDFD ; SMC -@dispatchSingle - adc #(@singleslo-@slideshowslo)-1 - bne - ; always branches - @slideshowslo !byte HGRTitleSlideshow !byte >HGRActionSlideshow @@ -220,8 +275,13 @@ RunAttractModule !byte >DHGRActionSlideshow !byte >SHRSlideshow !byte >GRActionSlideshow + !byte >DGRActionSlideshow @singleshi !byte >HGRSingle !byte >DHGRSingle !byte >SHRSingle !byte >GRSingle + !byte >DGRSingle + +DemoFilename + !byte 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 diff --git a/src/ui.attract.shr.a b/src/ui.attract.shr.a index 4c74d85..94b3911 100644 --- a/src/ui.attract.shr.a +++ b/src/ui.attract.shr.a @@ -1,13 +1,34 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; Super hi-res slideshows ; ; Public functions +; - AllSHRSlideshow ; - SHRSlideshow ; - SHRSingle ; +;------------------------------------------------------------------------------ +; AllSHRSlideshow +; execute mega-attract mode of all super hi-res artwork (and nothing else) +; +; safe to call if machine can not display super hi-res graphics (clears carry +; and exits) +; +; in: none +; out: C=0 if machine can not display SHR +; otherwise all registers and flags clobbered +;------------------------------------------------------------------------------ +AllSHRSlideshow + clc + lda MachineStatus ; only show SHR on IIgs or if we have a VidHD card + and #SUPPORTS_SHR + beq SHRRTS + lda #ATTRACT_SHR + sta gMegaAttractModeFilter + jmp MegaAttractMode + ;------------------------------------------------------------------------------ ; SHRSlideshow ; execute a slideshow of super hi-res artwork @@ -22,16 +43,15 @@ SHRSlideshow lda MachineStatus ; only show SHR on IIgs or if we have a VidHD card and #SUPPORTS_SHR - bne + -SHRRTS rts -+ jsr LoadSHRTransition + beq SHRRTS + jsr LoadSHRTransition jsr okvs_iter !word gSlideshowStore !word SHRArtworkCallback - jmp BlankHGR + beq jmpblank ; always taken ;------------------------------------------------------------------------------ -; SHRSlideshow +; SHRSingle ; display a single super hi-res artwork ; ; safe to call if machine can not display super hi-res graphics (does nothing @@ -42,34 +62,52 @@ SHRRTS rts ; graphics mode reset to display hi-res screen, which is blank ;------------------------------------------------------------------------------ SHRSingle - +ST16 + + jsr SetPath + +LDADDR gPathname + +ST16 IndexedSHRFilename lda MachineStatus ; only show SHR on IIgs or if we have a VidHD card and #SUPPORTS_SHR beq SHRRTS jsr BlankSHR - jsr LoadFile - !word kRootDirectory -+ !word $FDFD ; SMC - !word $1FF8 + jsr LoadIndexedSHRFile jsr DecompressSHR jsr LoadSHRTransition jsr ExecuteTransitionAtA000AndWait +jmpblank jmp BlankHGR ;------------------------------------------------------------------------------ -; LoadSHGRTransition [private] -; load the SHR transition effect code (currently always the same file) +; LoadSHRTransition [private] +; looks up name of next SHR transition effect in SFX.CONF and loads that file +; at $A000 ; ; in: none ; out: all registers and flags clobbered ; $A000..$BFFF/main contains transition effect code ;------------------------------------------------------------------------------ LoadSHRTransition - jsr LoadFile - !word kFXDirectory - !word kSFXFizzleFile - !word $A000 - rts + jsr LoadIndexedFile ; load SHR transition effects list into $A000 +- !word $A000 + !word kSFXIndexRecord + + jsr pref_get ; get SHR transition effect from prefs + !word kNextSFX + !word - + +ST16 @indexRecordPtr ; A/Y = filename (don't load file yet) + ; $WINDEX = index of the transition in SFX store + +LDADDR - + jsr okvs_next ; get transition after this one + +ST16 + + + jsr pref_set ; update prefs store and save to disk + !word kNextSFX ++ !word $FDFD ; SMC + + jsr LoadIndexedFile + !word $A000 ; load actual transition effect code into $A000 +@indexRecordPtr + !word $FDFD ; SMC +SHRRTS rts ;------------------------------------------------------------------------------ ; SHRArtworkCallback [private] @@ -87,7 +125,8 @@ SHRArtworkCallback bit KBD bmi SHRRTS - +ST16 @sfname + +ST16 IndexedSHRFilename + +ST16 gLastMegaAttractGame jsr FindGame ; if game is not found (C will be set here), it means it can't be played on @@ -95,19 +134,30 @@ SHRArtworkCallback ; it in slideshows bcs SHRRTS - +LD16 WINDEX ; save game index in case user hits RETURN - +ST16 gGameToLaunch ; while it's visible (we'll launch it) - jsr BlankSHR - - ; load compressed SHR artwork at $1FF0/main (not aux) - jsr LoadFile - !word kSHRArtworkDirectory -@sfname !word $FDFD - !word $1FF8 + jsr LoadIndexedSHRFile jsr DecompressSHR jmp ExecuteTransitionAtA000AndWait +LoadIndexedSHRFile +; in: caller has populated IndexedSHRFilename +; out: all flags & registers clobbered + jsr LoadIndexedFile ; load index file into $2000 +- !word $2000 + !word kSHRArtworkIndexRecord + + jsr okvs_find + !word - +IndexedSHRFilename + !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadIndexedFile ; load compressed SHR artwork at $1FF8/main (not aux) + !word $1FF8 +@indexRecordPtr + !word $FDFD ; SMC + rts + ;------------------------------------------------------------------------------ ; BlankSHR [private] ; clear and show SHR mode without flickering @@ -117,7 +167,7 @@ SHRArtworkCallback ; NOTE: THIS ROUTINE WILL CRASH ON AN APPLE //C due to writing to $C029, ; so it is imperative that the caller ensures the machine type. ; Thanks to John Brooks for explaining all of this to me. Twice. -; out: text page clobbered (but screen holes preserved) +; out: text page clobbered ; $2000..$9FFF/aux cleared ;------------------------------------------------------------------------------ BlankSHR diff --git a/src/ui.browse.mode.a b/src/ui.browse.mode.a index 5ce427d..3568efe 100644 --- a/src/ui.browse.mode.a +++ b/src/ui.browse.mode.a @@ -36,6 +36,7 @@ kBrowseCheat = 8 kSoftBell = 9 ; must match kInputError kBrowseJoystick = 10 kBrowseQuit = 11 +kBrowseSHR = 12 ldy #kNumBrowseKeys - dey @@ -47,8 +48,10 @@ kBrowseQuit = 11 @noKeyMatch jsr IsSearchKey +!if kBrowseSearch > 0 { bne @BrowseDispatch ldx #kBrowseSearch +} ; execution falls through here @BrowseDispatch @@ -59,6 +62,9 @@ kBrowseQuit = 11 @j jsr $FDFD ; SMC jmp @BrowseModeInputLoop +;------------------------------------------------------------------------------ +; internal functions + OnBrowseSearch sta InputBuffer lda #$01 @@ -66,9 +72,13 @@ OnBrowseSearch jmp SearchMode OnBrowsePrevious - +LDX16 gGameToLaunch - +CPX16_0 - bne @notFirstGame + jsr AnyGameSelected + ; A/Y = gGameToLaunch + bcs @goToLastGame ; if no game selected, select last game + tax ; X/Y = gGameToLaunch + tya ; set up first comparison in CPX16 macro + +CPX16_0_NE @notFirstGame ; if first game selected, select last game +@goToLastGame +LDX16 GameCount @notFirstGame +DEX16 @@ -77,14 +87,15 @@ OnBrowsePrevious OnBrowseNext +LDX16 gGameToLaunch +INX16 - +CPX16ADDR GameCount - bne notLastGame + +CPX16ADDR_NE GameCount, notLastGame ldx #0 ldy #0 notLastGame +STX16 gGameToLaunch jmp OnBrowseChanged +ReloadIndexAndLaunch + jsr ReloadSearchIndex OnBrowseLaunch jsr PlayGame jsr BlankHGR @@ -97,13 +108,15 @@ OnBrowseCheat OnBrowseTab jsr MiniAttractMode cmp #$8D - beq OnBrowseLaunch + beq ReloadIndexAndLaunch ; execution falls through here ForceBrowseChanged + jsr ReloadSearchIndex bit CLEARKBD ; execution falls through here OnBrowseChanged ; in: gGameToLaunch = game index (word) +; gSearchStore populated jsr SwitchToBank2 jsr EnableAcceleratorAndSwitchToBank1 jsr LoadGameTitleOffscreen @@ -116,8 +129,6 @@ BrowseHelpWrapper jsr Help jmp ForceBrowseChanged -;------------------------------------------------------------------------------ - BrowseDispatchTableLo !byte OnBrowseSearch !byte >OnBrowsePrevious @@ -144,39 +156,42 @@ BrowseDispatchTableHi !byte >SoftBell !byte >Joystick !byte >OnQuit + !byte >AllSHRSlideshow -kNumBrowseKeys = 14 +kNumBrowseKeys = 15 ; number of entries in next 2 tables (each) BrowseKeys + !byte $80 ; Ctrl-@ = SHR-only slideshow !byte $83 ; Ctrl-C = toggle cheat mode !byte $81 ; Ctrl-A = about !byte $AF ; '/' = help !byte $BF ; '?' = help !byte $A0 ; Space = mini attract mode !byte $89 ; TAB = mini attract mode - !byte $8D ; ENTER = launch current game - !byte $9B ; Esc = switch to search mode - !byte $8A ; down arrow = next - !byte $95 ; right arrow = next - !byte $8B ; up arrow = previous - !byte $88 ; left arrow = previous !byte $90 ; Ctrl-P = launch joystick calibration program !byte $91 ; Ctrl-Q = quit + !byte $9B ; Esc = switch to search mode + !byte $8D ; ENTER = launch current game + !byte $8B ; up arrow = previous + !byte $8A ; down arrow = next + !byte $88 ; left arrow = previous + !byte $95 ; right arrow = next BrowseKeyDispatch + !byte kBrowseSHR !byte kBrowseCheat !byte kBrowseCredits !byte kBrowseHelp !byte kBrowseHelp !byte kBrowseTab !byte kBrowseTab - !byte kBrowseLaunch - !byte kBrowseExitToSearch - !byte kBrowseNext - !byte kBrowseNext - !byte kBrowsePrevious - !byte kBrowsePrevious !byte kBrowseJoystick !byte kBrowseQuit + !byte kBrowseExitToSearch + !byte kBrowseLaunch + !byte kBrowsePrevious + !byte kBrowseNext + !byte kBrowsePrevious + !byte kBrowseNext GameCount !word 0 diff --git a/src/ui.common.a b/src/ui.common.a index 4b0a3e9..d9cae21 100755 --- a/src/ui.common.a +++ b/src/ui.common.a @@ -59,7 +59,7 @@ Home ; clear and show DHGR page 1 without flickering ; ; in: none -; out: text page clobbered (but screen holes preserved) +; out: text page clobbered ; $2000..$3FFF/main and /aux cleared ;------------------------------------------------------------------------------ BlankDHGR @@ -68,11 +68,13 @@ BlankDHGR sta WRITEAUXMEM jsr ClearHGR1 ; clear hi-res screen 1 in auxmem sta WRITEMAINMEM + lda #1 + sta OffscreenPage ; /!\ execution falls through here to DHGRMode ;------------------------------------------------------------------------------ ; DHGRMode -; switch to DHGR mode (HARDER THAN IT SOUNDS) +; switch to DHGR or DGR mode (HARDER THAN IT SOUNDS) ; ; in: none ; out: none @@ -92,9 +94,9 @@ DHGRMode sta DHIRESOFF sta DHIRESON ; then turn DHGR on - bit PAGE1 + jsr ToggleOffscreenPage + jsr ShowOtherPage lda #1 - sta OffscreenPage sta gMachineInDHGRMode jsr UnwaitForVBL jmp HGRMode diff --git a/src/ui.credits.a b/src/ui.credits.a index 5a40b56..7d84ce1 100644 --- a/src/ui.credits.a +++ b/src/ui.credits.a @@ -1,13 +1,50 @@ ;license:MIT -;(c) 2018-2020 by 4am +;(c) 2018-2021 by 4am & qkumba ; ; credits page ; ; Public functions -; - Credits ; - Help +; - Credits ; +;------------------------------------------------------------------------------ +; Help +; display per-game or global help page and wait +; +; in: none +; out: see above +;------------------------------------------------------------------------------ +Help + jsr GetGameToLaunch + bcs @global + +ST16 @game + + jsr LoadIndexedFile +@okvsPtr !word gSearchCache + !word kGameHelpIndexRecord + + jsr okvs_find + !word @okvsPtr +@game !word $FDFD ; SMC + +ST16 @indexRecordPtr + + jsr LoadIndexedFile + !word $800 +@indexRecordPtr + !word $FDFD ; SMC + + clc + bcc .clearAndDisplayHelp ; always branches + +@global jsr LoadIndexedFile ; load help text into $800 + !word $800 + !word kHelpTextRecord + + jsr LoadHelpOffscreen ; load fancy backdrop + ldx #7 + bne .displayHelp ; always branches + ;------------------------------------------------------------------------------ ; Credits ; display credits page and wait @@ -17,17 +54,50 @@ ; all other flags and registers clobbered ;------------------------------------------------------------------------------ Credits - jsr LoadFile ; load credits text into $8000 - !word kRootDirectory - !word kCreditsFile - !word $8000 --- jsr ForceHGRMode + jsr LoadIndexedFile ; load credits text into $800 + !word $800 + !word kCreditsRecord +.clearAndDisplayHelp + jsr ForceHGRMode jsr ClearOffscreen - ldx #0 -- lda OffscreenPage + ldx #0 ; left margin (0 for credits, different for global help) +.displayHelp + lda OffscreenPage ror ; draw on offscreen page - +LDADDR $8000 - jsr DrawPage ; draw credits + +LDADDR $800 + +ST16 PTR +;DrawPage inlined here +; +; PTR contains address of array of length-prefixed strings +; length #$FF terminates +; X contains 0-indexed left margin (HTAB) +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; drawing starts at VTAB 0 +; each line starts at column X which was passed in (0-indexed) +; clobbers $FF +; clobbers A/X/Y +; preserves C, other flags clobbered + stx $FF + ldx #0 + stx VTAB + php ; save C, but Z=1 because of ldx #0 +@drawLine + lda $FF + sta HTAB + jsr DrawString_PTR_is_already_set + bmi @donePage + clc + adc PTR + sta PTR + bcc + + inc PTR+1 ++ plp ; restore C to whatever it was on entry + php + beq @drawLine ; always branches +@donePage + plp +;end inline jsr ShowOtherPage ; show credits jsr WaitForKeyFor30Seconds; wait bit CLEARKBD ; don't care about key @@ -41,28 +111,3 @@ Credits jsr ToggleCheat + sec ; if called from search mode, tell caller to refresh rts - -;------------------------------------------------------------------------------ -; Help -; display per-game or global help page and wait -; -; in: none -; out: see above -;------------------------------------------------------------------------------ -Help - jsr GetGameToLaunch - bcs @global - +ST16 @fname - jsr LoadFile - !word kGameHelpDirectory -@fname !word $FDFD ; SMC - !word $8000 - clc - bcc -- ; always branches -@global jsr LoadFile ; load help text into $8000 - !word kRootDirectory - !word kHelpTextFile - !word $8000 - jsr LoadHelpOffscreen ; load fancy backdrop - ldx #7 - bne - ; always branches diff --git a/src/ui.font.a b/src/ui.font.a index 5d28cbc..9670c0d 100644 --- a/src/ui.font.a +++ b/src/ui.font.a @@ -3,40 +3,162 @@ ; ; hi-res font drawing routines ; -; Glue functions that handle bank switching and calling the real font drawing routines -; that live in LC RAM 2 now. -; ; Public functions -; - DrawPage ; - Draw40Chars ; - DrawCenteredString ; - DrawString -; - DrawBuffer ; -DrawString - jsr SwitchToBank2 - jsr DrawStringInternal - bmi JmpSwitch ; always - -DrawPage - jsr SwitchToBank2 - jsr DrawPageInternal - -JmpSwitch - jmp SwitchToBank1 - Draw40Chars - jsr SwitchToBank2 - jsr Draw40CharsInternal - beq JmpSwitch ; always +; A/Y contains address of character buffer +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; $25 contains textpage line (0..23) (this is the standard VTAB address) +; drawing starts at HTAB 0 +; increments VTAB on exit +; sets HTAB to 0 on exit +; Z=1 on exit +; clobbers A/X/Y + jsr + + ldx #40 + jsr .DrawBufferInternal ++ ldx #0 + stx HTAB + rts DrawCenteredString - jsr SwitchToBank2 - jsr DrawCenteredStringInternal - bmi JmpSwitch ; always +; A/Y contains address of length-prefixed string +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; $25 contains textpage line (0..23) (this is the standard VTAB address) +; clobbers A/X/Y + +ST16 PTR + php + ldy #0 + lda #40 + sec + sbc (PTR),y + lsr + sta HTAB + plp + jmp DrawString_PTR_is_already_set -DrawBuffer - jsr SwitchToBank2 - jsr DrawBufferInternal - bmi JmpSwitch ; always +DrawString +; A/Y contains address of length-prefixed string +; length can be 0 +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; $24 contains starting column (0..39) (this is the standard HTAB address) +; $25 contains textpage line (0..23) (this is the standard VTAB address) +; clobbers A/X/Y + +ST16 PTR +DrawString_PTR_is_already_set + ldy #0 + lda (PTR),y + inc PTR + bne + + inc PTR+1 ++ tax + bpl + + rts ++ + +LD16 PTR + ; /!\ execution falls through here to .DrawBufferInternal + +.DrawBufferInternal +; [private] +; A/Y contains address of character buffer +; X contains buffer length (0..40) +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; characters MUST have high bit off (0x00..0x7F) +; special characters (0x00..0x1F) will be drawn +; $24 contains starting column (0..39) (this is the standard HTAB address) +; $25 contains textpage line (0..23) (this is the standard VTAB address) +; all characters are drawn on the same line +; HTAB is incremented for each character +; clobbers X,Y +; increments VTAB on exit +; A=buffer length on exit +; N=0,Z=0 on exit + +ST16 DBISrc+1 + php + lda VTAB + asl + asl + asl +; routine to calculate memory address within HGR page +; and self-modify addresses within draw loop that follows +; (routine clobbers A and Y but preserves X) + asl + tay + and #$F0 + bpl @calc1 + ora #$05 +@calc1 bcc @calc2 + ora #$0A +@calc2 asl + asl + sta @hgrlo+1 + tya + and #$0E + adc #$10 + asl @hgrlo+1 + rol + plp + bcc + + eor #$60 + clc ++ + sta DBIRow0+2 + adc #$04 + sta DBIRow1+2 + adc #$04 + sta DBIRow2+2 + adc #$04 + sta DBIRow3+2 + adc #$04 + sta DBIRow4+2 + adc #$04 + sta DBIRow5+2 + adc #$04 + sta DBIRow6+2 + adc #$04 + sta DBIRow7+2 +@hgrlo lda #$FD + adc HTAB + sta DBIRow0+1 + sta DBIRow1+1 + sta DBIRow2+1 + sta DBIRow3+1 + sta DBIRow4+1 + sta DBIRow5+1 + sta DBIRow6+1 + sta DBIRow7+1 + txa + pha + bpl + ; always branches because X is 0..40 +DBILoop +DBISrc ldy $FDFD,x + lda FontDataRow0,y +DBIRow0 sta $FDFD,x + lda FontDataRow1,y +DBIRow1 sta $FDFD,x + lda FontDataRow2,y +DBIRow2 sta $FDFD,x + lda FontDataRow3,y +DBIRow3 sta $FDFD,x + lda FontDataRow4,y +DBIRow4 sta $FDFD,x + lda FontDataRow5,y +DBIRow5 sta $FDFD,x + lda FontDataRow6,y +DBIRow6 sta $FDFD,x + lda FontDataRow7,y +DBIRow7 sta $FDFD,x + inc HTAB ++ dex + bpl DBILoop + pla ; A = buffer length (passed in in X) + inc VTAB + rts diff --git a/src/ui.font.data.lc2.a b/src/ui.font.data.a similarity index 100% rename from src/ui.font.data.lc2.a rename to src/ui.font.data.a diff --git a/src/ui.font.lc2.a b/src/ui.font.lc2.a deleted file mode 100644 index 0958ce0..0000000 --- a/src/ui.font.lc2.a +++ /dev/null @@ -1,221 +0,0 @@ -;license:MIT -;(c) 2018-2020 by 4am -; -; hi-res font drawing routines -; -; /!\ These live in LC RAM 2 and rely on the font data which is also in LC RAM 2. /!\ -; Code in LC RAM 1 (which is most program code) should call the functions in ui.font -; which handle bank switching for you. -; - -DrawPageInternal -; A/Y contains address of character buffer -; X contains 0-indexed left margin (HTAB) -; carry bit clear -> draw on page 1 -; carry bit set -> draw on page 2 -; drawing starts at VTAB 0 -; each line starts at column X which was passed in (0-indexed) -; clobbers PTR -; clobbers $FF -; clobbers A/X/Y -; preserves all flags, by a quirk of implementation - php - stx $FF - ldx #0 - stx VTAB - +ST16 PTR -@drawLine - lda $FF - sta HTAB - ldy #0 -@parseLine - lda (PTR),y - cmp #$5B ; '[' at beginning on line - bne + ; ends the parsing - tya - beq @donePage -+ cmp #$0A - beq @doneParsingLine - ldx #5 -- cmp @subs_a,x - bne @nosub - lda @subs_b,x - sta (PTR),y -@nosub - dex - bpl - - iny - bne @parseLine -@doneParsingLine - sty SAVE - tya - beq @skip - ldx SAVE - +LD16 PTR - plp - php - jsr DrawBufferInternal -@skip inc SAVE ; skip carriage return - lda SAVE ; advance PTR to start of next line - clc - adc PTR - sta PTR - bcc + - inc PTR+1 -+ inc VTAB ; this will print 255 lines if you give it - bne @drawLine ; 255 lines, so don't do that -@donePage - plp - rts -@subs_a - !byte $2A,$7E,$3C,$3E,$24,$25 -@subs_b - !byte $10,$11,$08,$15,$0E,$0F - -Draw40CharsInternal -; A/Y contains address of character buffer -; carry bit clear -> draw on page 1 -;v carry bit set -> draw on page 2 -; $25 contains textpage line (0..23) (this is the standard VTAB address) -; drawing starts at HTAB 0 -; increments VTAB -; sets HTAB to 0 on exit -; clobbers A/X/Y - jsr + - ldx #40 - jsr DrawBufferInternal - inc VTAB -+ ldx #0 - stx HTAB - rts - -DrawCenteredStringInternal -; A/Y contains address of length-prefixed string -; carry bit clear -> draw on page 1 -; carry bit set -> draw on page 2 -; $25 contains textpage line (0..23) (this is the standard VTAB address) -; clobbers A/X/Y -; clobbers PTR/PTR+1 - +ST16 PTR - - ldy #0 - php - lda #40 - sec - sbc (PTR),y - lsr - sta HTAB - plp - beq + - -DrawStringInternal -; A/Y contains address of length-prefixed string -; carry bit clear -> draw on page 1 -; carry bit set -> draw on page 2 -; $24 contains starting column (0..39) (this is the standard HTAB address) -; $25 contains textpage line (0..23) (this is the standard VTAB address) -; clobbers A/X/Y -; clobbers PTR/PTR+1 - +ST16 PTR - - ldy #0 -+ lda (PTR),y - tax - inc PTR - bne + - inc PTR+1 -+ - +LD16 PTR - ; /!\ execution falls through here to DrawBufferInternal - -DrawBufferInternal -; A/Y contains address of character buffer -; X contains buffer length (1..40) -; carry bit clear -> draw on page 1 -; carry bit set -> draw on page 2 -; characters MUST have high bit off (0x00..0x7F) -; special characters (0x00..0x1F) will be drawn -; $24 contains starting column (0..39) (this is the standard HTAB address) -; $25 contains textpage line (0..23) (this is the standard VTAB address) -; all characters are drawn on the same line -; HTAB is incremented for each character -; VTAB is NOT incremented -; clobbers A/X/Y - +ST16 DBISrc+1 - php - dex - lda VTAB - asl - asl - asl -; routine to calculate memory address within HGR page -; and self-modify addresses within draw loop that follows -; (routine clobbers A and Y but preserves X) - asl - tay - and #$F0 - bpl @calc1 - ora #$05 -@calc1 bcc @calc2 - ora #$0A -@calc2 asl - asl - sta @hgrlo+1 - tya - and #$0E - adc #$10 - asl @hgrlo+1 - rol - plp - bcc + - eor #$60 - clc -+ - sta DBIRow0+2 - adc #$04 - sta DBIRow1+2 - adc #$04 - sta DBIRow2+2 - adc #$04 - sta DBIRow3+2 - adc #$04 - sta DBIRow4+2 - adc #$04 - sta DBIRow5+2 - adc #$04 - sta DBIRow6+2 - adc #$04 - sta DBIRow7+2 -@hgrlo lda #$FD - clc - adc HTAB - sta DBIRow0+1 - sta DBIRow1+1 - sta DBIRow2+1 - sta DBIRow3+1 - sta DBIRow4+1 - sta DBIRow5+1 - sta DBIRow6+1 - sta DBIRow7+1 -DBILoop -DBISrc ldy $FDFD,x - lda FontDataRow0,y -DBIRow0 sta $FDFD,x - lda FontDataRow1,y -DBIRow1 sta $FDFD,x - lda FontDataRow2,y -DBIRow2 sta $FDFD,x - lda FontDataRow3,y -DBIRow3 sta $FDFD,x - lda FontDataRow4,y -DBIRow4 sta $FDFD,x - lda FontDataRow5,y -DBIRow5 sta $FDFD,x - lda FontDataRow6,y -DBIRow6 sta $FDFD,x - lda FontDataRow7,y -DBIRow7 sta $FDFD,x - inc HTAB - dex - bpl DBILoop - rts diff --git a/src/ui.offscreen.a b/src/ui.offscreen.a index b117260..1884fa9 100644 --- a/src/ui.offscreen.a +++ b/src/ui.offscreen.a @@ -8,8 +8,10 @@ ; - LoadCoverOffscreen ; - LoadHelpOffscreen ; - LoadGameTitleOffscreen +; - UnpackHGRTitle ; - ResyncPage ; - ShowOtherPage +; - ShowOtherDHGRPage ; - ToggleOffscreenPage ; - ClearScreens ; - ClearOffscreen @@ -48,7 +50,7 @@ OffscreenPage = * + 1 ; out: all flags and registers clobbered ;------------------------------------------------------------------------------ LoadTitleOffscreen - lda #kCoverFile ; all of these are on the same page - !byte $00 -+ !byte $FD ; SMC - rts - -LoadGameTitleOffscreen -; in: gGameToLaunch = index into gGamesListStore (word) - jsr GetGameToLaunch - +ST16 @fname - bit MachineStatus ; if < 128K, don't bother checking for DHGR title - bvc @hgr - jsr okvs_get_current - ; (PTR) -> game display name + bitfield of game info - ; Y = 0 - lda (PTR),y ; A = game display name length + 1 - sta SAVE - tay - lda (PTR),y ; A = game info bitfield - ;;and #HAS_DHGR_TITLE - bmi @dhgr -@hgr + sta @indexlo jsr ForceHGRMode jsr GetOffscreenAddress sta @addrhi - jsr LoadFile - !word kHGRTitleDirectory -@fname !word $FDFD ; SMC + jsr LoadIndexedFile !byte $00 @addrhi !byte $FD ; SMC +@indexlo !byte $FD ; SMC + !byte >kCoverRecord ; all of these are on the same page rts -@dhgr - jsr BlankDHGR - +LD16 @fname - +ST16 + - jsr LoadDHRFile - !word kDHGRTitleDirectory -+ !word $FDFD + +LoadGameTitleOffscreen +; in: gGameToLaunch = index into gSearchStore (word) + jsr GetGameToLaunch + jsr okvs_next_field + jsr okvs_next_field_PTR_is_already_set + ; (PTR) -> length-prefixed game info bitfield + ; Y = 0 + iny ; Y = 1 + lda (PTR), y ; A = game info bitfield + bpl .LoadHGRGameTitleOffscreen ; bit 7 = 1 if game has DHGR title, 0 if HGR title + + jsr SwitchToBank2 +- iny + lda (PTR), y + sta OKVS_CACHE-1, y + cpy #6 + bne - +LoadIndexedDHRFile + jsr SwitchToBank2 + lda #0 + sta OKVS_CACHE + lda #$20 ; load first $2000 bytes into auxiliary memory + sta OKVS_CACHE + 5 + jsr GetOffscreenAddress + sta @dhgr_addr_aux + 1 + sta @dhgr_addr_main + 1 + jsr LoadAuxIndexedFile +@dhgr_addr_aux + !word $FD00 ; SMC high byte + !word OKVS_CACHE + jsr SwitchToBank2 + lda OKVS_CACHE + 2 ; offset += $2000 (note: stored in big-endian) + clc + adc #$20 + sta OKVS_CACHE + 2 + bcc + + inc OKVS_CACHE + 1 ++ jsr LoadIndexedFile ; load next $2000 bytes into main memory +@dhgr_addr_main + !word $FD00 ; SMC high byte + !word OKVS_CACHE + rts + +.LoadHGRGameTitleOffscreen + jsr ForceHGRMode + jsr GetOffscreenAddress + sta @hgr_addr + 1 + eor #$1F + sta @poke+2 + sta @peek+2 +@poke sta $3FFD ; SMC high byte to clear screen hole before load + +LD16 PTR + +ST16 @hgrIndexRecordPtr + jsr LoadIndexedFile +@hgr_addr + !word $FD00 ; SMC high byte +@hgrIndexRecordPtr + !word $FDFD ; SMC +@peek lda $3FFD ; SMC high byte + cmp #$4C ; Check if screen hole now contains a JMP + beq OFFSCREENRTS ; if so, file was not packed, so skip unpack + ; /!\ execution falls through here to UnpackHGRTitle +;------------------------------------------------------------------------------ +; UnpackHGRTitle +; unpack data from screen holes of the off screen HGR page +; +;------------------------------------------------------------------------------ +UnpackHGRTitle + jsr GetOffscreenAddress + sta src+2 + ora #$1E + sta dest+2 + lda #$00 + sta src+1 + sta dest+1 + lda #3 + sta $E0 +loop + ldx #0 +-- ldy #$78 +src +- lda $0000,y ;smc +dest + sta $0000,x ;smc + inx + iny + bpl - + tya ; y = #$80 + eor src+1 + sta src+1 + bne + + inc src+2 ++ cpx #$78 + bne -- + lda dest+1 + eor #$80 + sta dest+1 + bne + + inc dest+2 ++ dec $E0 + bpl loop +OFFSCREENRTS rts ;------------------------------------------------------------------------------ @@ -162,14 +233,15 @@ ClearMem ;------------------------------------------------------------------------------ CopyHGR ldx #$20 - ldy #$B9 ; LDY + ldy #$B9 ; LDA $0000,Y opcode + sty PageFrom sta PageTo+2 +ClearToBlack lda #$00 ClearGR ldy #0 -PageFrom lda $FD00,y ; SMC -PageTo sta $FD00,y ; SMC +PageFrom lda $FD00,y ; SMC address high byte, also SMC opcode (might be BIT) +PageTo sta $FD00,y ; SMC address high byte iny bne PageFrom inc PageFrom+2 @@ -198,6 +270,10 @@ ShowOtherPage + bit PAGE1 ; show page 1 rts +ShowOtherDHGRPage + jsr ToggleOffscreenPage + jmp DHGRMode + ;------------------------------------------------------------------------------ ; ToggleOffscreenPage ; switch the internal variable that tracks which HGR page is showing diff --git a/src/ui.overlay.a b/src/ui.overlay.a index 8ded1f8..74a3eaf 100644 --- a/src/ui.overlay.a +++ b/src/ui.overlay.a @@ -20,12 +20,14 @@ ReturnToPlay !byte $0D !text " to play" -kCheatsEnabled = 6 ; index of 'cheats enabled' string in following table +kCheatsEnabled = 8 ; index of 'cheats enabled' string in following table kCheatDescriptionLo !byte sInfiniteLives !byte >sInfiniteWeapons !byte >sInfiniteLivesAndWeapons + !byte >sInfiniteLivesAndTime + !byte >sInfiniteTime !byte >sInvincibility !byte >sInGame !byte >sCheatsEnabled @@ -42,46 +46,60 @@ sNoCheats !text "no cheat" sInfiniteLives !byte 18 ; length - !byte $16 ; bolt character + !byte $16 ; padlock character !text " " !text "infinite lives" !text " " - !byte $16 ; bolt character + !byte $16 ; padlock character sInfiniteWeapons !byte 20 ; length - !byte $16 ; bolt character + !byte $16 ; padlock character !text " " !text "infinite weapons" !text " " - !byte $16 ; bolt character + !byte $16 ; padlock character sInfiniteLivesAndWeapons !byte 28 ; length - !byte $16 ; bolt character + !byte $16 ; padlock character !text " " !text "infinite lives & weapons" !text " " - !byte $16 ; bolt character + !byte $16 ; padlock character +sInfiniteLivesAndTime + !byte 25 ; length + !byte $16 ; padlock character + !text " " + !text "infinite lives & time" + !text " " + !byte $16 ; padlock character +sInfiniteTime + !byte 17 ; length + !byte $16 ; padlock character + !text " " + !text "infinite time" + !text " " + !byte $16 ; padlock character sInvincibility !byte 14 ; length - !byte $16 ; bolt character + !byte $16 ; padlock character !text " " !text "invincible" !text " " - !byte $16 ; bolt character + !byte $16 ; padlock character sInGame !byte 18 ; length - !byte $16 ; bolt character + !byte $16 ; padlock character !text " " !text "in-game cheats" !text " " - !byte $16 ; bolt character + !byte $16 ; padlock character sCheatsEnabled !byte 18 ; length - !byte $16 ; bolt character + !byte $16 ; padlock character !text " " !text "cheats enabled" !text " " - !byte $16 ; bolt character + !byte $16 ; padlock character sCheatDescriptionPrefix !byte 2 ; length !byte $03 ; vertical line character @@ -124,16 +142,18 @@ DrawUI jsr GetGameToLaunch ; get current game, if any bcs @doneWithLine2 ; if no game, nothing more to do on UI line 2 - jsr GetGameDisplayName - ; A/Y -> game display name + bitfield of game info - +ST16 PTR - ldy #0 - lda (PTR),y ; A = game display name length + 1 - sta SAVE + ; A/Y -> key of current game (in gSearchStore) + jsr okvs_next_field ; (PTR) -> display name of current game + ; Y = 0 + lda (PTR), y tay - lda (PTR),y ; A = game info bitfield + iny + sty SAVE + iny + lda (PTR), y ; A = game info bitfield sta gGameToLaunchInfo ldy #0 + - iny @printCursor lda #$FD ; SMC @@ -194,7 +214,7 @@ DrawUI ldy #0 @dotloop iny - lda (PTR),y ; (PTR) still points to game display name + game info bitfield + lda (PTR),y ; (PTR) still points to game display name ora #$20 ; force lower-case always cmp InputBuffer,x bne + @@ -253,17 +273,25 @@ gDrawingOnscreen=*+1 jsr AddToPath +LDADDR sCheatDescriptionSuffix jsr AddToPath - inc VTAB plp +LDADDR gPathname jsr DrawCenteredString ; draw cheat UI line 2 jsr MaybeRedrawUIForDHGR ; transform for DHGR if this is a DHGR title screen @uidone lda #0 sta gDrawingOnscreen - clc - jmp ShowOtherPage + bit MachineStatus + bvc + + bit gGameToLaunchInfo + bpl + + jmp ShowOtherDHGRPage ++ jmp ShowOtherPage + +;------------------------------------------------------------------------------ +; internal functions CheckCheats +; out: (SAVE) -> length-prefixed string, either a game-specific description +; or the global 'cheats enabled' message ldx #kCheatsEnabled jsr AnyGameSelected bcs + @@ -276,11 +304,19 @@ gGameToLaunchInfo=*+1 sta SAVE lda kCheatDescriptionHi,x sta SAVE+1 -- rts +OVERLAYRTS + rts MaybeRedrawUIForDHGR +; If this is a DHGR title screen, then redraw the already-drawn overlay +; for double hi-res. This allows us to use a single font and drawing +; routines for both HGR and DHGR. There is a small amount of flicker +; if we're redrawing directly on the visible screen without swapping +; pages (e.g. adding a dot without changing the selected game), but +; gDrawingOnscreen tracks this and we reduce the redrawing to an +; absolute minimum to reduce flicker. bit MachineStatus - bvc - + bvc OVERLAYRTS bit gGameToLaunchInfo - bpl - + bpl OVERLAYRTS jmp RedrawForDHGR diff --git a/src/ui.search.mode.a b/src/ui.search.mode.a index cf69fde..c6f5c17 100644 --- a/src/ui.search.mode.a +++ b/src/ui.search.mode.a @@ -21,6 +21,7 @@ kInputCheat = 8 kInputError = 9 kInputJoystick = 10 kInputQuit = 11 +kInputSHR = 12 InputDispatchTableLo !byte OnSearch !byte >OnClear @@ -48,8 +50,9 @@ InputDispatchTableHi !byte >OnError !byte >Joystick !byte >OnQuit + !byte >AllSHRSlideshow -kNumInputKeys = 12 +kNumInputKeys = 13 ; number of entries in next 2 tables (each) InputKeys !byte $83 ; Ctrl-C = toggle cheat mode @@ -66,6 +69,7 @@ InputKeys ; or switch to mega attract mode !byte $90 ; Ctrl-P = launch joystick calibration program !byte $91 ; Ctrl-Q = quit + !byte $80 ; Ctrl-@ = SHR-only slideshow InputKeyDispatch !byte kInputCheat !byte kInputCredits @@ -79,6 +83,7 @@ InputKeyDispatch !byte kInputClear !byte kInputJoystick !byte kInputQuit + !byte kInputSHR .noKeyMatch jsr IsSearchKey @@ -112,7 +117,8 @@ SearchMode txs stx gGameToLaunch ; $FFFF = no game selected stx gGameToLaunch+1 - jsr BuildSearchStore + stx gMegaAttractModeFilter ; $FF = all module types + jsr ReloadSearchIndex jsr Home ; clear screen (switches to text mode) stx OffscreenPage ; don't show text page 2 by accident jsr OnInputChanged ; draw UI offscreen @@ -162,7 +168,8 @@ OnTab jsr MiniAttractMode cmp #$8D ; if we exited mini attract mode bne .req_redraw ; by pressing Enter, launch the game - + jsr ReloadSearchIndex ; must reload search index before calling PlayGame + ; /!\ execution falls through here OnLaunch ldx gGameToLaunch+1 inx @@ -170,7 +177,7 @@ OnLaunch jsr PlayGame .req_redraw - sec ; tell caller to redraw UI + sec ; tell caller to reload search index and redraw UI from scratch rts OnCheat @@ -199,8 +206,10 @@ FindMatchingTitle jsr SwitchToBank2 jsr EnableAcceleratorAndSwitchToBank1 - jsr ResetTextRank + jsr FindTitleInCache + bcc + ; sets BestMatchIndex on success + jsr ResetTextRank jsr okvs_iter_values ; iterate through all game display names !word gSearchStore ; and rank them for the best match !word TextRankCallback ; to the current input buffer diff --git a/src/ui.wait.a b/src/ui.wait.a index 4a78aad..2d00328 100644 --- a/src/ui.wait.a +++ b/src/ui.wait.a @@ -4,7 +4,6 @@ ; UI functions for doing things then waiting, or waiting then doing things ; ; - ExecuteTransitionAt6000AndWait -; - ExecuteTransitionAt6400AndWait ; - ExecuteTransitionAtA000AndWait ; - ExecuteTransitionAndWait ; - WaitForKeyFor30Seconds @@ -13,9 +12,6 @@ ExecuteTransitionAt6000AndWait ldy #$60 +HIDE_NEXT_2_BYTES -ExecuteTransitionAt6400AndWait - ldy #$64 - +HIDE_NEXT_2_BYTES ExecuteTransitionAtA000AndWait ldy #$A0 ; /!\ execution falls through here to ExecuteTransitionAndWait @@ -31,6 +27,8 @@ ExecuteTransitionAndWait lda #0 +ST16 @j+1 @j jsr $FDFD ; SMC call transition effect code + sta WRITEMAINMEM ; several transition effects exit with + ; auxmem writeable so we reset it here ldx #$20 ; picture is showing so now we wait - lda #0 jsr WaitForKeyWithTimeout @@ -85,10 +83,9 @@ CoverFade jsr ShowOtherPage lda OffscreenPage beq CoverFade - jsr LoadFile ; load transition effect code at $6000 - !word kFXDirectory - !word kCoverFadeFile + jsr LoadIndexedFile ; load transition effect code at $6000 !word $6000 + !word kCoverFadeRecord jsr $6000 ; call transition effect jmp MegaAttractMode ; exit via mega attract mode !if (RELBASE != $2000) and (>WaitForKeyFor30Seconds != >*) {