commit 5a2714014a41c7e72b3d1996f3815eccabf9fc1a Author: Joerg Deckert Date: Fri May 2 20:16:37 2014 +0200 initial commit diff --git a/BOULDER.md b/BOULDER.md new file mode 100644 index 0000000..385d6c5 --- /dev/null +++ b/BOULDER.md @@ -0,0 +1,83 @@ +Hive-Computer-Projekt: Boulder Dash - Hive-Version +================================================== + + http://hive-project.de + +Basierend auf dem Fanprojekt diverser Propellerköpfe: + + http://forums.parallax.com/forums/default.aspx?f=33&m=263404 + +Besonderer Dank an Pex "Mahoney" Tufvesson für die coole Musik!: + + http://mahoney.c64.org + http://www.livet.se/visa + + +Installation: +------------- + +- Alle Dateien aus dem Ordner "bin" auf eine Hive-SD-Card kopieren. +- "bd" : Startest das Game im PAL-Modus + "bd n": Startet das Game im NTSC-Modus + +Tasten: +------- + +ESC Stop Button A +Space Pause Button B +LShift Start +LCTRL Select +Cursor + +Anpassungen für den Hive +------------------------ + +09-01-2010 - Entfernung der Hardwareerkennung + - Anpassung Konfiguration an Hive/Bellatrix + - Gamecontr. entfernt + - Auskommentierung Sound +12-01-2010 - Soundadapter optimiert + - Scrolltext im Titelbildschirm eingefügt +19-04-2010 - Anpassung an TriOS: Boulder läuft jetzt auch aus dem Verzeichnis. + Bedingt durch das neue, etwas trägere WAV-Soundsystem, habe ich + einige Effekte durch HSS/SFX ersetzt. + +Zur Hive-Version: +Das Game an sich, also der ursprüngliche Basiscode aus dem Parallax-Forum, +läuft auf einem einzigen Propellerchip! Was war zu tun um diese Version an +den Hive anzupassen: + +1. Der Code kann im wesentlichen fast ausschließlich auf Bellatrix laufen. +Dafür müssen die entsprechenden Belegungen der IO-Pins für Video und Keyboard +angepasst werden. + +2. Da Bellatrix keinen Sound ausgeben kann, sondern diese Aufgabe im Hive +Administra übernimmt, muß die Soundausgabe angepasst werden. Im Originalcode +übernimmt das Objekt "sound.spin" diese Aufgabe - welches wieder den SIDemu +in einer getrennten Cog startet. Hier zeigt sich die Stärke der SPIN-Objekte: +Für die Anpassung brauchte ich einfach nur ein neues Objekt gleicher Struktur +definieren, ohne das Hauptprogramm zu ändern. Dieses neue Soundobjekt startet +ebenfalls eine Cog, welche einzig die Aufgabe hat, die Kommunikation zu +Regnatix/Administra zu realisieren. + +3. Regnatix-Code: Tja, die Königin kann bei der ganzen Sache Däumchen drehen, +denn sie hat nur folgend Aufgaben in einer einzigen Cog zu bewältigen: + - Bellatrix-Code laden + - SFX-Slots in Administra initialisieren + - Warten bis Bellatrix einen Ton von sich geben möchte und Übermittlung dieser + Tonesequenz an Administra + +Damit werden natürlich auf der einen Seite massig Ressourcen in Bellatrix +gegenüber dem ursprünglichen Code frei und es sind durch die Verwendung von +HSS/SFX + Waveplayer + SDCard mehr Möglichkeiten gegeben. + +Bellatrix-Code : 20,5 KByte +Regnatix-Code : 3,2 KByte + +Bei diesen Werten ist zu beachten, dass der Regnatix das blanke IOS mit +2,6 KByte eingebunden hat - ohne Optimierung, denn ein Großteil der IOS- +Routinen sind in diesem Fall ungenutzt. + +Zeitaufwand : ca. 3 nette Abende ;) + +drohne235 diff --git a/README.md b/README.md new file mode 100644 index 0000000..63a0d98 --- /dev/null +++ b/README.md @@ -0,0 +1,135 @@ +Toolbox 2 +========= + +Futter für den Hive. Wie bei der ersten Toolbox genügt es den Inhalt des +Ordners "SDCARD" auf ein passendes Medium zu kopieren. Dieses mal ist das +Paket durch die Mediendateien allerdings recht groß geworden, aber es lohnt +sich. Wie gehabt, sind zu den Programmen wieder alle Quelltexte für eigene +Expermente enthalten. + +Inhalt: Ordner sounds +===================== + +AYS - Yamaha-Chipmusik +---------------------- +Diese Dateien können mit dem Y-Player abgespielt werden, wenn vorher der +passende Administra-Code geladen wird. Bei diesem und den folgenden Playern +und Tools gibt es meist die Möglichkeit mit dem Parameter /h einen Hilfetext +anzuzeigen. + +``` +> admym + ok +> cd sounds + ok +> cd ays + ok +> yplay /d + +``` +Mit dem Kommando "admsys" kann wieder der normale Administra-Code geladen +werden. + + +HSS - Hydra-Sound-System +------------------------ +HSS-Dateien sind 4-Kanal Soundtracker-Module in einem speziellen Format. Da +der HSS-code im Standardcode von Administra enthalten ist, können sie sofort +abgespielt werden. Im TriOS enthalten ist ein Player für die Kommandozeile +und in dieser Toolbox der StarTracker mit seiner Startrek-GUI. + +hplay /d - spielt alle HSS-module im aktuellen Verzeichnis ab + +Oder als Alternative den Startracker mit LCARS-GUI: + +stplay + + +SFX - HSS FX-Sounds +------------------- +In der HSS-Engine sind neben dem 4-Kanal-Tracker auch zwei Effektkanäle +enthalten. Der Hertbeat und die Fehlertöne im TriOS werden zum Beispiel damit +erzeugt. Ebenso die Soundeffekte in dem Game Boulder Dash. Im TriOS enthalten +ist das Tool "sfxtool", um diese Effekte zu entwerfen, so laden und zu +speichern. Ebenso können fertige Effekte als Spin-Quelltext exportiert werden, +um sie in eigene Programme einzubinden. Bei Interesse einfach mal in den +Quelltexten von Boulder Dash schauen. + + +SID - SID-Chip Musik vom C64 +---------------------------- +Dank der genialen SIDCog von Ahle2 können wir auf dem Hive dieses Soundformat +verwenden. Die Dateien im SID-Ordner sind Registerdumps von originalen C64- +Games und Demos. Im SID-Bios für Administra ist ein kompletter Playercode für +diese Dateien enthalten. Es ist sogar möglich, die original 3stimmigen Songs +durch einen Trick 6stimmig in Stereo zu genießen. Als Player ist momentan nur +ein Kommanduzeilentool und das passende Bios im TriOS integriert. + +``` +> admsid + ok +> cd sounds + ok +> cd sid + ok +> splay /d +``` + +Im Ordner sind weitere Unterordner mit vielen handverlesenen Songs. Mit dem +Parameter /m kann der Sound auch mono auf einer SIDCog ausgegeben werden. + +Inhalt: Ordner tbox-2 +===================== + +DEMO/3DMULTI +------------ +Dieses Demo ist ein reiner Bellatrix-Code. Leider kann das Prog nur per Reset +verlassen werden, da in Bella neben dem Demo kein Platz mehr für den Keyboard- +Treiber ist. Bei Gelegenheit wird der Code für den G0-Treiber umgesetzt, dann +wird es auch eine normale Rückkehroption geben. + + +DEMO/VECDEM +----------- +Dieser Bellatrix-Code ist ein kleines Experiment. Der zugrunde liegende VGA- +Treiber arbeitet mit einer Auflösung von 512 x 384 Pixel. Der Screenpuffer hat +eine Größe von 24 KByte, weshalb eine Anwendung mit Double Buffer nicht möglich +ist. Im Prinzip ist der Treiber Monochrom, aber für ein Tile von 32 x 32 Pixel +kann die Vordergrundfarbe ausgewählt werden. +Wie geschrieben ist kein Double Buffer möglich, wodurch Animationen nur sehr +begrenzt möglich sind, da man immer Phase für Phase zeichnen und wieder löschen +muss. Die Idee ist jetzt folgende: Im Prinzip könnte man sich den aufwendigen +Löschvorgang sparen, indem der VGA-Treiber bei der Darstellung sofort in PASM +diese Aufgabe übernimmt. Damit hat man natürlich einen Bildschirm, welcher +ständig in einer endlosen Schleife beschrieben werden muß, stopt dieser +Vorgang, wird der Screen beim nächsten Bildwechsel gelöscht. Ein wenig erinnert +dieses Prinzip an die Vectrex, wo ja der gleiche Effekt auftritt. + + +BOULDER DASH +------------ +Das legendre Game auf dem Hive mit einem tollen Remix des originalen Titelsongs +von Pex "Mahoney" Tufvesson. Das Spiel basiert auf dem Code aus dem +amerikanischen Propellerforum. Der Hauptcode läuft fast vollständig in +Bellatrix. Über Regnatix wird der Sound in Administra angesteuert. + +Steuerung: +Button A ESC +Button B Space +Start Left Shift, Enter +Steuerkreuz Pfeiltasten + + +SHOOT +----- +Beispiel für ein kleines Spiel mit dem Graphics-Objekt. Läuft im TV-Modus mit +Maussteuerung. Wie Boulder Dash läuft das Game fast vollständig in Bella, +Regnatix Steuert den Sound und liefert Daten für die Trackeranzeige im +Hintergrund zurück. + + +StarTracker +----------- +Soundplayer mit LCARS-interface für HSS-Module. Der Player spielt alle HSS- +Dateien im gleichen Verzeichnis ab. Benötigt wird die Startdatei "stplay" und +der Bellatrixcode "stplay.bel" für die Oberfläche. diff --git a/make.sh b/make.sh new file mode 100755 index 0000000..6c64350 --- /dev/null +++ b/make.sh @@ -0,0 +1,66 @@ +#! /bin/sh + +# Definitionen +##D="-D __DEBUG -D __LANG_EN" +##D="-D __LANG_EN" +D="-D __LANG_DE" + +# Pfade +##bin="../Bin" +bin="/home/ftp/hive" +sdtbox="${bin}/sdcard/tbox-2" +sdsnd="${bin}/sdcard/sounds" +sdsys="${bin}/sdcard/system" +libpath="../TriOS/lib" +BSTC="bstc" + +# ---------------------------------------------------------------- +# Alte Versionen löschen + +rm -rf ${sdsnd} +rm -rf ${sdtbox} +mkdir -p ${sdsnd} +mkdir -p ${sdtbox} +mkdir ${sdtbox}/demo +mkdir ${sdtbox}/boulder +mkdir ${sdtbox}/shoot +mkdir ${sdtbox}/stracker + +##rm -f ${sdsys}/xxxxxx +##mkdir -p ${sdsys} + +# ---------------------------------------------------------------- +# Daten kopieren + +cp -r sounds/* ${sdsnd} + +# ---------------------------------------------------------------- +# Bin-Dateien erzeugen + +${BSTC} -L ${libpath} ${D} -b -O a source/3dmulti/3dmulti.spin +mv 3dmulti.binary "${sdtbox}/demo/3dmulti.bel" + +${BSTC} -L ${libpath} ${D} -b -O a source/boulder/bellatrix/bd_pal.spin +${BSTC} -L ${libpath} ${D} -b -O a source/boulder/bellatrix/bd_ntsc.spin +mv bd_pal.binary "${sdtbox}/boulder/bd_pal.bin" +mv bd_ntsc.binary "${sdtbox}/boulder/bd_ntsc.bin" +${BSTC} -L ${libpath} ${D} -b -O a source/boulder/regnatix/bd.spin +mv bd.binary "${sdtbox}/boulder/bd.bin" +cp source/boulder/musik/bd.wav "${sdtbox}/boulder/" + +${BSTC} -L ${libpath} ${D} -b -O a source/shoot/bellatrix/shoot.spin +mv shoot.binary "${sdtbox}/shoot/shoot.bel" +${BSTC} -L ${libpath} ${D} -b -O a source/shoot/regnatix/shoot.spin +mv shoot.binary "${sdtbox}/shoot/shoot.bin" +cp source/shoot/musik/*.hss "${sdtbox}/shoot/" + +${BSTC} -L ${libpath} ${D} -b -O a source/vecdem/vecdem.spin +mv vecdem.binary "${sdtbox}/demo/vecdem.bel" + +${BSTC} -L ${libpath} ${D} -b -O a source/stracker/bellatrix/stint.spin +cp stint.binary "${sdsnd}/hss/stint.bin" +mv stint.binary "${sdtbox}/stracker/stint.bel" +${BSTC} -L ${libpath} ${D} -b -O a source/stracker/regnatix/stplay.spin +cp stplay.binary "${sdsnd}/hss/stplay.bin" +mv stplay.binary "${sdtbox}/stracker/stplay.bin" + diff --git a/sounds/ays/4stavebk_unde.ym b/sounds/ays/4stavebk_unde.ym new file mode 100644 index 0000000..c2e7f90 Binary files /dev/null and b/sounds/ays/4stavebk_unde.ym differ diff --git a/sounds/ays/Awesome 1_unde.ym b/sounds/ays/Awesome 1_unde.ym new file mode 100644 index 0000000..fc201a1 Binary files /dev/null and b/sounds/ays/Awesome 1_unde.ym differ diff --git a/sounds/ays/Axel Folley_unde.ym b/sounds/ays/Axel Folley_unde.ym new file mode 100644 index 0000000..23729bd Binary files /dev/null and b/sounds/ays/Axel Folley_unde.ym differ diff --git a/sounds/ays/Batman - The Movie 1_unde.ym b/sounds/ays/Batman - The Movie 1_unde.ym new file mode 100644 index 0000000..c8ca87c Binary files /dev/null and b/sounds/ays/Batman - The Movie 1_unde.ym differ diff --git a/sounds/ays/Batman - The Movie 2_unde.ym b/sounds/ays/Batman - The Movie 2_unde.ym new file mode 100644 index 0000000..3abe420 Binary files /dev/null and b/sounds/ays/Batman - The Movie 2_unde.ym differ diff --git a/sounds/ays/Batman - The Movie 3_unde.ym b/sounds/ays/Batman - The Movie 3_unde.ym new file mode 100644 index 0000000..c992aab Binary files /dev/null and b/sounds/ays/Batman - The Movie 3_unde.ym differ diff --git a/sounds/ays/BeBop_unde.ym b/sounds/ays/BeBop_unde.ym new file mode 100644 index 0000000..b2ba14f Binary files /dev/null and b/sounds/ays/BeBop_unde.ym differ diff --git a/sounds/ays/Beachtro_unde.ym b/sounds/ays/Beachtro_unde.ym new file mode 100644 index 0000000..0112d6a Binary files /dev/null and b/sounds/ays/Beachtro_unde.ym differ diff --git a/sounds/ays/Bionic Commando 1_unde.ym b/sounds/ays/Bionic Commando 1_unde.ym new file mode 100644 index 0000000..a566f5b Binary files /dev/null and b/sounds/ays/Bionic Commando 1_unde.ym differ diff --git a/sounds/ays/Bjerregard Conv_unde.ym b/sounds/ays/Bjerregard Conv_unde.ym new file mode 100644 index 0000000..4b966a0 Binary files /dev/null and b/sounds/ays/Bjerregard Conv_unde.ym differ diff --git a/sounds/ays/Bubble Bobble 1_unde.ym b/sounds/ays/Bubble Bobble 1_unde.ym new file mode 100644 index 0000000..c10df4e Binary files /dev/null and b/sounds/ays/Bubble Bobble 1_unde.ym differ diff --git a/sounds/ays/Colorz Trackmo_unde.ym b/sounds/ays/Colorz Trackmo_unde.ym new file mode 100644 index 0000000..1fb3a80 Binary files /dev/null and b/sounds/ays/Colorz Trackmo_unde.ym differ diff --git a/sounds/ays/Commando highscore_unde.ym b/sounds/ays/Commando highscore_unde.ym new file mode 100644 index 0000000..c49f44a Binary files /dev/null and b/sounds/ays/Commando highscore_unde.ym differ diff --git a/sounds/ays/Commando_unde.ym b/sounds/ays/Commando_unde.ym new file mode 100644 index 0000000..712c18a Binary files /dev/null and b/sounds/ays/Commando_unde.ym differ diff --git a/sounds/ays/Dark Fuzion_unde.ym b/sounds/ays/Dark Fuzion_unde.ym new file mode 100644 index 0000000..8c14530 Binary files /dev/null and b/sounds/ays/Dark Fuzion_unde.ym differ diff --git a/sounds/ays/Decade Gigadist_unde.ym b/sounds/ays/Decade Gigadist_unde.ym new file mode 100644 index 0000000..8d53865 Binary files /dev/null and b/sounds/ays/Decade Gigadist_unde.ym differ diff --git a/sounds/ays/Decade Intro_unde.ym b/sounds/ays/Decade Intro_unde.ym new file mode 100644 index 0000000..861da5d Binary files /dev/null and b/sounds/ays/Decade Intro_unde.ym differ diff --git a/sounds/ays/Deflektor 1_unde.ym b/sounds/ays/Deflektor 1_unde.ym new file mode 100644 index 0000000..592c697 Binary files /dev/null and b/sounds/ays/Deflektor 1_unde.ym differ diff --git a/sounds/ays/Gauntlet 3_unde.ym b/sounds/ays/Gauntlet 3_unde.ym new file mode 100644 index 0000000..8427336 Binary files /dev/null and b/sounds/ays/Gauntlet 3_unde.ym differ diff --git a/sounds/ays/Ghouls 3_unde.ym b/sounds/ays/Ghouls 3_unde.ym new file mode 100644 index 0000000..1bffde7 Binary files /dev/null and b/sounds/ays/Ghouls 3_unde.ym differ diff --git a/sounds/ays/Gritty_unde.ym b/sounds/ays/Gritty_unde.ym new file mode 100644 index 0000000..e683337 Binary files /dev/null and b/sounds/ays/Gritty_unde.ym differ diff --git a/sounds/ays/Hit me!_unde.ym b/sounds/ays/Hit me!_unde.ym new file mode 100644 index 0000000..693d9e7 Binary files /dev/null and b/sounds/ays/Hit me!_unde.ym differ diff --git a/sounds/ays/Hybris_unde.ym b/sounds/ays/Hybris_unde.ym new file mode 100644 index 0000000..ce99d2f Binary files /dev/null and b/sounds/ays/Hybris_unde.ym differ diff --git a/sounds/ays/I wonder_unde.ym b/sounds/ays/I wonder_unde.ym new file mode 100644 index 0000000..610050f Binary files /dev/null and b/sounds/ays/I wonder_unde.ym differ diff --git a/sounds/ays/JMJDMO01.ym b/sounds/ays/JMJDMO01.ym new file mode 100644 index 0000000..639cd53 Binary files /dev/null and b/sounds/ays/JMJDMO01.ym differ diff --git a/sounds/ays/JMJDMO02.ym b/sounds/ays/JMJDMO02.ym new file mode 100644 index 0000000..0f18186 Binary files /dev/null and b/sounds/ays/JMJDMO02.ym differ diff --git a/sounds/ays/JMJDMO03.ym b/sounds/ays/JMJDMO03.ym new file mode 100644 index 0000000..7ab27e3 Binary files /dev/null and b/sounds/ays/JMJDMO03.ym differ diff --git a/sounds/ays/JMJDMO04.ym b/sounds/ays/JMJDMO04.ym new file mode 100644 index 0000000..a152823 Binary files /dev/null and b/sounds/ays/JMJDMO04.ym differ diff --git a/sounds/ays/JMJDMO05.ym b/sounds/ays/JMJDMO05.ym new file mode 100644 index 0000000..cffffcb Binary files /dev/null and b/sounds/ays/JMJDMO05.ym differ diff --git a/sounds/ays/JMJDMO06.ym b/sounds/ays/JMJDMO06.ym new file mode 100644 index 0000000..c5d34ff Binary files /dev/null and b/sounds/ays/JMJDMO06.ym differ diff --git a/sounds/ays/JMJDMO07.ym b/sounds/ays/JMJDMO07.ym new file mode 100644 index 0000000..3134158 Binary files /dev/null and b/sounds/ays/JMJDMO07.ym differ diff --git a/sounds/ays/JMJDMO08.ym b/sounds/ays/JMJDMO08.ym new file mode 100644 index 0000000..0b3cbc5 Binary files /dev/null and b/sounds/ays/JMJDMO08.ym differ diff --git a/sounds/ays/JMJDMO09.ym b/sounds/ays/JMJDMO09.ym new file mode 100644 index 0000000..c4a2b34 Binary files /dev/null and b/sounds/ays/JMJDMO09.ym differ diff --git a/sounds/ays/JMJDMO11.ym b/sounds/ays/JMJDMO11.ym new file mode 100644 index 0000000..afa057f Binary files /dev/null and b/sounds/ays/JMJDMO11.ym differ diff --git a/sounds/ays/Jim Power 1_unde.ym b/sounds/ays/Jim Power 1_unde.ym new file mode 100644 index 0000000..d2e7f85 Binary files /dev/null and b/sounds/ays/Jim Power 1_unde.ym differ diff --git a/sounds/ays/Jim Power 2_unde.ym b/sounds/ays/Jim Power 2_unde.ym new file mode 100644 index 0000000..5fba85d Binary files /dev/null and b/sounds/ays/Jim Power 2_unde.ym differ diff --git a/sounds/ays/Jim Power 3_unde.ym b/sounds/ays/Jim Power 3_unde.ym new file mode 100644 index 0000000..64bd656 Binary files /dev/null and b/sounds/ays/Jim Power 3_unde.ym differ diff --git a/sounds/ays/Jim Power 4_unde.ym b/sounds/ays/Jim Power 4_unde.ym new file mode 100644 index 0000000..77bd11d Binary files /dev/null and b/sounds/ays/Jim Power 4_unde.ym differ diff --git a/sounds/ays/Jim Power 5_unde.ym b/sounds/ays/Jim Power 5_unde.ym new file mode 100644 index 0000000..6c3b5b3 Binary files /dev/null and b/sounds/ays/Jim Power 5_unde.ym differ diff --git a/sounds/ays/Jim Power 6_unde.ym b/sounds/ays/Jim Power 6_unde.ym new file mode 100644 index 0000000..42ea730 Binary files /dev/null and b/sounds/ays/Jim Power 6_unde.ym differ diff --git a/sounds/ays/Jim Power 9_unde.ym b/sounds/ays/Jim Power 9_unde.ym new file mode 100644 index 0000000..326f7cf Binary files /dev/null and b/sounds/ays/Jim Power 9_unde.ym differ diff --git a/sounds/ays/Kidney Bean 18_unde.ym b/sounds/ays/Kidney Bean 18_unde.ym new file mode 100644 index 0000000..b274a96 Binary files /dev/null and b/sounds/ays/Kidney Bean 18_unde.ym differ diff --git a/sounds/ays/Last Ninja_unde.ym b/sounds/ays/Last Ninja_unde.ym new file mode 100644 index 0000000..9dc4d16 Binary files /dev/null and b/sounds/ays/Last Ninja_unde.ym differ diff --git a/sounds/ays/Leaving Teramis_unde.ym b/sounds/ays/Leaving Teramis_unde.ym new file mode 100644 index 0000000..c697cd2 Binary files /dev/null and b/sounds/ays/Leaving Teramis_unde.ym differ diff --git a/sounds/ays/Liberator 1_unde.ym b/sounds/ays/Liberator 1_unde.ym new file mode 100644 index 0000000..50b1785 Binary files /dev/null and b/sounds/ays/Liberator 1_unde.ym differ diff --git a/sounds/ays/Megatwins 1_unde.ym b/sounds/ays/Megatwins 1_unde.ym new file mode 100644 index 0000000..b5b0099 Binary files /dev/null and b/sounds/ays/Megatwins 1_unde.ym differ diff --git a/sounds/ays/Misfits 19_unde.ym b/sounds/ays/Misfits 19_unde.ym new file mode 100644 index 0000000..7d3f2b8 Binary files /dev/null and b/sounds/ays/Misfits 19_unde.ym differ diff --git a/sounds/ays/Misfits 20_unde.ym b/sounds/ays/Misfits 20_unde.ym new file mode 100644 index 0000000..d968f8c Binary files /dev/null and b/sounds/ays/Misfits 20_unde.ym differ diff --git a/sounds/ays/Misfits 25_unde.ym b/sounds/ays/Misfits 25_unde.ym new file mode 100644 index 0000000..019ec9d Binary files /dev/null and b/sounds/ays/Misfits 25_unde.ym differ diff --git a/sounds/ays/Misfits 26_unde.ym b/sounds/ays/Misfits 26_unde.ym new file mode 100644 index 0000000..dd90dc6 Binary files /dev/null and b/sounds/ays/Misfits 26_unde.ym differ diff --git a/sounds/ays/Misfits 27_unde.ym b/sounds/ays/Misfits 27_unde.ym new file mode 100644 index 0000000..2ba3487 Binary files /dev/null and b/sounds/ays/Misfits 27_unde.ym differ diff --git a/sounds/ays/Mr Boomer 1_unde.ym b/sounds/ays/Mr Boomer 1_unde.ym new file mode 100644 index 0000000..bb97f0a Binary files /dev/null and b/sounds/ays/Mr Boomer 1_unde.ym differ diff --git a/sounds/ays/New_unde.ym b/sounds/ays/New_unde.ym new file mode 100644 index 0000000..09b035f Binary files /dev/null and b/sounds/ays/New_unde.ym differ diff --git a/sounds/ays/Noisy Pillars_unde.ym b/sounds/ays/Noisy Pillars_unde.ym new file mode 100644 index 0000000..6bae4ae Binary files /dev/null and b/sounds/ays/Noisy Pillars_unde.ym differ diff --git a/sounds/ays/Offbeat_unde.ym b/sounds/ays/Offbeat_unde.ym new file mode 100644 index 0000000..ff32fc4 Binary files /dev/null and b/sounds/ays/Offbeat_unde.ym differ diff --git a/sounds/ays/Outrun 1_unde.ym b/sounds/ays/Outrun 1_unde.ym new file mode 100644 index 0000000..6176de4 Binary files /dev/null and b/sounds/ays/Outrun 1_unde.ym differ diff --git a/sounds/ays/Outrun 2_unde.ym b/sounds/ays/Outrun 2_unde.ym new file mode 100644 index 0000000..4ae45e7 Binary files /dev/null and b/sounds/ays/Outrun 2_unde.ym differ diff --git a/sounds/ays/Pacmania 1_unde.ym b/sounds/ays/Pacmania 1_unde.ym new file mode 100644 index 0000000..9987d65 Binary files /dev/null and b/sounds/ays/Pacmania 1_unde.ym differ diff --git a/sounds/ays/Pacmania 2_unde.ym b/sounds/ays/Pacmania 2_unde.ym new file mode 100644 index 0000000..5549dd2 Binary files /dev/null and b/sounds/ays/Pacmania 2_unde.ym differ diff --git a/sounds/ays/Parasol Stars 1_unde.ym b/sounds/ays/Parasol Stars 1_unde.ym new file mode 100644 index 0000000..34f1d4c Binary files /dev/null and b/sounds/ays/Parasol Stars 1_unde.ym differ diff --git a/sounds/ays/Parasol Stars 5_unde.ym b/sounds/ays/Parasol Stars 5_unde.ym new file mode 100644 index 0000000..e81d286 Binary files /dev/null and b/sounds/ays/Parasol Stars 5_unde.ym differ diff --git a/sounds/ays/Phaleon Shadow of The Beast 2_unde.ym b/sounds/ays/Phaleon Shadow of The Beast 2_unde.ym new file mode 100644 index 0000000..0018089 Binary files /dev/null and b/sounds/ays/Phaleon Shadow of The Beast 2_unde.ym differ diff --git a/sounds/ays/Quick & Silva 3_unde.ym b/sounds/ays/Quick & Silva 3_unde.ym new file mode 100644 index 0000000..8505528 Binary files /dev/null and b/sounds/ays/Quick & Silva 3_unde.ym differ diff --git a/sounds/ays/R-Type 1 - intro_unde.ym b/sounds/ays/R-Type 1 - intro_unde.ym new file mode 100644 index 0000000..638fa00 Binary files /dev/null and b/sounds/ays/R-Type 1 - intro_unde.ym differ diff --git a/sounds/ays/R-Type 2 - level 1_unde.ym b/sounds/ays/R-Type 2 - level 1_unde.ym new file mode 100644 index 0000000..8e97bf1 Binary files /dev/null and b/sounds/ays/R-Type 2 - level 1_unde.ym differ diff --git a/sounds/ays/R-Type 3 - boss_unde.ym b/sounds/ays/R-Type 3 - boss_unde.ym new file mode 100644 index 0000000..0bbc076 Binary files /dev/null and b/sounds/ays/R-Type 3 - boss_unde.ym differ diff --git a/sounds/ays/Rick Dangerous 1_unde.ym b/sounds/ays/Rick Dangerous 1_unde.ym new file mode 100644 index 0000000..30737bb Binary files /dev/null and b/sounds/ays/Rick Dangerous 1_unde.ym differ diff --git a/sounds/ays/Rick Dangerous II 1_unde.ym b/sounds/ays/Rick Dangerous II 1_unde.ym new file mode 100644 index 0000000..7f05033 Binary files /dev/null and b/sounds/ays/Rick Dangerous II 1_unde.ym differ diff --git a/sounds/ays/Spunge_unde.ym b/sounds/ays/Spunge_unde.ym new file mode 100644 index 0000000..8faf73d Binary files /dev/null and b/sounds/ays/Spunge_unde.ym differ diff --git a/sounds/ays/Stolen_unde.ym b/sounds/ays/Stolen_unde.ym new file mode 100644 index 0000000..f25d2fb Binary files /dev/null and b/sounds/ays/Stolen_unde.ym differ diff --git a/sounds/ays/Summer_unde.ym b/sounds/ays/Summer_unde.ym new file mode 100644 index 0000000..2818ff8 Binary files /dev/null and b/sounds/ays/Summer_unde.ym differ diff --git a/sounds/ays/Swiv_unde.ym b/sounds/ays/Swiv_unde.ym new file mode 100644 index 0000000..6d6ec9f Binary files /dev/null and b/sounds/ays/Swiv_unde.ym differ diff --git a/sounds/ays/Thomas Danko_unde.ym b/sounds/ays/Thomas Danko_unde.ym new file mode 100644 index 0000000..ae4ced2 Binary files /dev/null and b/sounds/ays/Thomas Danko_unde.ym differ diff --git a/sounds/ays/Vixen 1_unde.ym b/sounds/ays/Vixen 1_unde.ym new file mode 100644 index 0000000..2def8fc Binary files /dev/null and b/sounds/ays/Vixen 1_unde.ym differ diff --git a/sounds/ays/Vixen 2_unde.ym b/sounds/ays/Vixen 2_unde.ym new file mode 100644 index 0000000..7cfd3d9 Binary files /dev/null and b/sounds/ays/Vixen 2_unde.ym differ diff --git a/sounds/ays/Xbios Ala Turka_unde.ym b/sounds/ays/Xbios Ala Turka_unde.ym new file mode 100644 index 0000000..8701323 Binary files /dev/null and b/sounds/ays/Xbios Ala Turka_unde.ym differ diff --git a/sounds/ays/alemix/AfterBurner.ym b/sounds/ays/alemix/AfterBurner.ym new file mode 100644 index 0000000..2a5a48d Binary files /dev/null and b/sounds/ays/alemix/AfterBurner.ym differ diff --git a/sounds/ays/alemix/Chicago.ym b/sounds/ays/alemix/Chicago.ym new file mode 100644 index 0000000..af97170 Binary files /dev/null and b/sounds/ays/alemix/Chicago.ym differ diff --git a/sounds/ays/alemix/DogsOfWar.ym b/sounds/ays/alemix/DogsOfWar.ym new file mode 100644 index 0000000..0437c1d Binary files /dev/null and b/sounds/ays/alemix/DogsOfWar.ym differ diff --git a/sounds/ays/alemix/GoldenAxe.ym b/sounds/ays/alemix/GoldenAxe.ym new file mode 100644 index 0000000..e1909cc Binary files /dev/null and b/sounds/ays/alemix/GoldenAxe.ym differ diff --git a/sounds/ays/alemix/LotusIII.ym b/sounds/ays/alemix/LotusIII.ym new file mode 100644 index 0000000..3d0a0db Binary files /dev/null and b/sounds/ays/alemix/LotusIII.ym differ diff --git a/sounds/ays/alemix/MusicDiskSong6.ym b/sounds/ays/alemix/MusicDiskSong6.ym new file mode 100644 index 0000000..6b591d7 Binary files /dev/null and b/sounds/ays/alemix/MusicDiskSong6.ym differ diff --git a/sounds/ays/alemix/RickDangerous.ym b/sounds/ays/alemix/RickDangerous.ym new file mode 100644 index 0000000..56ae5d0 Binary files /dev/null and b/sounds/ays/alemix/RickDangerous.ym differ diff --git a/sounds/ays/alemix/Rodland.ym b/sounds/ays/alemix/Rodland.ym new file mode 100644 index 0000000..f7d0466 Binary files /dev/null and b/sounds/ays/alemix/Rodland.ym differ diff --git a/sounds/ays/alemix/WickedPolygonsPart2.ym b/sounds/ays/alemix/WickedPolygonsPart2.ym new file mode 100644 index 0000000..9addbd5 Binary files /dev/null and b/sounds/ays/alemix/WickedPolygonsPart2.ym differ diff --git a/sounds/ays/comp1/.svn/all-wcprops b/sounds/ays/comp1/.svn/all-wcprops new file mode 100644 index 0000000..03ea7e9 --- /dev/null +++ b/sounds/ays/comp1/.svn/all-wcprops @@ -0,0 +1,59 @@ +K 25 +svn:wc:ra_dav:version-url +V 50 +/svn/!svn/ver/16/trunk/bin/sd-card-basic/YM6/comp1 +END +Mr Boomer 1_unde.ym +K 25 +svn:wc:ra_dav:version-url +V 74 +/svn/!svn/ver/16/trunk/bin/sd-card-basic/YM6/comp1/Mr%20Boomer%201_unde.ym +END +Axel Folley_unde.ym +K 25 +svn:wc:ra_dav:version-url +V 72 +/svn/!svn/ver/16/trunk/bin/sd-card-basic/YM6/comp1/Axel%20Folley_unde.ym +END +Misfits 25_unde.ym +K 25 +svn:wc:ra_dav:version-url +V 71 +/svn/!svn/ver/16/trunk/bin/sd-card-basic/YM6/comp1/Misfits%2025_unde.ym +END +alphaville.ym +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/!svn/ver/16/trunk/bin/sd-card-basic/YM6/comp1/alphaville.ym +END +BeBop_unde.ym +K 25 +svn:wc:ra_dav:version-url +V 64 +/svn/!svn/ver/16/trunk/bin/sd-card-basic/YM6/comp1/BeBop_unde.ym +END +Thomas Danko_unde.ym +K 25 +svn:wc:ra_dav:version-url +V 73 +/svn/!svn/ver/16/trunk/bin/sd-card-basic/YM6/comp1/Thomas%20Danko_unde.ym +END +Xbios Ala Turka_unde.ym +K 25 +svn:wc:ra_dav:version-url +V 78 +/svn/!svn/ver/16/trunk/bin/sd-card-basic/YM6/comp1/Xbios%20Ala%20Turka_unde.ym +END +cybernet_unde.ym +K 25 +svn:wc:ra_dav:version-url +V 67 +/svn/!svn/ver/16/trunk/bin/sd-card-basic/YM6/comp1/cybernet_unde.ym +END +Jim Power 2_unde.ym +K 25 +svn:wc:ra_dav:version-url +V 77 +/svn/!svn/ver/16/trunk/bin/sd-card-basic/YM6/comp1/Jim%20Power%20%202_unde.ym +END diff --git a/sounds/ays/comp1/.svn/entries b/sounds/ays/comp1/.svn/entries new file mode 100644 index 0000000..c53cbec --- /dev/null +++ b/sounds/ays/comp1/.svn/entries @@ -0,0 +1,334 @@ +10 + +dir +16 +https://hive-trios.googlecode.com/svn/trunk/bin/sd-card-basic/YM6/comp1 +https://hive-trios.googlecode.com/svn + + + +2010-11-26T22:50:49.059382Z +16 +drohne235@googlemail.com + + + + + + + + + + + + + + +7db10379-1cae-3978-5756-083c5ee721e3 + +Mr Boomer 1_unde.ym +file + + + + +2010-05-23T20:57:14.000000Z +486b79042be35cf9c98716a91d8ca173 +2010-11-26T22:50:49.059382Z +16 +drohne235@googlemail.com +has-props + + + + + + + + + + + + + + + + + + + + +110817 + +Axel Folley_unde.ym +file + + + + +2010-05-23T20:49:38.000000Z +bb6afdc83c0ea6d28c7891be49f0b98f +2010-11-26T22:50:49.059382Z +16 +drohne235@googlemail.com +has-props + + + + + + + + + + + + + + + + + + + + +61525 + +Misfits 25_unde.ym +file + + + + +2010-05-23T20:56:50.000000Z +384523f64042577ee09504d867f8c382 +2010-11-26T22:50:49.059382Z +16 +drohne235@googlemail.com +has-props + + + + + + + + + + + + + + + + + + + + +196700 + +alphaville.ym +file + + + + +2010-07-18T21:25:24.000000Z +1ca8772d8908d2867e9d3bc2b1265873 +2010-11-26T22:50:49.059382Z +16 +drohne235@googlemail.com +has-props + + + + + + + + + + + + + + + + + + + + +184403 + +BeBop_unde.ym +file + + + + +2010-05-23T20:50:50.000000Z +927eea9818d740cf7aee04fece9fb9c9 +2010-11-26T22:50:49.059382Z +16 +drohne235@googlemail.com +has-props + + + + + + + + + + + + + + + + + + + + +55123 + +Thomas Danko_unde.ym +file + + + + +2010-05-23T21:02:06.000000Z +ba652dab48a93dc10324eb90eebe6642 +2010-11-26T22:50:49.059382Z +16 +drohne235@googlemail.com +has-props + + + + + + + + + + + + + + + + + + + + +104558 + +Xbios Ala Turka_unde.ym +file + + + + +2010-05-23T21:02:36.000000Z +015e5a3fde7256d2cd81803fd6ab03b2 +2010-11-26T22:50:49.059382Z +16 +drohne235@googlemail.com +has-props + + + + + + + + + + + + + + + + + + + + +141975 + +cybernet_unde.ym +file + + + + +2010-05-20T21:47:48.000000Z +79ec2700aa181fbf3b58e462ed04f560 +2010-11-26T22:50:49.059382Z +16 +drohne235@googlemail.com +has-props + + + + + + + + + + + + + + + + + + + + +160450 + +Jim Power 2_unde.ym +file + + + + +2010-05-23T20:54:42.000000Z +6641f87a929115543c90165d02b0eb22 +2010-11-26T22:50:49.059382Z +16 +drohne235@googlemail.com +has-props + + + + + + + + + + + + + + + + + + + + +118448 + diff --git a/sounds/ays/comp1/.svn/prop-base/Axel Folley_unde.ym.svn-base b/sounds/ays/comp1/.svn/prop-base/Axel Folley_unde.ym.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/sounds/ays/comp1/.svn/prop-base/Axel Folley_unde.ym.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/sounds/ays/comp1/.svn/prop-base/BeBop_unde.ym.svn-base b/sounds/ays/comp1/.svn/prop-base/BeBop_unde.ym.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/sounds/ays/comp1/.svn/prop-base/BeBop_unde.ym.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/sounds/ays/comp1/.svn/prop-base/Jim Power 2_unde.ym.svn-base b/sounds/ays/comp1/.svn/prop-base/Jim Power 2_unde.ym.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/sounds/ays/comp1/.svn/prop-base/Jim Power 2_unde.ym.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/sounds/ays/comp1/.svn/prop-base/Misfits 25_unde.ym.svn-base b/sounds/ays/comp1/.svn/prop-base/Misfits 25_unde.ym.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/sounds/ays/comp1/.svn/prop-base/Misfits 25_unde.ym.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/sounds/ays/comp1/.svn/prop-base/Mr Boomer 1_unde.ym.svn-base b/sounds/ays/comp1/.svn/prop-base/Mr Boomer 1_unde.ym.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/sounds/ays/comp1/.svn/prop-base/Mr Boomer 1_unde.ym.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/sounds/ays/comp1/.svn/prop-base/Thomas Danko_unde.ym.svn-base b/sounds/ays/comp1/.svn/prop-base/Thomas Danko_unde.ym.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/sounds/ays/comp1/.svn/prop-base/Thomas Danko_unde.ym.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/sounds/ays/comp1/.svn/prop-base/Xbios Ala Turka_unde.ym.svn-base b/sounds/ays/comp1/.svn/prop-base/Xbios Ala Turka_unde.ym.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/sounds/ays/comp1/.svn/prop-base/Xbios Ala Turka_unde.ym.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/sounds/ays/comp1/.svn/prop-base/alphaville.ym.svn-base b/sounds/ays/comp1/.svn/prop-base/alphaville.ym.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/sounds/ays/comp1/.svn/prop-base/alphaville.ym.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/sounds/ays/comp1/.svn/prop-base/cybernet_unde.ym.svn-base b/sounds/ays/comp1/.svn/prop-base/cybernet_unde.ym.svn-base new file mode 100644 index 0000000..5e9587e --- /dev/null +++ b/sounds/ays/comp1/.svn/prop-base/cybernet_unde.ym.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mime-type +V 24 +application/octet-stream +END diff --git a/sounds/ays/comp1/.svn/text-base/Axel Folley_unde.ym.svn-base b/sounds/ays/comp1/.svn/text-base/Axel Folley_unde.ym.svn-base new file mode 100644 index 0000000..23729bd Binary files /dev/null and b/sounds/ays/comp1/.svn/text-base/Axel Folley_unde.ym.svn-base differ diff --git a/sounds/ays/comp1/.svn/text-base/BeBop_unde.ym.svn-base b/sounds/ays/comp1/.svn/text-base/BeBop_unde.ym.svn-base new file mode 100644 index 0000000..b2ba14f Binary files /dev/null and b/sounds/ays/comp1/.svn/text-base/BeBop_unde.ym.svn-base differ diff --git a/sounds/ays/comp1/.svn/text-base/Jim Power 2_unde.ym.svn-base b/sounds/ays/comp1/.svn/text-base/Jim Power 2_unde.ym.svn-base new file mode 100644 index 0000000..5fba85d Binary files /dev/null and b/sounds/ays/comp1/.svn/text-base/Jim Power 2_unde.ym.svn-base differ diff --git a/sounds/ays/comp1/.svn/text-base/Misfits 25_unde.ym.svn-base b/sounds/ays/comp1/.svn/text-base/Misfits 25_unde.ym.svn-base new file mode 100644 index 0000000..019ec9d Binary files /dev/null and b/sounds/ays/comp1/.svn/text-base/Misfits 25_unde.ym.svn-base differ diff --git a/sounds/ays/comp1/.svn/text-base/Mr Boomer 1_unde.ym.svn-base b/sounds/ays/comp1/.svn/text-base/Mr Boomer 1_unde.ym.svn-base new file mode 100644 index 0000000..bb97f0a Binary files /dev/null and b/sounds/ays/comp1/.svn/text-base/Mr Boomer 1_unde.ym.svn-base differ diff --git a/sounds/ays/comp1/.svn/text-base/Thomas Danko_unde.ym.svn-base b/sounds/ays/comp1/.svn/text-base/Thomas Danko_unde.ym.svn-base new file mode 100644 index 0000000..ae4ced2 Binary files /dev/null and b/sounds/ays/comp1/.svn/text-base/Thomas Danko_unde.ym.svn-base differ diff --git a/sounds/ays/comp1/.svn/text-base/Xbios Ala Turka_unde.ym.svn-base b/sounds/ays/comp1/.svn/text-base/Xbios Ala Turka_unde.ym.svn-base new file mode 100644 index 0000000..8701323 Binary files /dev/null and b/sounds/ays/comp1/.svn/text-base/Xbios Ala Turka_unde.ym.svn-base differ diff --git a/sounds/ays/comp1/.svn/text-base/alphaville.ym.svn-base b/sounds/ays/comp1/.svn/text-base/alphaville.ym.svn-base new file mode 100644 index 0000000..be668ac Binary files /dev/null and b/sounds/ays/comp1/.svn/text-base/alphaville.ym.svn-base differ diff --git a/sounds/ays/comp1/.svn/text-base/cybernet_unde.ym.svn-base b/sounds/ays/comp1/.svn/text-base/cybernet_unde.ym.svn-base new file mode 100644 index 0000000..68a45b3 Binary files /dev/null and b/sounds/ays/comp1/.svn/text-base/cybernet_unde.ym.svn-base differ diff --git a/sounds/ays/comp1/Axel Folley_unde.ym b/sounds/ays/comp1/Axel Folley_unde.ym new file mode 100644 index 0000000..23729bd Binary files /dev/null and b/sounds/ays/comp1/Axel Folley_unde.ym differ diff --git a/sounds/ays/comp1/BeBop_unde.ym b/sounds/ays/comp1/BeBop_unde.ym new file mode 100644 index 0000000..b2ba14f Binary files /dev/null and b/sounds/ays/comp1/BeBop_unde.ym differ diff --git a/sounds/ays/comp1/Jim Power 2_unde.ym b/sounds/ays/comp1/Jim Power 2_unde.ym new file mode 100644 index 0000000..5fba85d Binary files /dev/null and b/sounds/ays/comp1/Jim Power 2_unde.ym differ diff --git a/sounds/ays/comp1/Misfits 25_unde.ym b/sounds/ays/comp1/Misfits 25_unde.ym new file mode 100644 index 0000000..019ec9d Binary files /dev/null and b/sounds/ays/comp1/Misfits 25_unde.ym differ diff --git a/sounds/ays/comp1/Mr Boomer 1_unde.ym b/sounds/ays/comp1/Mr Boomer 1_unde.ym new file mode 100644 index 0000000..bb97f0a Binary files /dev/null and b/sounds/ays/comp1/Mr Boomer 1_unde.ym differ diff --git a/sounds/ays/comp1/Thomas Danko_unde.ym b/sounds/ays/comp1/Thomas Danko_unde.ym new file mode 100644 index 0000000..ae4ced2 Binary files /dev/null and b/sounds/ays/comp1/Thomas Danko_unde.ym differ diff --git a/sounds/ays/comp1/Xbios Ala Turka_unde.ym b/sounds/ays/comp1/Xbios Ala Turka_unde.ym new file mode 100644 index 0000000..8701323 Binary files /dev/null and b/sounds/ays/comp1/Xbios Ala Turka_unde.ym differ diff --git a/sounds/ays/comp1/alphaville.ym b/sounds/ays/comp1/alphaville.ym new file mode 100644 index 0000000..be668ac Binary files /dev/null and b/sounds/ays/comp1/alphaville.ym differ diff --git a/sounds/ays/comp1/cybernet_unde.ym b/sounds/ays/comp1/cybernet_unde.ym new file mode 100644 index 0000000..68a45b3 Binary files /dev/null and b/sounds/ays/comp1/cybernet_unde.ym differ diff --git a/sounds/ays/cybernet_unde.ym b/sounds/ays/cybernet_unde.ym new file mode 100644 index 0000000..68a45b3 Binary files /dev/null and b/sounds/ays/cybernet_unde.ym differ diff --git a/sounds/ays/db96invi_unde.ym b/sounds/ays/db96invi_unde.ym new file mode 100644 index 0000000..e00f8ac Binary files /dev/null and b/sounds/ays/db96invi_unde.ym differ diff --git a/sounds/ays/echo2_unde.ym b/sounds/ays/echo2_unde.ym new file mode 100644 index 0000000..c5f6963 Binary files /dev/null and b/sounds/ays/echo2_unde.ym differ diff --git a/sounds/ays/harmony_unde.ym b/sounds/ays/harmony_unde.ym new file mode 100644 index 0000000..9988349 Binary files /dev/null and b/sounds/ays/harmony_unde.ym differ diff --git a/sounds/ays/jingle_unde.ym b/sounds/ays/jingle_unde.ym new file mode 100644 index 0000000..f8d02cd Binary files /dev/null and b/sounds/ays/jingle_unde.ym differ diff --git a/sounds/ays/kurztech_unde.ym b/sounds/ays/kurztech_unde.ym new file mode 100644 index 0000000..2f0f00b Binary files /dev/null and b/sounds/ays/kurztech_unde.ym differ diff --git a/sounds/ays/noro_unde.ym b/sounds/ays/noro_unde.ym new file mode 100644 index 0000000..91df370 Binary files /dev/null and b/sounds/ays/noro_unde.ym differ diff --git a/sounds/ays/perinded_unde.ym b/sounds/ays/perinded_unde.ym new file mode 100644 index 0000000..5954533 Binary files /dev/null and b/sounds/ays/perinded_unde.ym differ diff --git a/sounds/ays/q_psb_unde.ym b/sounds/ays/q_psb_unde.ym new file mode 100644 index 0000000..a3ef883 Binary files /dev/null and b/sounds/ays/q_psb_unde.ym differ diff --git a/sounds/ays/swtchldo_unde.ym b/sounds/ays/swtchldo_unde.ym new file mode 100644 index 0000000..c3ff9c2 Binary files /dev/null and b/sounds/ays/swtchldo_unde.ym differ diff --git a/sounds/ays/trashe_unde.ym b/sounds/ays/trashe_unde.ym new file mode 100644 index 0000000..4284489 Binary files /dev/null and b/sounds/ays/trashe_unde.ym differ diff --git a/sounds/hss/genes.hss b/sounds/hss/genes.hss new file mode 100644 index 0000000..414d066 Binary files /dev/null and b/sounds/hss/genes.hss differ diff --git a/sounds/hss/greenpuz.hss b/sounds/hss/greenpuz.hss new file mode 100644 index 0000000..475021c Binary files /dev/null and b/sounds/hss/greenpuz.hss differ diff --git a/sounds/hss/hssintro.hss b/sounds/hss/hssintro.hss new file mode 100644 index 0000000..7698612 Binary files /dev/null and b/sounds/hss/hssintro.hss differ diff --git a/sounds/hss/kali766.hss b/sounds/hss/kali766.hss new file mode 100644 index 0000000..d7d7d41 Binary files /dev/null and b/sounds/hss/kali766.hss differ diff --git a/sounds/hss/kw.hss b/sounds/hss/kw.hss new file mode 100644 index 0000000..96fd04f Binary files /dev/null and b/sounds/hss/kw.hss differ diff --git a/sounds/hss/machine.hss b/sounds/hss/machine.hss new file mode 100644 index 0000000..4c8d9d5 Binary files /dev/null and b/sounds/hss/machine.hss differ diff --git a/sounds/hss/metroid.hss b/sounds/hss/metroid.hss new file mode 100644 index 0000000..6568848 Binary files /dev/null and b/sounds/hss/metroid.hss differ diff --git a/sounds/hss/mrboss.hss b/sounds/hss/mrboss.hss new file mode 100644 index 0000000..6f56d22 Binary files /dev/null and b/sounds/hss/mrboss.hss differ diff --git a/sounds/hss/mrevil.hss b/sounds/hss/mrevil.hss new file mode 100644 index 0000000..95b86e5 Binary files /dev/null and b/sounds/hss/mrevil.hss differ diff --git a/sounds/hss/raind.hss b/sounds/hss/raind.hss new file mode 100644 index 0000000..a24b2b9 Binary files /dev/null and b/sounds/hss/raind.hss differ diff --git a/sounds/hss/sytrus.hss b/sounds/hss/sytrus.hss new file mode 100644 index 0000000..3f6dc92 Binary files /dev/null and b/sounds/hss/sytrus.hss differ diff --git a/sounds/hss/tbellsp1.hss b/sounds/hss/tbellsp1.hss new file mode 100644 index 0000000..17aff53 Binary files /dev/null and b/sounds/hss/tbellsp1.hss differ diff --git a/sounds/hss/tbellsp2.hss b/sounds/hss/tbellsp2.hss new file mode 100644 index 0000000..4007234 Binary files /dev/null and b/sounds/hss/tbellsp2.hss differ diff --git a/sounds/sfx/BONUS.SFX b/sounds/sfx/BONUS.SFX new file mode 100644 index 0000000..97f538e Binary files /dev/null and b/sounds/sfx/BONUS.SFX differ diff --git a/sounds/sfx/BONUS.SPN b/sounds/sfx/BONUS.SPN new file mode 100644 index 0000000..ada8775 --- /dev/null +++ b/sounds/sfx/BONUS.SPN @@ -0,0 +1 @@ +bonus ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $03,$03,$FF,$0F,$02,$00,$05,$00,$FF,$01,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sfx/COL1.SFX b/sounds/sfx/COL1.SFX new file mode 100644 index 0000000..44be65c Binary files /dev/null and b/sounds/sfx/COL1.SFX differ diff --git a/sounds/sfx/COL1.SPN b/sounds/sfx/COL1.SPN new file mode 100644 index 0000000..6cf386b --- /dev/null +++ b/sounds/sfx/COL1.SPN @@ -0,0 +1 @@ +col1 ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $01,$04,$10,$0F,$88,$03,$01,$00,$FF,$01,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sfx/COL2.SFX b/sounds/sfx/COL2.SFX new file mode 100644 index 0000000..e9477b5 Binary files /dev/null and b/sounds/sfx/COL2.SFX differ diff --git a/sounds/sfx/COL2.SPN b/sounds/sfx/COL2.SPN new file mode 100644 index 0000000..24982c9 --- /dev/null +++ b/sounds/sfx/COL2.SPN @@ -0,0 +1 @@ +col2 ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $01,$04,$88,$0F,$00,$05,$01,$00,$FF,$01,$50,$66 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sfx/COL3.SFX b/sounds/sfx/COL3.SFX new file mode 100644 index 0000000..be45503 Binary files /dev/null and b/sounds/sfx/COL3.SFX differ diff --git a/sounds/sfx/COL3.SPN b/sounds/sfx/COL3.SPN new file mode 100644 index 0000000..ffbfa73 --- /dev/null +++ b/sounds/sfx/COL3.SPN @@ -0,0 +1 @@ +col3 ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $01,$02,$55,$0F,$03,$03,$FF,$FF,$FF,$01,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sfx/CRACK.SFX b/sounds/sfx/CRACK.SFX new file mode 100644 index 0000000..f3de3e2 Binary files /dev/null and b/sounds/sfx/CRACK.SFX differ diff --git a/sounds/sfx/CRACK.SPN b/sounds/sfx/CRACK.SPN new file mode 100644 index 0000000..424e89e --- /dev/null +++ b/sounds/sfx/CRACK.SPN @@ -0,0 +1 @@ +crack ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $01,$22,$01,$0F,$11,$00,$05,$00,$55,$01,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sfx/ECHO.SFX b/sounds/sfx/ECHO.SFX new file mode 100644 index 0000000..cec46a7 Binary files /dev/null and b/sounds/sfx/ECHO.SFX differ diff --git a/sounds/sfx/ERROR.SFX b/sounds/sfx/ERROR.SFX new file mode 100644 index 0000000..c671bc0 Binary files /dev/null and b/sounds/sfx/ERROR.SFX differ diff --git a/sounds/sfx/ERROR.SPN b/sounds/sfx/ERROR.SPN new file mode 100644 index 0000000..131169e --- /dev/null +++ b/sounds/sfx/ERROR.SPN @@ -0,0 +1 @@ +error ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $04,$01,$80,$0F,$00,$00,$00,$00,$FF,$00,$00,$80 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sfx/EXP.SFX b/sounds/sfx/EXP.SFX new file mode 100644 index 0000000..feb669b Binary files /dev/null and b/sounds/sfx/EXP.SFX differ diff --git a/sounds/sfx/EXP.SPN b/sounds/sfx/EXP.SPN new file mode 100644 index 0000000..bd1258f --- /dev/null +++ b/sounds/sfx/EXP.SPN @@ -0,0 +1 @@ +exp ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $06,$04,$10,$0F,$00,$00,$00,$00,$FF,$01,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sfx/OFF.SFX b/sounds/sfx/OFF.SFX new file mode 100644 index 0000000..2dee7e6 Binary files /dev/null and b/sounds/sfx/OFF.SFX differ diff --git a/sounds/sfx/OFF.SPN b/sounds/sfx/OFF.SPN new file mode 100644 index 0000000..8e7b823 --- /dev/null +++ b/sounds/sfx/OFF.SPN @@ -0,0 +1 @@ +off ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $00,$05,$33,$0F,$05,$03,$10,$00,$FF,$00,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sfx/ON.SFX b/sounds/sfx/ON.SFX new file mode 100644 index 0000000..6c3e5cc Binary files /dev/null and b/sounds/sfx/ON.SFX differ diff --git a/sounds/sfx/ON.SPN b/sounds/sfx/ON.SPN new file mode 100644 index 0000000..6433682 --- /dev/null +++ b/sounds/sfx/ON.SPN @@ -0,0 +1 @@ +on ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $00,$05,$10,$0F,$08,$02,$05,$00,$FF,$00,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sfx/PHASER1.SFX b/sounds/sfx/PHASER1.SFX new file mode 100644 index 0000000..bb330c8 Binary files /dev/null and b/sounds/sfx/PHASER1.SFX differ diff --git a/sounds/sfx/PHASER1.SPN b/sounds/sfx/PHASER1.SPN new file mode 100644 index 0000000..bed9142 --- /dev/null +++ b/sounds/sfx/PHASER1.SPN @@ -0,0 +1 @@ +phaser1 ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $01,$04,$10,$0F,$00,$03,$01,$00,$FF,$01,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sfx/PHASER2.SFX b/sounds/sfx/PHASER2.SFX new file mode 100644 index 0000000..843cc12 Binary files /dev/null and b/sounds/sfx/PHASER2.SFX differ diff --git a/sounds/sfx/PHASER2.SPN b/sounds/sfx/PHASER2.SPN new file mode 100644 index 0000000..0ff9b19 --- /dev/null +++ b/sounds/sfx/PHASER2.SPN @@ -0,0 +1 @@ +phaser2 ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $01,$04,$88,$0F,$00,$01,$01,$00,$FF,$01,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sfx/PHASER3.SFX b/sounds/sfx/PHASER3.SFX new file mode 100644 index 0000000..3f95295 Binary files /dev/null and b/sounds/sfx/PHASER3.SFX differ diff --git a/sounds/sfx/PHASER3.SPN b/sounds/sfx/PHASER3.SPN new file mode 100644 index 0000000..e3629e3 --- /dev/null +++ b/sounds/sfx/PHASER3.SPN @@ -0,0 +1 @@ +phaser3 ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $01,$04,$88,$0F,$00,$02,$01,$00,$FF,$01,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sfx/SHOOT.SFX b/sounds/sfx/SHOOT.SFX new file mode 100644 index 0000000..5994a4a Binary files /dev/null and b/sounds/sfx/SHOOT.SFX differ diff --git a/sounds/sfx/SHOOT.SPN b/sounds/sfx/SHOOT.SPN new file mode 100644 index 0000000..3b6f357 --- /dev/null +++ b/sounds/sfx/SHOOT.SPN @@ -0,0 +1 @@ +shoot ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $06,$03,$80,$0F,$08,$04,$05,$00,$FF,$40,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sfx/TEST1.SFX b/sounds/sfx/TEST1.SFX new file mode 100644 index 0000000..ec73e8b Binary files /dev/null and b/sounds/sfx/TEST1.SFX differ diff --git a/sounds/sfx/TEST2.SFX b/sounds/sfx/TEST2.SFX new file mode 100644 index 0000000..c671bc0 Binary files /dev/null and b/sounds/sfx/TEST2.SFX differ diff --git a/sounds/sfx/TEST2.SPN b/sounds/sfx/TEST2.SPN new file mode 100644 index 0000000..e225477 --- /dev/null +++ b/sounds/sfx/TEST2.SPN @@ -0,0 +1 @@ +ton1 ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $04,$01,$80,$0F,$00,$00,$00,$00,$FF,$00,$00,$80 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sfx/WALL.SFX b/sounds/sfx/WALL.SFX new file mode 100644 index 0000000..dec7ab7 Binary files /dev/null and b/sounds/sfx/WALL.SFX differ diff --git a/sounds/sfx/WALL.SPN b/sounds/sfx/WALL.SPN new file mode 100644 index 0000000..8465ad0 --- /dev/null +++ b/sounds/sfx/WALL.SPN @@ -0,0 +1 @@ +wall ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $04,$FF,$FF,$0F,$01,$00,$01,$00,$FF,$06,$20,$00 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/sounds/sid/1_Emax.dmp b/sounds/sid/1_Emax.dmp new file mode 100644 index 0000000..bc43cb0 Binary files /dev/null and b/sounds/sid/1_Emax.dmp differ diff --git a/sounds/sid/Blitter.dmp b/sounds/sid/Blitter.dmp new file mode 100644 index 0000000..e78ce1a Binary files /dev/null and b/sounds/sid/Blitter.dmp differ diff --git a/sounds/sid/Boulder_Dash.dmp b/sounds/sid/Boulder_Dash.dmp new file mode 100644 index 0000000..40e9bd1 Binary files /dev/null and b/sounds/sid/Boulder_Dash.dmp differ diff --git a/sounds/sid/Boz_Hubbard.dmp b/sounds/sid/Boz_Hubbard.dmp new file mode 100644 index 0000000..1a3d5eb Binary files /dev/null and b/sounds/sid/Boz_Hubbard.dmp differ diff --git a/sounds/sid/alemix/Afterburner.dmp b/sounds/sid/alemix/Afterburner.dmp new file mode 100644 index 0000000..605edcf Binary files /dev/null and b/sounds/sid/alemix/Afterburner.dmp differ diff --git a/sounds/sid/alemix/Comic_Bakery.dmp b/sounds/sid/alemix/Comic_Bakery.dmp new file mode 100644 index 0000000..121f97a Binary files /dev/null and b/sounds/sid/alemix/Comic_Bakery.dmp differ diff --git a/sounds/sid/alemix/Commando.dmp b/sounds/sid/alemix/Commando.dmp new file mode 100644 index 0000000..5337073 Binary files /dev/null and b/sounds/sid/alemix/Commando.dmp differ diff --git a/sounds/sid/alemix/Cucumber_Juice_2_tune_3.dmp b/sounds/sid/alemix/Cucumber_Juice_2_tune_3.dmp new file mode 100644 index 0000000..31d69bd Binary files /dev/null and b/sounds/sid/alemix/Cucumber_Juice_2_tune_3.dmp differ diff --git a/sounds/sid/alemix/Eskimonika.dmp b/sounds/sid/alemix/Eskimonika.dmp new file mode 100644 index 0000000..afdf02f Binary files /dev/null and b/sounds/sid/alemix/Eskimonika.dmp differ diff --git a/sounds/sid/alemix/Funk_Junk.dmp b/sounds/sid/alemix/Funk_Junk.dmp new file mode 100644 index 0000000..d9cd806 Binary files /dev/null and b/sounds/sid/alemix/Funk_Junk.dmp differ diff --git a/sounds/sid/alemix/Ghouls_n_Ghosts_08.dmp b/sounds/sid/alemix/Ghouls_n_Ghosts_08.dmp new file mode 100644 index 0000000..fb47f23 Binary files /dev/null and b/sounds/sid/alemix/Ghouls_n_Ghosts_08.dmp differ diff --git a/sounds/sid/alemix/Golden_Axe.dmp b/sounds/sid/alemix/Golden_Axe.dmp new file mode 100644 index 0000000..d2236af Binary files /dev/null and b/sounds/sid/alemix/Golden_Axe.dmp differ diff --git a/sounds/sid/alemix/International_Karate.dmp b/sounds/sid/alemix/International_Karate.dmp new file mode 100644 index 0000000..5431a3e Binary files /dev/null and b/sounds/sid/alemix/International_Karate.dmp differ diff --git a/sounds/sid/alemix/Ocean_Loader_2.dmp b/sounds/sid/alemix/Ocean_Loader_2.dmp new file mode 100644 index 0000000..19100a0 Binary files /dev/null and b/sounds/sid/alemix/Ocean_Loader_2.dmp differ diff --git a/sounds/sid/sid1/1_Emax.dmp b/sounds/sid/sid1/1_Emax.dmp new file mode 100644 index 0000000..bc43cb0 Binary files /dev/null and b/sounds/sid/sid1/1_Emax.dmp differ diff --git a/sounds/sid/sid1/BOZ_HUB.DMP b/sounds/sid/sid1/BOZ_HUB.DMP new file mode 100644 index 0000000..1a3d5eb Binary files /dev/null and b/sounds/sid/sid1/BOZ_HUB.DMP differ diff --git a/sounds/sid/sid1/Blitter.dmp b/sounds/sid/sid1/Blitter.dmp new file mode 100644 index 0000000..e78ce1a Binary files /dev/null and b/sounds/sid/sid1/Blitter.dmp differ diff --git a/sounds/sid/sid1/Blue_Max_2001.dmp b/sounds/sid/sid1/Blue_Max_2001.dmp new file mode 100644 index 0000000..218d33d Binary files /dev/null and b/sounds/sid/sid1/Blue_Max_2001.dmp differ diff --git a/sounds/sid/sid1/Bobsleigh.dmp b/sounds/sid/sid1/Bobsleigh.dmp new file mode 100644 index 0000000..9f82152 Binary files /dev/null and b/sounds/sid/sid1/Bobsleigh.dmp differ diff --git a/sounds/sid/sid1/Boulder_Dash.dmp b/sounds/sid/sid1/Boulder_Dash.dmp new file mode 100644 index 0000000..40e9bd1 Binary files /dev/null and b/sounds/sid/sid1/Boulder_Dash.dmp differ diff --git a/sounds/sid/sid1/Bruth-Lan-Dan.dmp b/sounds/sid/sid1/Bruth-Lan-Dan.dmp new file mode 100644 index 0000000..1ac4c98 Binary files /dev/null and b/sounds/sid/sid1/Bruth-Lan-Dan.dmp differ diff --git a/sounds/sid/sid1/Bubble_Bobble.dmp b/sounds/sid/sid1/Bubble_Bobble.dmp new file mode 100644 index 0000000..059c127 Binary files /dev/null and b/sounds/sid/sid1/Bubble_Bobble.dmp differ diff --git a/sounds/sid/sid1/California_Games.dmp b/sounds/sid/sid1/California_Games.dmp new file mode 100644 index 0000000..3c599f0 Binary files /dev/null and b/sounds/sid/sid1/California_Games.dmp differ diff --git a/sounds/sid/sid1/Candleglow.dmp b/sounds/sid/sid1/Candleglow.dmp new file mode 100644 index 0000000..b5a9412 Binary files /dev/null and b/sounds/sid/sid1/Candleglow.dmp differ diff --git a/sounds/sid/sid1/Chevytech.dmp b/sounds/sid/sid1/Chevytech.dmp new file mode 100644 index 0000000..57a35b9 Binary files /dev/null and b/sounds/sid/sid1/Chevytech.dmp differ diff --git a/sounds/sid/sid1/Chimera.dmp b/sounds/sid/sid1/Chimera.dmp new file mode 100644 index 0000000..26fc6e4 Binary files /dev/null and b/sounds/sid/sid1/Chimera.dmp differ diff --git a/sounds/sid/sid1/Chris_01.dmp b/sounds/sid/sid1/Chris_01.dmp new file mode 100644 index 0000000..b080de9 Binary files /dev/null and b/sounds/sid/sid1/Chris_01.dmp differ diff --git a/sounds/sid/sid1/Ciabah_1_magazine.dmp b/sounds/sid/sid1/Ciabah_1_magazine.dmp new file mode 100644 index 0000000..04fae2a Binary files /dev/null and b/sounds/sid/sid1/Ciabah_1_magazine.dmp differ diff --git a/sounds/sid/sid1/Commando.dmp b/sounds/sid/sid1/Commando.dmp new file mode 100644 index 0000000..8fc3233 Binary files /dev/null and b/sounds/sid/sid1/Commando.dmp differ diff --git a/sounds/sid/sid1/Daley_Thompsons_Decathlon.dmp b/sounds/sid/sid1/Daley_Thompsons_Decathlon.dmp new file mode 100644 index 0000000..5083f75 Binary files /dev/null and b/sounds/sid/sid1/Daley_Thompsons_Decathlon.dmp differ diff --git a/sounds/sid/sid1/Deblin_01.dmp b/sounds/sid/sid1/Deblin_01.dmp new file mode 100644 index 0000000..8a34fd3 Binary files /dev/null and b/sounds/sid/sid1/Deblin_01.dmp differ diff --git a/sounds/sid/sid1/Domino.dmp b/sounds/sid/sid1/Domino.dmp new file mode 100644 index 0000000..19ccf80 Binary files /dev/null and b/sounds/sid/sid1/Domino.dmp differ diff --git a/sounds/sid/sid1/Dont_Worry_be_Happy.dmp b/sounds/sid/sid1/Dont_Worry_be_Happy.dmp new file mode 100644 index 0000000..90c2666 Binary files /dev/null and b/sounds/sid/sid1/Dont_Worry_be_Happy.dmp differ diff --git a/sounds/sid/sid1/Eye.dmp b/sounds/sid/sid1/Eye.dmp new file mode 100644 index 0000000..d9ea5a0 Binary files /dev/null and b/sounds/sid/sid1/Eye.dmp differ diff --git a/sounds/sid/sid1/Fly_Around_the_World.dmp b/sounds/sid/sid1/Fly_Around_the_World.dmp new file mode 100644 index 0000000..c20e2c2 Binary files /dev/null and b/sounds/sid/sid1/Fly_Around_the_World.dmp differ diff --git a/sounds/sid/sid1/Gyroscope.dmp b/sounds/sid/sid1/Gyroscope.dmp new file mode 100644 index 0000000..c71ede9 Binary files /dev/null and b/sounds/sid/sid1/Gyroscope.dmp differ diff --git a/sounds/sid/sid1/Human_Race.dmp b/sounds/sid/sid1/Human_Race.dmp new file mode 100644 index 0000000..a2a6257 Binary files /dev/null and b/sounds/sid/sid1/Human_Race.dmp differ diff --git a/sounds/sid/sid1/IK.dmp b/sounds/sid/sid1/IK.dmp new file mode 100644 index 0000000..8d6ccf1 Binary files /dev/null and b/sounds/sid/sid1/IK.dmp differ diff --git a/sounds/sid/sid1/IK_plus.dmp b/sounds/sid/sid1/IK_plus.dmp new file mode 100644 index 0000000..65b5343 Binary files /dev/null and b/sounds/sid/sid1/IK_plus.dmp differ diff --git a/sounds/sid/sid1/Klamany_Zutass.dmp b/sounds/sid/sid1/Klamany_Zutass.dmp new file mode 100644 index 0000000..78bd7ec Binary files /dev/null and b/sounds/sid/sid1/Klamany_Zutass.dmp differ diff --git a/sounds/sid/sid1/Oxygen_4.dmp b/sounds/sid/sid1/Oxygen_4.dmp new file mode 100644 index 0000000..1af49a2 Binary files /dev/null and b/sounds/sid/sid1/Oxygen_4.dmp differ diff --git a/sounds/sid/sid1/S_O_S.dmp b/sounds/sid/sid1/S_O_S.dmp new file mode 100644 index 0000000..e8a5629 Binary files /dev/null and b/sounds/sid/sid1/S_O_S.dmp differ diff --git a/sounds/sid/sid1/Stepper.dmp b/sounds/sid/sid1/Stepper.dmp new file mode 100644 index 0000000..0820be8 Binary files /dev/null and b/sounds/sid/sid1/Stepper.dmp differ diff --git a/sounds/sid/sid1/Synth_Sample.dmp b/sounds/sid/sid1/Synth_Sample.dmp new file mode 100644 index 0000000..183b369 Binary files /dev/null and b/sounds/sid/sid1/Synth_Sample.dmp differ diff --git a/sounds/sid/sid1/Theres_That_Light_Again.dmp b/sounds/sid/sid1/Theres_That_Light_Again.dmp new file mode 100644 index 0000000..5e7bc3e Binary files /dev/null and b/sounds/sid/sid1/Theres_That_Light_Again.dmp differ diff --git a/sounds/sid/sid1/mule.dmp b/sounds/sid/sid1/mule.dmp new file mode 100644 index 0000000..bc640c7 Binary files /dev/null and b/sounds/sid/sid1/mule.dmp differ diff --git a/sounds/sid/sid1/xenon_m.dmp b/sounds/sid/sid1/xenon_m.dmp new file mode 100644 index 0000000..b609361 Binary files /dev/null and b/sounds/sid/sid1/xenon_m.dmp differ diff --git a/sounds/sid/sid2/Castlevania_64_Mixes_01.dmp b/sounds/sid/sid2/Castlevania_64_Mixes_01.dmp new file mode 100644 index 0000000..fb05a97 Binary files /dev/null and b/sounds/sid/sid2/Castlevania_64_Mixes_01.dmp differ diff --git a/sounds/sid/sid2/Crankshaft_3003.dmp b/sounds/sid/sid2/Crankshaft_3003.dmp new file mode 100644 index 0000000..3be873b Binary files /dev/null and b/sounds/sid/sid2/Crankshaft_3003.dmp differ diff --git a/sounds/sid/sid2/Cucumber_Juice_2_tune_3.dmp b/sounds/sid/sid2/Cucumber_Juice_2_tune_3.dmp new file mode 100644 index 0000000..af69242 Binary files /dev/null and b/sounds/sid/sid2/Cucumber_Juice_2_tune_3.dmp differ diff --git a/sounds/sid/sid2/Funkrock.dmp b/sounds/sid/sid2/Funkrock.dmp new file mode 100644 index 0000000..123485d Binary files /dev/null and b/sounds/sid/sid2/Funkrock.dmp differ diff --git a/sounds/sid/sid2/Lamebada.dmp b/sounds/sid/sid2/Lamebada.dmp new file mode 100644 index 0000000..65a8510 Binary files /dev/null and b/sounds/sid/sid2/Lamebada.dmp differ diff --git a/sounds/sid/sid2/Mr_Marvellous.dmp b/sounds/sid/sid2/Mr_Marvellous.dmp new file mode 100644 index 0000000..667e4f1 Binary files /dev/null and b/sounds/sid/sid2/Mr_Marvellous.dmp differ diff --git a/sounds/sid/sid2/Reggae.dmp b/sounds/sid/sid2/Reggae.dmp new file mode 100644 index 0000000..70b1540 Binary files /dev/null and b/sounds/sid/sid2/Reggae.dmp differ diff --git a/sounds/sid/sid2/Super_Frog.dmp b/sounds/sid/sid2/Super_Frog.dmp new file mode 100644 index 0000000..0418eb1 Binary files /dev/null and b/sounds/sid/sid2/Super_Frog.dmp differ diff --git a/sounds/sid/sid2/Super_Mario_Land.dmp b/sounds/sid/sid2/Super_Mario_Land.dmp new file mode 100644 index 0000000..fc09947 Binary files /dev/null and b/sounds/sid/sid2/Super_Mario_Land.dmp differ diff --git a/sounds/sid/sid3/1942.dmp b/sounds/sid/sid3/1942.dmp new file mode 100644 index 0000000..dca6170 Binary files /dev/null and b/sounds/sid/sid3/1942.dmp differ diff --git a/sounds/sid/sid3/AHSDF.dmp b/sounds/sid/sid3/AHSDF.dmp new file mode 100644 index 0000000..9ac2a05 Binary files /dev/null and b/sounds/sid/sid3/AHSDF.dmp differ diff --git a/sounds/sid/sid3/AWMonty.dmp b/sounds/sid/sid3/AWMonty.dmp new file mode 100644 index 0000000..ef470d0 Binary files /dev/null and b/sounds/sid/sid3/AWMonty.dmp differ diff --git a/sounds/sid/sid3/Arkanoid.dmp b/sounds/sid/sid3/Arkanoid.dmp new file mode 100644 index 0000000..ca82f86 Binary files /dev/null and b/sounds/sid/sid3/Arkanoid.dmp differ diff --git a/sounds/sid/sid3/Aztec.dmp b/sounds/sid/sid3/Aztec.dmp new file mode 100644 index 0000000..0e496fa Binary files /dev/null and b/sounds/sid/sid3/Aztec.dmp differ diff --git a/sounds/sid/sid3/BBobble.dmp b/sounds/sid/sid3/BBobble.dmp new file mode 100644 index 0000000..059c127 Binary files /dev/null and b/sounds/sid/sid3/BBobble.dmp differ diff --git a/sounds/sid/sid3/BDash.dmp b/sounds/sid/sid3/BDash.dmp new file mode 100644 index 0000000..fe34609 Binary files /dev/null and b/sounds/sid/sid3/BDash.dmp differ diff --git a/sounds/sid/sid3/BLee.dmp b/sounds/sid/sid3/BLee.dmp new file mode 100644 index 0000000..e33b1e4 Binary files /dev/null and b/sounds/sid/sid3/BLee.dmp differ diff --git a/sounds/sid/sid3/Batman.dmp b/sounds/sid/sid3/Batman.dmp new file mode 100644 index 0000000..6502bf4 Binary files /dev/null and b/sounds/sid/sid3/Batman.dmp differ diff --git a/sounds/sid/sid3/Batman2.dmp b/sounds/sid/sid3/Batman2.dmp new file mode 100644 index 0000000..4cf20e9 Binary files /dev/null and b/sounds/sid/sid3/Batman2.dmp differ diff --git a/sounds/sid/sid3/Batman3.dmp b/sounds/sid/sid3/Batman3.dmp new file mode 100644 index 0000000..227242c Binary files /dev/null and b/sounds/sid/sid3/Batman3.dmp differ diff --git a/sounds/sid/sid3/Batman4.dmp b/sounds/sid/sid3/Batman4.dmp new file mode 100644 index 0000000..2f3edcf Binary files /dev/null and b/sounds/sid/sid3/Batman4.dmp differ diff --git a/sounds/sid/sid3/Batman5.dmp b/sounds/sid/sid3/Batman5.dmp new file mode 100644 index 0000000..86770cc Binary files /dev/null and b/sounds/sid/sid3/Batman5.dmp differ diff --git a/sounds/sid/sid3/Batman6.dmp b/sounds/sid/sid3/Batman6.dmp new file mode 100644 index 0000000..b53f332 Binary files /dev/null and b/sounds/sid/sid3/Batman6.dmp differ diff --git a/sounds/sid/sid3/CWorld.dmp b/sounds/sid/sid3/CWorld.dmp new file mode 100644 index 0000000..5194abb Binary files /dev/null and b/sounds/sid/sid3/CWorld.dmp differ diff --git a/sounds/sid/sid3/Calgames.dmp b/sounds/sid/sid3/Calgames.dmp new file mode 100644 index 0000000..3c599f0 Binary files /dev/null and b/sounds/sid/sid3/Calgames.dmp differ diff --git a/sounds/sid/sid3/CastleV.dmp b/sounds/sid/sid3/CastleV.dmp new file mode 100644 index 0000000..e5cff35 Binary files /dev/null and b/sounds/sid/sid3/CastleV.dmp differ diff --git a/sounds/sid/sid3/Cauld2.dmp b/sounds/sid/sid3/Cauld2.dmp new file mode 100644 index 0000000..60d9a88 Binary files /dev/null and b/sounds/sid/sid3/Cauld2.dmp differ diff --git a/sounds/sid/sid3/Cobra.dmp b/sounds/sid/sid3/Cobra.dmp new file mode 100644 index 0000000..3a64fb9 Binary files /dev/null and b/sounds/sid/sid3/Cobra.dmp differ diff --git a/sounds/sid/sid3/Cybern2.dmp b/sounds/sid/sid3/Cybern2.dmp new file mode 100644 index 0000000..66fb778 Binary files /dev/null and b/sounds/sid/sid3/Cybern2.dmp differ diff --git a/sounds/sid/sid3/Cybernoid.dmp b/sounds/sid/sid3/Cybernoid.dmp new file mode 100644 index 0000000..e590c67 Binary files /dev/null and b/sounds/sid/sid3/Cybernoid.dmp differ diff --git a/sounds/sid/sid3/Daley.dmp b/sounds/sid/sid3/Daley.dmp new file mode 100644 index 0000000..5083f75 Binary files /dev/null and b/sounds/sid/sid3/Daley.dmp differ diff --git a/sounds/sid/sid3/Dragons.dmp b/sounds/sid/sid3/Dragons.dmp new file mode 100644 index 0000000..50fd070 Binary files /dev/null and b/sounds/sid/sid3/Dragons.dmp differ diff --git a/sounds/sid/sid3/DropGirl.dmp b/sounds/sid/sid3/DropGirl.dmp new file mode 100644 index 0000000..bc2d8b6 Binary files /dev/null and b/sounds/sid/sid3/DropGirl.dmp differ diff --git a/sounds/sid/sid3/Eleminator.dmp b/sounds/sid/sid3/Eleminator.dmp new file mode 100644 index 0000000..02ed2b3 Binary files /dev/null and b/sounds/sid/sid3/Eleminator.dmp differ diff --git a/sounds/sid/sid3/Enforcer.dmp b/sounds/sid/sid3/Enforcer.dmp new file mode 100644 index 0000000..47cd480 Binary files /dev/null and b/sounds/sid/sid3/Enforcer.dmp differ diff --git a/sounds/sid/sid3/GGiana.dmp b/sounds/sid/sid3/GGiana.dmp new file mode 100644 index 0000000..34427b6 Binary files /dev/null and b/sounds/sid/sid3/GGiana.dmp differ diff --git a/sounds/sid/sid3/Gauntle3.dmp b/sounds/sid/sid3/Gauntle3.dmp new file mode 100644 index 0000000..2843d95 Binary files /dev/null and b/sounds/sid/sid3/Gauntle3.dmp differ diff --git a/sounds/sid/sid3/Ghostsn.dmp b/sounds/sid/sid3/Ghostsn.dmp new file mode 100644 index 0000000..3984733 Binary files /dev/null and b/sounds/sid/sid3/Ghostsn.dmp differ diff --git a/sounds/sid/sid3/Ghoulsn.dmp b/sounds/sid/sid3/Ghoulsn.dmp new file mode 100644 index 0000000..1476c55 Binary files /dev/null and b/sounds/sid/sid3/Ghoulsn.dmp differ diff --git a/sounds/sid/sid3/GianBoss.dmp b/sounds/sid/sid3/GianBoss.dmp new file mode 100644 index 0000000..e6dadf2 Binary files /dev/null and b/sounds/sid/sid3/GianBoss.dmp differ diff --git a/sounds/sid/sid3/GianFire.dmp b/sounds/sid/sid3/GianFire.dmp new file mode 100644 index 0000000..026710a Binary files /dev/null and b/sounds/sid/sid3/GianFire.dmp differ diff --git a/sounds/sid/sid3/GianHigh.dmp b/sounds/sid/sid3/GianHigh.dmp new file mode 100644 index 0000000..d15e87f Binary files /dev/null and b/sounds/sid/sid3/GianHigh.dmp differ diff --git a/sounds/sid/sid3/GianNext.dmp b/sounds/sid/sid3/GianNext.dmp new file mode 100644 index 0000000..ffa8411 Binary files /dev/null and b/sounds/sid/sid3/GianNext.dmp differ diff --git a/sounds/sid/sid3/Gianalvl.dmp b/sounds/sid/sid3/Gianalvl.dmp new file mode 100644 index 0000000..67434aa Binary files /dev/null and b/sounds/sid/sid3/Gianalvl.dmp differ diff --git a/sounds/sid/sid3/Golden_Axe.dmp b/sounds/sid/sid3/Golden_Axe.dmp new file mode 100644 index 0000000..1b1a123 Binary files /dev/null and b/sounds/sid/sid3/Golden_Axe.dmp differ diff --git a/sounds/sid/sid3/Hammer.dmp b/sounds/sid/sid3/Hammer.dmp new file mode 100644 index 0000000..7db0776 Binary files /dev/null and b/sounds/sid/sid3/Hammer.dmp differ diff --git a/sounds/sid/sid3/Hobbit.dmp b/sounds/sid/sid3/Hobbit.dmp new file mode 100644 index 0000000..c6f1595 Binary files /dev/null and b/sounds/sid/sid3/Hobbit.dmp differ diff --git a/sounds/sid/sid3/IKarate.dmp b/sounds/sid/sid3/IKarate.dmp new file mode 100644 index 0000000..2ce0133 Binary files /dev/null and b/sounds/sid/sid3/IKarate.dmp differ diff --git a/sounds/sid/sid3/IKplus.dmp b/sounds/sid/sid3/IKplus.dmp new file mode 100644 index 0000000..406e2f3 Binary files /dev/null and b/sounds/sid/sid3/IKplus.dmp differ diff --git a/sounds/sid/sid3/IceAge.dmp b/sounds/sid/sid3/IceAge.dmp new file mode 100644 index 0000000..4f4ce4e Binary files /dev/null and b/sounds/sid/sid3/IceAge.dmp differ diff --git a/sounds/sid/sid3/Iend.dmp b/sounds/sid/sid3/Iend.dmp new file mode 100644 index 0000000..2695b87 Binary files /dev/null and b/sounds/sid/sid3/Iend.dmp differ diff --git a/sounds/sid/sid3/Intro.dmp b/sounds/sid/sid3/Intro.dmp new file mode 100644 index 0000000..f159fe4 Binary files /dev/null and b/sounds/sid/sid3/Intro.dmp differ diff --git a/sounds/sid/sid3/IntroFin.dmp b/sounds/sid/sid3/IntroFin.dmp new file mode 100644 index 0000000..c45c243 Binary files /dev/null and b/sounds/sid/sid3/IntroFin.dmp differ diff --git a/sounds/sid/sid3/Jabdah.dmp b/sounds/sid/sid3/Jabdah.dmp new file mode 100644 index 0000000..a85c81e Binary files /dev/null and b/sounds/sid/sid3/Jabdah.dmp differ diff --git a/sounds/sid/sid3/Jackal.dmp b/sounds/sid/sid3/Jackal.dmp new file mode 100644 index 0000000..4c95343 Binary files /dev/null and b/sounds/sid/sid3/Jackal.dmp differ diff --git a/sounds/sid/sid3/KED.dmp b/sounds/sid/sid3/KED.dmp new file mode 100644 index 0000000..fa6acae Binary files /dev/null and b/sounds/sid/sid3/KED.dmp differ diff --git a/sounds/sid/sid3/Kikst2.dmp b/sounds/sid/sid3/Kikst2.dmp new file mode 100644 index 0000000..b5e900f Binary files /dev/null and b/sounds/sid/sid3/Kikst2.dmp differ diff --git a/sounds/sid/sid3/Krakout.dmp b/sounds/sid/sid3/Krakout.dmp new file mode 100644 index 0000000..e3c89e6 Binary files /dev/null and b/sounds/sid/sid3/Krakout.dmp differ diff --git a/sounds/sid/sid3/Krakout1.dmp b/sounds/sid/sid3/Krakout1.dmp new file mode 100644 index 0000000..d3223ca Binary files /dev/null and b/sounds/sid/sid3/Krakout1.dmp differ diff --git a/sounds/sid/sid3/Krakout2.dmp b/sounds/sid/sid3/Krakout2.dmp new file mode 100644 index 0000000..50526dd Binary files /dev/null and b/sounds/sid/sid3/Krakout2.dmp differ diff --git a/sounds/sid/sid3/Krakout3.dmp b/sounds/sid/sid3/Krakout3.dmp new file mode 100644 index 0000000..0e6f53e Binary files /dev/null and b/sounds/sid/sid3/Krakout3.dmp differ diff --git a/sounds/sid/sid3/Krakow.dmp b/sounds/sid/sid3/Krakow.dmp new file mode 100644 index 0000000..51683c7 Binary files /dev/null and b/sounds/sid/sid3/Krakow.dmp differ diff --git a/sounds/sid/sid3/LNinja.dmp b/sounds/sid/sid3/LNinja.dmp new file mode 100644 index 0000000..0afb25a Binary files /dev/null and b/sounds/sid/sid3/LNinja.dmp differ diff --git a/sounds/sid/sid3/LNinja2.dmp b/sounds/sid/sid3/LNinja2.dmp new file mode 100644 index 0000000..77e1d7b Binary files /dev/null and b/sounds/sid/sid3/LNinja2.dmp differ diff --git a/sounds/sid/sid3/LNinja3.dmp b/sounds/sid/sid3/LNinja3.dmp new file mode 100644 index 0000000..4a124c9 Binary files /dev/null and b/sounds/sid/sid3/LNinja3.dmp differ diff --git a/sounds/sid/sid3/Lax_Up.dmp b/sounds/sid/sid3/Lax_Up.dmp new file mode 100644 index 0000000..da5f891 Binary files /dev/null and b/sounds/sid/sid3/Lax_Up.dmp differ diff --git a/sounds/sid/sid3/Lightforce.dmp b/sounds/sid/sid3/Lightforce.dmp new file mode 100644 index 0000000..063bcb9 Binary files /dev/null and b/sounds/sid/sid3/Lightforce.dmp differ diff --git a/sounds/sid/sid3/MHuman.dmp b/sounds/sid/sid3/MHuman.dmp new file mode 100644 index 0000000..c1ae13f Binary files /dev/null and b/sounds/sid/sid3/MHuman.dmp differ diff --git a/sounds/sid/sid3/Midnight.dmp b/sounds/sid/sid3/Midnight.dmp new file mode 100644 index 0000000..c543ac9 Binary files /dev/null and b/sounds/sid/sid3/Midnight.dmp differ diff --git a/sounds/sid/sid3/Mofm.dmp b/sounds/sid/sid3/Mofm.dmp new file mode 100644 index 0000000..d0652c6 Binary files /dev/null and b/sounds/sid/sid3/Mofm.dmp differ diff --git a/sounds/sid/sid3/Monday.dmp b/sounds/sid/sid3/Monday.dmp new file mode 100644 index 0000000..acb4fac Binary files /dev/null and b/sounds/sid/sid3/Monday.dmp differ diff --git a/sounds/sid/sid3/MrMarv.dmp b/sounds/sid/sid3/MrMarv.dmp new file mode 100644 index 0000000..189fb6a Binary files /dev/null and b/sounds/sid/sid3/MrMarv.dmp differ diff --git a/sounds/sid/sid3/Mysteries.dmp b/sounds/sid/sid3/Mysteries.dmp new file mode 100644 index 0000000..de0c672 Binary files /dev/null and b/sounds/sid/sid3/Mysteries.dmp differ diff --git a/sounds/sid/sid3/Myth_mix.dmp b/sounds/sid/sid3/Myth_mix.dmp new file mode 100644 index 0000000..4a910af Binary files /dev/null and b/sounds/sid/sid3/Myth_mix.dmp differ diff --git a/sounds/sid/sid3/Nemesis.dmp b/sounds/sid/sid3/Nemesis.dmp new file mode 100644 index 0000000..07c956a Binary files /dev/null and b/sounds/sid/sid3/Nemesis.dmp differ diff --git a/sounds/sid/sid3/NightB.dmp b/sounds/sid/sid3/NightB.dmp new file mode 100644 index 0000000..c872b0a Binary files /dev/null and b/sounds/sid/sid3/NightB.dmp differ diff --git a/sounds/sid/sid3/OutrunRe.dmp b/sounds/sid/sid3/OutrunRe.dmp new file mode 100644 index 0000000..aff83b0 Binary files /dev/null and b/sounds/sid/sid3/OutrunRe.dmp differ diff --git a/sounds/sid/sid3/Oxyron.dmp b/sounds/sid/sid3/Oxyron.dmp new file mode 100644 index 0000000..635fada Binary files /dev/null and b/sounds/sid/sid3/Oxyron.dmp differ diff --git a/sounds/sid/sid3/PPop.dmp b/sounds/sid/sid3/PPop.dmp new file mode 100644 index 0000000..a8fd32d Binary files /dev/null and b/sounds/sid/sid3/PPop.dmp differ diff --git a/sounds/sid/sid3/Paperboy.dmp b/sounds/sid/sid3/Paperboy.dmp new file mode 100644 index 0000000..529fbdc Binary files /dev/null and b/sounds/sid/sid3/Paperboy.dmp differ diff --git a/sounds/sid/sid3/Parallax.dmp b/sounds/sid/sid3/Parallax.dmp new file mode 100644 index 0000000..535f782 Binary files /dev/null and b/sounds/sid/sid3/Parallax.dmp differ diff --git a/sounds/sid/sid3/Pitfall2.dmp b/sounds/sid/sid3/Pitfall2.dmp new file mode 100644 index 0000000..0114f4a Binary files /dev/null and b/sounds/sid/sid3/Pitfall2.dmp differ diff --git a/sounds/sid/sid3/PowerD.dmp b/sounds/sid/sid3/PowerD.dmp new file mode 100644 index 0000000..bb6ea87 Binary files /dev/null and b/sounds/sid/sid3/PowerD.dmp differ diff --git a/sounds/sid/sid3/R-Type.dmp b/sounds/sid/sid3/R-Type.dmp new file mode 100644 index 0000000..8f4bd83 Binary files /dev/null and b/sounds/sid/sid3/R-Type.dmp differ diff --git a/sounds/sid/sid3/REALIntr.dmp b/sounds/sid/sid3/REALIntr.dmp new file mode 100644 index 0000000..f159fe4 Binary files /dev/null and b/sounds/sid/sid3/REALIntr.dmp differ diff --git a/sounds/sid/sid3/REALplus.dmp b/sounds/sid/sid3/REALplus.dmp new file mode 100644 index 0000000..749dcbb Binary files /dev/null and b/sounds/sid/sid3/REALplus.dmp differ diff --git a/sounds/sid/sid3/Rasputin.dmp b/sounds/sid/sid3/Rasputin.dmp new file mode 100644 index 0000000..1b5d0d8 Binary files /dev/null and b/sounds/sid/sid3/Rasputin.dmp differ diff --git a/sounds/sid/sid3/RickD.dmp b/sounds/sid/sid3/RickD.dmp new file mode 100644 index 0000000..3633ed3 Binary files /dev/null and b/sounds/sid/sid3/RickD.dmp differ diff --git a/sounds/sid/sid3/Robocop.dmp b/sounds/sid/sid3/Robocop.dmp new file mode 100644 index 0000000..78b535e Binary files /dev/null and b/sounds/sid/sid3/Robocop.dmp differ diff --git a/sounds/sid/sid3/Ronny.dmp b/sounds/sid/sid3/Ronny.dmp new file mode 100644 index 0000000..b9405fe Binary files /dev/null and b/sounds/sid/sid3/Ronny.dmp differ diff --git a/sounds/sid/sid3/Shadow.dmp b/sounds/sid/sid3/Shadow.dmp new file mode 100644 index 0000000..f906882 Binary files /dev/null and b/sounds/sid/sid3/Shadow.dmp differ diff --git a/sounds/sid/sid3/Speedball.dmp b/sounds/sid/sid3/Speedball.dmp new file mode 100644 index 0000000..5af1cf2 Binary files /dev/null and b/sounds/sid/sid3/Speedball.dmp differ diff --git a/sounds/sid/sid3/Spyhunt.dmp b/sounds/sid/sid3/Spyhunt.dmp new file mode 100644 index 0000000..2f7d5ac Binary files /dev/null and b/sounds/sid/sid3/Spyhunt.dmp differ diff --git a/sounds/sid/sid3/Storm.dmp b/sounds/sid/sid3/Storm.dmp new file mode 100644 index 0000000..ca37018 Binary files /dev/null and b/sounds/sid/sid3/Storm.dmp differ diff --git a/sounds/sid/sid3/Stormlo.dmp b/sounds/sid/sid3/Stormlo.dmp new file mode 100644 index 0000000..ef70e7d Binary files /dev/null and b/sounds/sid/sid3/Stormlo.dmp differ diff --git a/sounds/sid/sid3/TJetPak.dmp b/sounds/sid/sid3/TJetPak.dmp new file mode 100644 index 0000000..5912fcb Binary files /dev/null and b/sounds/sid/sid3/TJetPak.dmp differ diff --git a/sounds/sid/sid3/Tcats.dmp b/sounds/sid/sid3/Tcats.dmp new file mode 100644 index 0000000..df1b868 Binary files /dev/null and b/sounds/sid/sid3/Tcats.dmp differ diff --git a/sounds/sid/sid3/Terrys.dmp b/sounds/sid/sid3/Terrys.dmp new file mode 100644 index 0000000..9a512b6 Binary files /dev/null and b/sounds/sid/sid3/Terrys.dmp differ diff --git a/sounds/sid/sid3/Thing.dmp b/sounds/sid/sid3/Thing.dmp new file mode 100644 index 0000000..e055494 Binary files /dev/null and b/sounds/sid/sid3/Thing.dmp differ diff --git a/sounds/sid/sid3/Thrust.dmp b/sounds/sid/sid3/Thrust.dmp new file mode 100644 index 0000000..f2e1c1a Binary files /dev/null and b/sounds/sid/sid3/Thrust.dmp differ diff --git a/sounds/sid/sid3/Turrican.dmp b/sounds/sid/sid3/Turrican.dmp new file mode 100644 index 0000000..3cf8fbe Binary files /dev/null and b/sounds/sid/sid3/Turrican.dmp differ diff --git a/sounds/sid/sid3/Turrican2.dmp b/sounds/sid/sid3/Turrican2.dmp new file mode 100644 index 0000000..7dfee19 Binary files /dev/null and b/sounds/sid/sid3/Turrican2.dmp differ diff --git a/sounds/sid/sid3/X-Out.dmp b/sounds/sid/sid3/X-Out.dmp new file mode 100644 index 0000000..ef23d6d Binary files /dev/null and b/sounds/sid/sid3/X-Out.dmp differ diff --git a/sounds/sid/sid3/hoverh.dmp b/sounds/sid/sid3/hoverh.dmp new file mode 100644 index 0000000..f713ef4 Binary files /dev/null and b/sounds/sid/sid3/hoverh.dmp differ diff --git a/sounds/sid/sid3/lastV8.dmp b/sounds/sid/sid3/lastV8.dmp new file mode 100644 index 0000000..2773269 Binary files /dev/null and b/sounds/sid/sid3/lastV8.dmp differ diff --git a/sounds/sid/sid3/ninja.dmp b/sounds/sid/sid3/ninja.dmp new file mode 100644 index 0000000..a1434b0 Binary files /dev/null and b/sounds/sid/sid3/ninja.dmp differ diff --git a/sounds/sid/sid4/1942.dmp b/sounds/sid/sid4/1942.dmp new file mode 100644 index 0000000..dca6170 Binary files /dev/null and b/sounds/sid/sid4/1942.dmp differ diff --git a/sounds/sid/sid4/1_45_Tune.dmp b/sounds/sid/sid4/1_45_Tune.dmp new file mode 100644 index 0000000..297f868 Binary files /dev/null and b/sounds/sid/sid4/1_45_Tune.dmp differ diff --git a/sounds/sid/sid4/2112.dmp b/sounds/sid/sid4/2112.dmp new file mode 100644 index 0000000..ea086f5 Binary files /dev/null and b/sounds/sid/sid4/2112.dmp differ diff --git a/sounds/sid/sid4/3D_Skramble.dmp b/sounds/sid/sid4/3D_Skramble.dmp new file mode 100644 index 0000000..6223180 Binary files /dev/null and b/sounds/sid/sid4/3D_Skramble.dmp differ diff --git a/sounds/sid/sid4/4x4_Off-Road_Racing.dmp b/sounds/sid/sid4/4x4_Off-Road_Racing.dmp new file mode 100644 index 0000000..dab7099 Binary files /dev/null and b/sounds/sid/sid4/4x4_Off-Road_Racing.dmp differ diff --git a/sounds/sid/sid4/5_mal_5.dmp b/sounds/sid/sid4/5_mal_5.dmp new file mode 100644 index 0000000..5b11204 Binary files /dev/null and b/sounds/sid/sid4/5_mal_5.dmp differ diff --git a/sounds/sid/sid4/AWMonty.dmp b/sounds/sid/sid4/AWMonty.dmp new file mode 100644 index 0000000..ef470d0 Binary files /dev/null and b/sounds/sid/sid4/AWMonty.dmp differ diff --git a/sounds/sid/sid4/A_P_E_X_preview.dmp b/sounds/sid/sid4/A_P_E_X_preview.dmp new file mode 100644 index 0000000..e72b8a8 Binary files /dev/null and b/sounds/sid/sid4/A_P_E_X_preview.dmp differ diff --git a/sounds/sid/sid4/Abyss.dmp b/sounds/sid/sid4/Abyss.dmp new file mode 100644 index 0000000..3308e58 Binary files /dev/null and b/sounds/sid/sid4/Abyss.dmp differ diff --git a/sounds/sid/sid4/Advanced_Tactical_Fighter.dmp b/sounds/sid/sid4/Advanced_Tactical_Fighter.dmp new file mode 100644 index 0000000..81c38d6 Binary files /dev/null and b/sounds/sid/sid4/Advanced_Tactical_Fighter.dmp differ diff --git a/sounds/sid/sid4/Aerobics.dmp b/sounds/sid/sid4/Aerobics.dmp new file mode 100644 index 0000000..45b0c95 Binary files /dev/null and b/sounds/sid/sid4/Aerobics.dmp differ diff --git a/sounds/sid/sid4/Agent_Orange.dmp b/sounds/sid/sid4/Agent_Orange.dmp new file mode 100644 index 0000000..e71f6c7 Binary files /dev/null and b/sounds/sid/sid4/Agent_Orange.dmp differ diff --git a/sounds/sid/sid4/Agent_UOP.dmp b/sounds/sid/sid4/Agent_UOP.dmp new file mode 100644 index 0000000..7a9ac1e Binary files /dev/null and b/sounds/sid/sid4/Agent_UOP.dmp differ diff --git a/sounds/sid/sid4/Air_Dance_4_part_4_remixed.dmp b/sounds/sid/sid4/Air_Dance_4_part_4_remixed.dmp new file mode 100644 index 0000000..bd3193f Binary files /dev/null and b/sounds/sid/sid4/Air_Dance_4_part_4_remixed.dmp differ diff --git a/sounds/sid/sid4/Airline.dmp b/sounds/sid/sid4/Airline.dmp new file mode 100644 index 0000000..c4cd844 Binary files /dev/null and b/sounds/sid/sid4/Airline.dmp differ diff --git a/sounds/sid/sid4/Airwolf_Fixer_v1_0_note.dmp b/sounds/sid/sid4/Airwolf_Fixer_v1_0_note.dmp new file mode 100644 index 0000000..9cb933f Binary files /dev/null and b/sounds/sid/sid4/Airwolf_Fixer_v1_0_note.dmp differ diff --git a/sounds/sid/sid4/Airwolf_Remix.dmp b/sounds/sid/sid4/Airwolf_Remix.dmp new file mode 100644 index 0000000..514df21 Binary files /dev/null and b/sounds/sid/sid4/Airwolf_Remix.dmp differ diff --git a/sounds/sid/sid4/Alphaflight_Intro.dmp b/sounds/sid/sid4/Alphaflight_Intro.dmp new file mode 100644 index 0000000..d8d4d41 Binary files /dev/null and b/sounds/sid/sid4/Alphaflight_Intro.dmp differ diff --git a/sounds/sid/sid4/Amazon_Warrior_03.dmp b/sounds/sid/sid4/Amazon_Warrior_03.dmp new file mode 100644 index 0000000..5f31fd6 Binary files /dev/null and b/sounds/sid/sid4/Amazon_Warrior_03.dmp differ diff --git a/sounds/sid/sid4/Android_2.dmp b/sounds/sid/sid4/Android_2.dmp new file mode 100644 index 0000000..7766ecb Binary files /dev/null and b/sounds/sid/sid4/Android_2.dmp differ diff --git a/sounds/sid/sid4/Antics.dmp b/sounds/sid/sid4/Antics.dmp new file mode 100644 index 0000000..b7f880f Binary files /dev/null and b/sounds/sid/sid4/Antics.dmp differ diff --git a/sounds/sid/sid4/Araknifoe.dmp b/sounds/sid/sid4/Araknifoe.dmp new file mode 100644 index 0000000..bc156a4 Binary files /dev/null and b/sounds/sid/sid4/Araknifoe.dmp differ diff --git a/sounds/sid/sid4/Arcana.dmp b/sounds/sid/sid4/Arcana.dmp new file mode 100644 index 0000000..4c34add Binary files /dev/null and b/sounds/sid/sid4/Arcana.dmp differ diff --git a/sounds/sid/sid4/Arkanoid_PSID.dmp b/sounds/sid/sid4/Arkanoid_PSID.dmp new file mode 100644 index 0000000..ca82f86 Binary files /dev/null and b/sounds/sid/sid4/Arkanoid_PSID.dmp differ diff --git a/sounds/sid/sid4/Atlantis.dmp b/sounds/sid/sid4/Atlantis.dmp new file mode 100644 index 0000000..e3978f6 Binary files /dev/null and b/sounds/sid/sid4/Atlantis.dmp differ diff --git a/sounds/sid/sid4/Atlantis_end_tune.dmp b/sounds/sid/sid4/Atlantis_end_tune.dmp new file mode 100644 index 0000000..7154ad6 Binary files /dev/null and b/sounds/sid/sid4/Atlantis_end_tune.dmp differ diff --git a/sounds/sid/sid4/Atomino_02.dmp b/sounds/sid/sid4/Atomino_02.dmp new file mode 100644 index 0000000..f340b44 Binary files /dev/null and b/sounds/sid/sid4/Atomino_02.dmp differ diff --git a/sounds/sid/sid4/Auf_Wiedersehen_Monty.dmp b/sounds/sid/sid4/Auf_Wiedersehen_Monty.dmp new file mode 100644 index 0000000..ef470d0 Binary files /dev/null and b/sounds/sid/sid4/Auf_Wiedersehen_Monty.dmp differ diff --git a/sounds/sid/sid4/Autumn_Symphony.dmp b/sounds/sid/sid4/Autumn_Symphony.dmp new file mode 100644 index 0000000..1439267 Binary files /dev/null and b/sounds/sid/sid4/Autumn_Symphony.dmp differ diff --git a/sounds/sid/sid4/Aviewtoakill.dmp b/sounds/sid/sid4/Aviewtoakill.dmp new file mode 100644 index 0000000..d714ef3 Binary files /dev/null and b/sounds/sid/sid4/Aviewtoakill.dmp differ diff --git a/sounds/sid/sid4/AxelfF.dmp b/sounds/sid/sid4/AxelfF.dmp new file mode 100644 index 0000000..2c4b1ce Binary files /dev/null and b/sounds/sid/sid4/AxelfF.dmp differ diff --git a/sounds/sid/sid4/Aztec_Challenge.dmp b/sounds/sid/sid4/Aztec_Challenge.dmp new file mode 100644 index 0000000..0e496fa Binary files /dev/null and b/sounds/sid/sid4/Aztec_Challenge.dmp differ diff --git a/sounds/sid/sid4/Bards_Tale_III_04.dmp b/sounds/sid/sid4/Bards_Tale_III_04.dmp new file mode 100644 index 0000000..145967c Binary files /dev/null and b/sounds/sid/sid4/Bards_Tale_III_04.dmp differ diff --git a/sounds/sid/sid4/Barom11.dmp b/sounds/sid/sid4/Barom11.dmp new file mode 100644 index 0000000..65404c9 Binary files /dev/null and b/sounds/sid/sid4/Barom11.dmp differ diff --git a/sounds/sid/sid4/Batman_The_Movie.dmp b/sounds/sid/sid4/Batman_The_Movie.dmp new file mode 100644 index 0000000..6502bf4 Binary files /dev/null and b/sounds/sid/sid4/Batman_The_Movie.dmp differ diff --git a/sounds/sid/sid4/Batman_The_Movie2.dmp b/sounds/sid/sid4/Batman_The_Movie2.dmp new file mode 100644 index 0000000..4cf20e9 Binary files /dev/null and b/sounds/sid/sid4/Batman_The_Movie2.dmp differ diff --git a/sounds/sid/sid4/Batman_The_Movie3.dmp b/sounds/sid/sid4/Batman_The_Movie3.dmp new file mode 100644 index 0000000..227242c Binary files /dev/null and b/sounds/sid/sid4/Batman_The_Movie3.dmp differ diff --git a/sounds/sid/sid4/Batman_The_Movie4.dmp b/sounds/sid/sid4/Batman_The_Movie4.dmp new file mode 100644 index 0000000..2f3edcf Binary files /dev/null and b/sounds/sid/sid4/Batman_The_Movie4.dmp differ diff --git a/sounds/sid/sid4/Batman_The_Movie5.dmp b/sounds/sid/sid4/Batman_The_Movie5.dmp new file mode 100644 index 0000000..86770cc Binary files /dev/null and b/sounds/sid/sid4/Batman_The_Movie5.dmp differ diff --git a/sounds/sid/sid4/Batman_The_Movie6.dmp b/sounds/sid/sid4/Batman_The_Movie6.dmp new file mode 100644 index 0000000..b53f332 Binary files /dev/null and b/sounds/sid/sid4/Batman_The_Movie6.dmp differ diff --git a/sounds/sid/sid4/Bear_George.dmp b/sounds/sid/sid4/Bear_George.dmp new file mode 100644 index 0000000..99da982 Binary files /dev/null and b/sounds/sid/sid4/Bear_George.dmp differ diff --git a/sounds/sid/sid4/Bert_The_Bug_Bites_Back.dmp b/sounds/sid/sid4/Bert_The_Bug_Bites_Back.dmp new file mode 100644 index 0000000..69f25b5 Binary files /dev/null and b/sounds/sid/sid4/Bert_The_Bug_Bites_Back.dmp differ diff --git a/sounds/sid/sid4/Bionic_Commando.dmp b/sounds/sid/sid4/Bionic_Commando.dmp new file mode 100644 index 0000000..7a182aa Binary files /dev/null and b/sounds/sid/sid4/Bionic_Commando.dmp differ diff --git a/sounds/sid/sid4/Bionic_Commando2.dmp b/sounds/sid/sid4/Bionic_Commando2.dmp new file mode 100644 index 0000000..5fb3254 Binary files /dev/null and b/sounds/sid/sid4/Bionic_Commando2.dmp differ diff --git a/sounds/sid/sid4/Bionic_Commando3.dmp b/sounds/sid/sid4/Bionic_Commando3.dmp new file mode 100644 index 0000000..c6b6467 Binary files /dev/null and b/sounds/sid/sid4/Bionic_Commando3.dmp differ diff --git a/sounds/sid/sid4/Blitter.dmp b/sounds/sid/sid4/Blitter.dmp new file mode 100644 index 0000000..9826652 Binary files /dev/null and b/sounds/sid/sid4/Blitter.dmp differ diff --git a/sounds/sid/sid4/Block_n_Bubble.dmp b/sounds/sid/sid4/Block_n_Bubble.dmp new file mode 100644 index 0000000..5ab5ea8 Binary files /dev/null and b/sounds/sid/sid4/Block_n_Bubble.dmp differ diff --git a/sounds/sid/sid4/Blue_Max_2001.dmp b/sounds/sid/sid4/Blue_Max_2001.dmp new file mode 100644 index 0000000..15f828d Binary files /dev/null and b/sounds/sid/sid4/Blue_Max_2001.dmp differ diff --git a/sounds/sid/sid4/Bob_Moran_Science_Fiction.dmp b/sounds/sid/sid4/Bob_Moran_Science_Fiction.dmp new file mode 100644 index 0000000..586c5c8 Binary files /dev/null and b/sounds/sid/sid4/Bob_Moran_Science_Fiction.dmp differ diff --git a/sounds/sid/sid4/Bobsleigh.dmp b/sounds/sid/sid4/Bobsleigh.dmp new file mode 100644 index 0000000..e9dadc8 Binary files /dev/null and b/sounds/sid/sid4/Bobsleigh.dmp differ diff --git a/sounds/sid/sid4/Bomb_Mania.dmp b/sounds/sid/sid4/Bomb_Mania.dmp new file mode 100644 index 0000000..209845d Binary files /dev/null and b/sounds/sid/sid4/Bomb_Mania.dmp differ diff --git a/sounds/sid/sid4/Boulder_Dash.dmp b/sounds/sid/sid4/Boulder_Dash.dmp new file mode 100644 index 0000000..6152603 Binary files /dev/null and b/sounds/sid/sid4/Boulder_Dash.dmp differ diff --git a/sounds/sid/sid4/Boulder_Dash_II.dmp b/sounds/sid/sid4/Boulder_Dash_II.dmp new file mode 100644 index 0000000..647cead Binary files /dev/null and b/sounds/sid/sid4/Boulder_Dash_II.dmp differ diff --git a/sounds/sid/sid4/Boz_Hubbard.dmp b/sounds/sid/sid4/Boz_Hubbard.dmp new file mode 100644 index 0000000..1a3d5eb Binary files /dev/null and b/sounds/sid/sid4/Boz_Hubbard.dmp differ diff --git a/sounds/sid/sid4/Bristles.dmp b/sounds/sid/sid4/Bristles.dmp new file mode 100644 index 0000000..28c59d7 Binary files /dev/null and b/sounds/sid/sid4/Bristles.dmp differ diff --git a/sounds/sid/sid4/Bruce_Lee.dmp b/sounds/sid/sid4/Bruce_Lee.dmp new file mode 100644 index 0000000..e33b1e4 Binary files /dev/null and b/sounds/sid/sid4/Bruce_Lee.dmp differ diff --git a/sounds/sid/sid4/Bruth-Lan-Dan.dmp b/sounds/sid/sid4/Bruth-Lan-Dan.dmp new file mode 100644 index 0000000..46a034f Binary files /dev/null and b/sounds/sid/sid4/Bruth-Lan-Dan.dmp differ diff --git a/sounds/sid/sid4/Bubble_Bobble.dmp b/sounds/sid/sid4/Bubble_Bobble.dmp new file mode 100644 index 0000000..059c127 Binary files /dev/null and b/sounds/sid/sid4/Bubble_Bobble.dmp differ diff --git a/sounds/sid/sid4/Bullseye.dmp b/sounds/sid/sid4/Bullseye.dmp new file mode 100644 index 0000000..3cc5524 Binary files /dev/null and b/sounds/sid/sid4/Bullseye.dmp differ diff --git a/sounds/sid/sid4/Burp_Intro.dmp b/sounds/sid/sid4/Burp_Intro.dmp new file mode 100644 index 0000000..6f55f5e Binary files /dev/null and b/sounds/sid/sid4/Burp_Intro.dmp differ diff --git a/sounds/sid/sid4/California_Games.dmp b/sounds/sid/sid4/California_Games.dmp new file mode 100644 index 0000000..3c599f0 Binary files /dev/null and b/sounds/sid/sid4/California_Games.dmp differ diff --git a/sounds/sid/sid4/Camelot_Warriors.dmp b/sounds/sid/sid4/Camelot_Warriors.dmp new file mode 100644 index 0000000..c2cbe9f Binary files /dev/null and b/sounds/sid/sid4/Camelot_Warriors.dmp differ diff --git a/sounds/sid/sid4/Candleglow.dmp b/sounds/sid/sid4/Candleglow.dmp new file mode 100644 index 0000000..e423019 Binary files /dev/null and b/sounds/sid/sid4/Candleglow.dmp differ diff --git a/sounds/sid/sid4/Carnivorous_part_1.dmp b/sounds/sid/sid4/Carnivorous_part_1.dmp new file mode 100644 index 0000000..d077ee8 Binary files /dev/null and b/sounds/sid/sid4/Carnivorous_part_1.dmp differ diff --git a/sounds/sid/sid4/Castle.dmp b/sounds/sid/sid4/Castle.dmp new file mode 100644 index 0000000..42c2ef7 Binary files /dev/null and b/sounds/sid/sid4/Castle.dmp differ diff --git a/sounds/sid/sid4/Castle_of_Madness.dmp b/sounds/sid/sid4/Castle_of_Madness.dmp new file mode 100644 index 0000000..b7b2884 Binary files /dev/null and b/sounds/sid/sid4/Castle_of_Madness.dmp differ diff --git a/sounds/sid/sid4/Castle_of_Terror.dmp b/sounds/sid/sid4/Castle_of_Terror.dmp new file mode 100644 index 0000000..555c603 Binary files /dev/null and b/sounds/sid/sid4/Castle_of_Terror.dmp differ diff --git a/sounds/sid/sid4/Castles_of_Dr_Creep.dmp b/sounds/sid/sid4/Castles_of_Dr_Creep.dmp new file mode 100644 index 0000000..1545528 Binary files /dev/null and b/sounds/sid/sid4/Castles_of_Dr_Creep.dmp differ diff --git a/sounds/sid/sid4/Castlevania_64_Mixes.dmp b/sounds/sid/sid4/Castlevania_64_Mixes.dmp new file mode 100644 index 0000000..e5cff35 Binary files /dev/null and b/sounds/sid/sid4/Castlevania_64_Mixes.dmp differ diff --git a/sounds/sid/sid4/Catalypse_PSID.dmp b/sounds/sid/sid4/Catalypse_PSID.dmp new file mode 100644 index 0000000..0408d0d Binary files /dev/null and b/sounds/sid/sid4/Catalypse_PSID.dmp differ diff --git a/sounds/sid/sid4/Cauldron.dmp b/sounds/sid/sid4/Cauldron.dmp new file mode 100644 index 0000000..fedd5b7 Binary files /dev/null and b/sounds/sid/sid4/Cauldron.dmp differ diff --git a/sounds/sid/sid4/Cauldron_II.dmp b/sounds/sid/sid4/Cauldron_II.dmp new file mode 100644 index 0000000..60d9a88 Binary files /dev/null and b/sounds/sid/sid4/Cauldron_II.dmp differ diff --git a/sounds/sid/sid4/Cavelon_10.dmp b/sounds/sid/sid4/Cavelon_10.dmp new file mode 100644 index 0000000..44a9942 Binary files /dev/null and b/sounds/sid/sid4/Cavelon_10.dmp differ diff --git a/sounds/sid/sid4/Champions_of_Krynn.dmp b/sounds/sid/sid4/Champions_of_Krynn.dmp new file mode 100644 index 0000000..21c83cb Binary files /dev/null and b/sounds/sid/sid4/Champions_of_Krynn.dmp differ diff --git a/sounds/sid/sid4/Chariots_of_Fire.dmp b/sounds/sid/sid4/Chariots_of_Fire.dmp new file mode 100644 index 0000000..fe6fc31 Binary files /dev/null and b/sounds/sid/sid4/Chariots_of_Fire.dmp differ diff --git a/sounds/sid/sid4/Chevytech.dmp b/sounds/sid/sid4/Chevytech.dmp new file mode 100644 index 0000000..48e1e46 Binary files /dev/null and b/sounds/sid/sid4/Chevytech.dmp differ diff --git a/sounds/sid/sid4/Children_of_the_Sea.dmp b/sounds/sid/sid4/Children_of_the_Sea.dmp new file mode 100644 index 0000000..114a50a Binary files /dev/null and b/sounds/sid/sid4/Children_of_the_Sea.dmp differ diff --git a/sounds/sid/sid4/Chimera.dmp b/sounds/sid/sid4/Chimera.dmp new file mode 100644 index 0000000..26fc6e4 Binary files /dev/null and b/sounds/sid/sid4/Chimera.dmp differ diff --git a/sounds/sid/sid4/China_Syndrome.dmp b/sounds/sid/sid4/China_Syndrome.dmp new file mode 100644 index 0000000..60fafc6 Binary files /dev/null and b/sounds/sid/sid4/China_Syndrome.dmp differ diff --git a/sounds/sid/sid4/Chris_01.dmp b/sounds/sid/sid4/Chris_01.dmp new file mode 100644 index 0000000..b080de9 Binary files /dev/null and b/sounds/sid/sid4/Chris_01.dmp differ diff --git a/sounds/sid/sid4/Chris_02.dmp b/sounds/sid/sid4/Chris_02.dmp new file mode 100644 index 0000000..5c4c43f Binary files /dev/null and b/sounds/sid/sid4/Chris_02.dmp differ diff --git a/sounds/sid/sid4/Ciabah_1_magazine.dmp b/sounds/sid/sid4/Ciabah_1_magazine.dmp new file mode 100644 index 0000000..0096605 Binary files /dev/null and b/sounds/sid/sid4/Ciabah_1_magazine.dmp differ diff --git a/sounds/sid/sid4/Cloud_Kingdoms.dmp b/sounds/sid/sid4/Cloud_Kingdoms.dmp new file mode 100644 index 0000000..325f7bc Binary files /dev/null and b/sounds/sid/sid4/Cloud_Kingdoms.dmp differ diff --git a/sounds/sid/sid4/Cobra.dmp b/sounds/sid/sid4/Cobra.dmp new file mode 100644 index 0000000..3a64fb9 Binary files /dev/null and b/sounds/sid/sid4/Cobra.dmp differ diff --git a/sounds/sid/sid4/Cockcrusher_Pride_Denmark.dmp b/sounds/sid/sid4/Cockcrusher_Pride_Denmark.dmp new file mode 100644 index 0000000..42ad1e3 Binary files /dev/null and b/sounds/sid/sid4/Cockcrusher_Pride_Denmark.dmp differ diff --git a/sounds/sid/sid4/Comet.dmp b/sounds/sid/sid4/Comet.dmp new file mode 100644 index 0000000..8d30ac2 Binary files /dev/null and b/sounds/sid/sid4/Comet.dmp differ diff --git a/sounds/sid/sid4/Comic_Bakery.dmp b/sounds/sid/sid4/Comic_Bakery.dmp new file mode 100644 index 0000000..860b118 Binary files /dev/null and b/sounds/sid/sid4/Comic_Bakery.dmp differ diff --git a/sounds/sid/sid4/Commando.dmp b/sounds/sid/sid4/Commando.dmp new file mode 100644 index 0000000..41cf15e Binary files /dev/null and b/sounds/sid/sid4/Commando.dmp differ diff --git a/sounds/sid/sid4/Compo_Tune.dmp b/sounds/sid/sid4/Compo_Tune.dmp new file mode 100644 index 0000000..dbbb5c8 Binary files /dev/null and b/sounds/sid/sid4/Compo_Tune.dmp differ diff --git a/sounds/sid/sid4/Connect_4.dmp b/sounds/sid/sid4/Connect_4.dmp new file mode 100644 index 0000000..fba8b0b Binary files /dev/null and b/sounds/sid/sid4/Connect_4.dmp differ diff --git a/sounds/sid/sid4/Cool_World.dmp b/sounds/sid/sid4/Cool_World.dmp new file mode 100644 index 0000000..5194abb Binary files /dev/null and b/sounds/sid/sid4/Cool_World.dmp differ diff --git a/sounds/sid/sid4/Crack_Down_02.dmp b/sounds/sid/sid4/Crack_Down_02.dmp new file mode 100644 index 0000000..1bcd5cd Binary files /dev/null and b/sounds/sid/sid4/Crack_Down_02.dmp differ diff --git a/sounds/sid/sid4/CrazyComet.dmp b/sounds/sid/sid4/CrazyComet.dmp new file mode 100644 index 0000000..abc6c6e Binary files /dev/null and b/sounds/sid/sid4/CrazyComet.dmp differ diff --git a/sounds/sid/sid4/Crazy_Cars.dmp b/sounds/sid/sid4/Crazy_Cars.dmp new file mode 100644 index 0000000..907299c Binary files /dev/null and b/sounds/sid/sid4/Crazy_Cars.dmp differ diff --git a/sounds/sid/sid4/Crazy_Comets.dmp b/sounds/sid/sid4/Crazy_Comets.dmp new file mode 100644 index 0000000..df60238 Binary files /dev/null and b/sounds/sid/sid4/Crazy_Comets.dmp differ diff --git a/sounds/sid/sid4/Crossfire.dmp b/sounds/sid/sid4/Crossfire.dmp new file mode 100644 index 0000000..8fd3a8d Binary files /dev/null and b/sounds/sid/sid4/Crossfire.dmp differ diff --git a/sounds/sid/sid4/Cubulus.dmp b/sounds/sid/sid4/Cubulus.dmp new file mode 100644 index 0000000..9fef9d7 Binary files /dev/null and b/sounds/sid/sid4/Cubulus.dmp differ diff --git a/sounds/sid/sid4/Cybernoid.dmp b/sounds/sid/sid4/Cybernoid.dmp new file mode 100644 index 0000000..e590c67 Binary files /dev/null and b/sounds/sid/sid4/Cybernoid.dmp differ diff --git a/sounds/sid/sid4/Cybernoid_II.dmp b/sounds/sid/sid4/Cybernoid_II.dmp new file mode 100644 index 0000000..66fb778 Binary files /dev/null and b/sounds/sid/sid4/Cybernoid_II.dmp differ diff --git a/sounds/sid/sid4/D_I_S_C_The_Game.dmp b/sounds/sid/sid4/D_I_S_C_The_Game.dmp new file mode 100644 index 0000000..4092969 Binary files /dev/null and b/sounds/sid/sid4/D_I_S_C_The_Game.dmp differ diff --git a/sounds/sid/sid4/Daley_Thompsons_Decathlon.dmp b/sounds/sid/sid4/Daley_Thompsons_Decathlon.dmp new file mode 100644 index 0000000..5083f75 Binary files /dev/null and b/sounds/sid/sid4/Daley_Thompsons_Decathlon.dmp differ diff --git a/sounds/sid/sid4/Deblin_01.dmp b/sounds/sid/sid4/Deblin_01.dmp new file mode 100644 index 0000000..0541498 Binary files /dev/null and b/sounds/sid/sid4/Deblin_01.dmp differ diff --git a/sounds/sid/sid4/Delta.dmp b/sounds/sid/sid4/Delta.dmp new file mode 100644 index 0000000..5e05911 Binary files /dev/null and b/sounds/sid/sid4/Delta.dmp differ diff --git a/sounds/sid/sid4/Demoscop_2_part_3.dmp b/sounds/sid/sid4/Demoscop_2_part_3.dmp new file mode 100644 index 0000000..d37f73d Binary files /dev/null and b/sounds/sid/sid4/Demoscop_2_part_3.dmp differ diff --git a/sounds/sid/sid4/Dickys_Diamonds.dmp b/sounds/sid/sid4/Dickys_Diamonds.dmp new file mode 100644 index 0000000..3ba90f5 Binary files /dev/null and b/sounds/sid/sid4/Dickys_Diamonds.dmp differ diff --git a/sounds/sid/sid4/Dinky_Doo.dmp b/sounds/sid/sid4/Dinky_Doo.dmp new file mode 100644 index 0000000..6314982 Binary files /dev/null and b/sounds/sid/sid4/Dinky_Doo.dmp differ diff --git a/sounds/sid/sid4/Domino.dmp b/sounds/sid/sid4/Domino.dmp new file mode 100644 index 0000000..fd52fd7 Binary files /dev/null and b/sounds/sid/sid4/Domino.dmp differ diff --git a/sounds/sid/sid4/Dont_Worry_be_Happy.dmp b/sounds/sid/sid4/Dont_Worry_be_Happy.dmp new file mode 100644 index 0000000..90c2666 Binary files /dev/null and b/sounds/sid/sid4/Dont_Worry_be_Happy.dmp differ diff --git a/sounds/sid/sid4/Dont_You_Want_Me.dmp b/sounds/sid/sid4/Dont_You_Want_Me.dmp new file mode 100644 index 0000000..2c49653 Binary files /dev/null and b/sounds/sid/sid4/Dont_You_Want_Me.dmp differ diff --git a/sounds/sid/sid4/Dracula.dmp b/sounds/sid/sid4/Dracula.dmp new file mode 100644 index 0000000..78bd8fb Binary files /dev/null and b/sounds/sid/sid4/Dracula.dmp differ diff --git a/sounds/sid/sid4/Dragons_Legend.dmp b/sounds/sid/sid4/Dragons_Legend.dmp new file mode 100644 index 0000000..50fd070 Binary files /dev/null and b/sounds/sid/sid4/Dragons_Legend.dmp differ diff --git a/sounds/sid/sid4/Drelbs.dmp b/sounds/sid/sid4/Drelbs.dmp new file mode 100644 index 0000000..b3f3f39 Binary files /dev/null and b/sounds/sid/sid4/Drelbs.dmp differ diff --git a/sounds/sid/sid4/Drop_The_Girl.dmp b/sounds/sid/sid4/Drop_The_Girl.dmp new file mode 100644 index 0000000..bc2d8b6 Binary files /dev/null and b/sounds/sid/sid4/Drop_The_Girl.dmp differ diff --git a/sounds/sid/sid4/Dynamite_Duex.dmp b/sounds/sid/sid4/Dynamite_Duex.dmp new file mode 100644 index 0000000..79cd545 Binary files /dev/null and b/sounds/sid/sid4/Dynamite_Duex.dmp differ diff --git a/sounds/sid/sid4/Ein_Fall_fuer_2_remix.dmp b/sounds/sid/sid4/Ein_Fall_fuer_2_remix.dmp new file mode 100644 index 0000000..e5f009c Binary files /dev/null and b/sounds/sid/sid4/Ein_Fall_fuer_2_remix.dmp differ diff --git a/sounds/sid/sid4/Electrosound.dmp b/sounds/sid/sid4/Electrosound.dmp new file mode 100644 index 0000000..354be73 Binary files /dev/null and b/sounds/sid/sid4/Electrosound.dmp differ diff --git a/sounds/sid/sid4/Eleminator.dmp b/sounds/sid/sid4/Eleminator.dmp new file mode 100644 index 0000000..02ed2b3 Binary files /dev/null and b/sounds/sid/sid4/Eleminator.dmp differ diff --git a/sounds/sid/sid4/Emax_01.dmp b/sounds/sid/sid4/Emax_01.dmp new file mode 100644 index 0000000..c4f9a49 Binary files /dev/null and b/sounds/sid/sid4/Emax_01.dmp differ diff --git a/sounds/sid/sid4/Enforcer.dmp b/sounds/sid/sid4/Enforcer.dmp new file mode 100644 index 0000000..47cd480 Binary files /dev/null and b/sounds/sid/sid4/Enforcer.dmp differ diff --git a/sounds/sid/sid4/EnloaGay.dmp b/sounds/sid/sid4/EnloaGay.dmp new file mode 100644 index 0000000..550207e Binary files /dev/null and b/sounds/sid/sid4/EnloaGay.dmp differ diff --git a/sounds/sid/sid4/Entertainer.dmp b/sounds/sid/sid4/Entertainer.dmp new file mode 100644 index 0000000..d2b69da Binary files /dev/null and b/sounds/sid/sid4/Entertainer.dmp differ diff --git a/sounds/sid/sid4/Entertainer_theme.dmp b/sounds/sid/sid4/Entertainer_theme.dmp new file mode 100644 index 0000000..59645be Binary files /dev/null and b/sounds/sid/sid4/Entertainer_theme.dmp differ diff --git a/sounds/sid/sid4/Espionage.dmp b/sounds/sid/sid4/Espionage.dmp new file mode 100644 index 0000000..ed4059e Binary files /dev/null and b/sounds/sid/sid4/Espionage.dmp differ diff --git a/sounds/sid/sid4/Euroopan_Kartta_64.dmp b/sounds/sid/sid4/Euroopan_Kartta_64.dmp new file mode 100644 index 0000000..a2da15c Binary files /dev/null and b/sounds/sid/sid4/Euroopan_Kartta_64.dmp differ diff --git a/sounds/sid/sid4/Eye.dmp b/sounds/sid/sid4/Eye.dmp new file mode 100644 index 0000000..9c70c71 Binary files /dev/null and b/sounds/sid/sid4/Eye.dmp differ diff --git a/sounds/sid/sid4/Faery_Tale.dmp b/sounds/sid/sid4/Faery_Tale.dmp new file mode 100644 index 0000000..691a4c2 Binary files /dev/null and b/sounds/sid/sid4/Faery_Tale.dmp differ diff --git a/sounds/sid/sid4/Fighter_Bomber_intro.dmp b/sounds/sid/sid4/Fighter_Bomber_intro.dmp new file mode 100644 index 0000000..78419d5 Binary files /dev/null and b/sounds/sid/sid4/Fighter_Bomber_intro.dmp differ diff --git a/sounds/sid/sid4/Fighting_Warrior.dmp b/sounds/sid/sid4/Fighting_Warrior.dmp new file mode 100644 index 0000000..776d83c Binary files /dev/null and b/sounds/sid/sid4/Fighting_Warrior.dmp differ diff --git a/sounds/sid/sid4/Final_Countdown.dmp b/sounds/sid/sid4/Final_Countdown.dmp new file mode 100644 index 0000000..9ce7057 Binary files /dev/null and b/sounds/sid/sid4/Final_Countdown.dmp differ diff --git a/sounds/sid/sid4/Firefly.dmp b/sounds/sid/sid4/Firefly.dmp new file mode 100644 index 0000000..dca322f Binary files /dev/null and b/sounds/sid/sid4/Firefly.dmp differ diff --git a/sounds/sid/sid4/Flashback.dmp b/sounds/sid/sid4/Flashback.dmp new file mode 100644 index 0000000..17eb10c Binary files /dev/null and b/sounds/sid/sid4/Flashback.dmp differ diff --git a/sounds/sid/sid4/Flimbos_Quest.dmp b/sounds/sid/sid4/Flimbos_Quest.dmp new file mode 100644 index 0000000..2a901f4 Binary files /dev/null and b/sounds/sid/sid4/Flimbos_Quest.dmp differ diff --git a/sounds/sid/sid4/Fly_Around_the_World.dmp b/sounds/sid/sid4/Fly_Around_the_World.dmp new file mode 100644 index 0000000..c20e2c2 Binary files /dev/null and b/sounds/sid/sid4/Fly_Around_the_World.dmp differ diff --git a/sounds/sid/sid4/Forbidden_Forest.dmp b/sounds/sid/sid4/Forbidden_Forest.dmp new file mode 100644 index 0000000..0dc5f53 Binary files /dev/null and b/sounds/sid/sid4/Forbidden_Forest.dmp differ diff --git a/sounds/sid/sid4/Foundations.dmp b/sounds/sid/sid4/Foundations.dmp new file mode 100644 index 0000000..90b75fb Binary files /dev/null and b/sounds/sid/sid4/Foundations.dmp differ diff --git a/sounds/sid/sid4/Freak_Factory.dmp b/sounds/sid/sid4/Freak_Factory.dmp new file mode 100644 index 0000000..a9a7d88 Binary files /dev/null and b/sounds/sid/sid4/Freak_Factory.dmp differ diff --git a/sounds/sid/sid4/Funkytown.dmp b/sounds/sid/sid4/Funkytown.dmp new file mode 100644 index 0000000..94eb2fb Binary files /dev/null and b/sounds/sid/sid4/Funkytown.dmp differ diff --git a/sounds/sid/sid4/Gauntlet_III.dmp b/sounds/sid/sid4/Gauntlet_III.dmp new file mode 100644 index 0000000..2843d95 Binary files /dev/null and b/sounds/sid/sid4/Gauntlet_III.dmp differ diff --git a/sounds/sid/sid4/Geir_Tjelta-11.dmp b/sounds/sid/sid4/Geir_Tjelta-11.dmp new file mode 100644 index 0000000..94185fe Binary files /dev/null and b/sounds/sid/sid4/Geir_Tjelta-11.dmp differ diff --git a/sounds/sid/sid4/Genias-Logo.dmp b/sounds/sid/sid4/Genias-Logo.dmp new file mode 100644 index 0000000..80a0f75 Binary files /dev/null and b/sounds/sid/sid4/Genias-Logo.dmp differ diff --git a/sounds/sid/sid4/Ghostbusters.dmp b/sounds/sid/sid4/Ghostbusters.dmp new file mode 100644 index 0000000..f17bcbd Binary files /dev/null and b/sounds/sid/sid4/Ghostbusters.dmp differ diff --git a/sounds/sid/sid4/Ghosts_n_Goblins.dmp b/sounds/sid/sid4/Ghosts_n_Goblins.dmp new file mode 100644 index 0000000..3984733 Binary files /dev/null and b/sounds/sid/sid4/Ghosts_n_Goblins.dmp differ diff --git a/sounds/sid/sid4/Ghouls_n_Ghosts.dmp b/sounds/sid/sid4/Ghouls_n_Ghosts.dmp new file mode 100644 index 0000000..1476c55 Binary files /dev/null and b/sounds/sid/sid4/Ghouls_n_Ghosts.dmp differ diff --git a/sounds/sid/sid4/GianaHighScore.dmp b/sounds/sid/sid4/GianaHighScore.dmp new file mode 100644 index 0000000..d15e87f Binary files /dev/null and b/sounds/sid/sid4/GianaHighScore.dmp differ diff --git a/sounds/sid/sid4/GianaSistersBoss.dmp b/sounds/sid/sid4/GianaSistersBoss.dmp new file mode 100644 index 0000000..e6dadf2 Binary files /dev/null and b/sounds/sid/sid4/GianaSistersBoss.dmp differ diff --git a/sounds/sid/sid4/GianaSistersDieNext.dmp b/sounds/sid/sid4/GianaSistersDieNext.dmp new file mode 100644 index 0000000..ffa8411 Binary files /dev/null and b/sounds/sid/sid4/GianaSistersDieNext.dmp differ diff --git a/sounds/sid/sid4/GianaSistersLevel.dmp b/sounds/sid/sid4/GianaSistersLevel.dmp new file mode 100644 index 0000000..67434aa Binary files /dev/null and b/sounds/sid/sid4/GianaSistersLevel.dmp differ diff --git a/sounds/sid/sid4/GianaSistersPressFire.dmp b/sounds/sid/sid4/GianaSistersPressFire.dmp new file mode 100644 index 0000000..026710a Binary files /dev/null and b/sounds/sid/sid4/GianaSistersPressFire.dmp differ diff --git a/sounds/sid/sid4/Giorgio_Armani_01.dmp b/sounds/sid/sid4/Giorgio_Armani_01.dmp new file mode 100644 index 0000000..c009dcd Binary files /dev/null and b/sounds/sid/sid4/Giorgio_Armani_01.dmp differ diff --git a/sounds/sid/sid4/Golden_Axe.dmp b/sounds/sid/sid4/Golden_Axe.dmp new file mode 100644 index 0000000..1b1a123 Binary files /dev/null and b/sounds/sid/sid4/Golden_Axe.dmp differ diff --git a/sounds/sid/sid4/Goodbye.dmp b/sounds/sid/sid4/Goodbye.dmp new file mode 100644 index 0000000..ce7cffe Binary files /dev/null and b/sounds/sid/sid4/Goodbye.dmp differ diff --git a/sounds/sid/sid4/Great_Giana_Sisters.dmp b/sounds/sid/sid4/Great_Giana_Sisters.dmp new file mode 100644 index 0000000..34427b6 Binary files /dev/null and b/sounds/sid/sid4/Great_Giana_Sisters.dmp differ diff --git a/sounds/sid/sid4/Happy_Rave.dmp b/sounds/sid/sid4/Happy_Rave.dmp new file mode 100644 index 0000000..4d6a9c2 Binary files /dev/null and b/sounds/sid/sid4/Happy_Rave.dmp differ diff --git a/sounds/sid/sid4/Head_Over_Heels.dmp b/sounds/sid/sid4/Head_Over_Heels.dmp new file mode 100644 index 0000000..f713ef4 Binary files /dev/null and b/sounds/sid/sid4/Head_Over_Heels.dmp differ diff --git a/sounds/sid/sid4/Hobbit.dmp b/sounds/sid/sid4/Hobbit.dmp new file mode 100644 index 0000000..c6f1595 Binary files /dev/null and b/sounds/sid/sid4/Hobbit.dmp differ diff --git a/sounds/sid/sid4/IK_plus.dmp b/sounds/sid/sid4/IK_plus.dmp new file mode 100644 index 0000000..406e2f3 Binary files /dev/null and b/sounds/sid/sid4/IK_plus.dmp differ diff --git a/sounds/sid/sid4/I_Love_You.dmp b/sounds/sid/sid4/I_Love_You.dmp new file mode 100644 index 0000000..c6f9bca Binary files /dev/null and b/sounds/sid/sid4/I_Love_You.dmp differ diff --git a/sounds/sid/sid4/Ice_Age.dmp b/sounds/sid/sid4/Ice_Age.dmp new file mode 100644 index 0000000..4f4ce4e Binary files /dev/null and b/sounds/sid/sid4/Ice_Age.dmp differ diff --git a/sounds/sid/sid4/Illmatic_end.dmp b/sounds/sid/sid4/Illmatic_end.dmp new file mode 100644 index 0000000..2695b87 Binary files /dev/null and b/sounds/sid/sid4/Illmatic_end.dmp differ diff --git a/sounds/sid/sid4/Illumination.dmp b/sounds/sid/sid4/Illumination.dmp new file mode 100644 index 0000000..3d02a0b Binary files /dev/null and b/sounds/sid/sid4/Illumination.dmp differ diff --git a/sounds/sid/sid4/Image_Remix.dmp b/sounds/sid/sid4/Image_Remix.dmp new file mode 100644 index 0000000..f76ef0d Binary files /dev/null and b/sounds/sid/sid4/Image_Remix.dmp differ diff --git a/sounds/sid/sid4/Instrumental_Compositions.dmp b/sounds/sid/sid4/Instrumental_Compositions.dmp new file mode 100644 index 0000000..1625283 Binary files /dev/null and b/sounds/sid/sid4/Instrumental_Compositions.dmp differ diff --git a/sounds/sid/sid4/International_Karate.dmp b/sounds/sid/sid4/International_Karate.dmp new file mode 100644 index 0000000..2ce0133 Binary files /dev/null and b/sounds/sid/sid4/International_Karate.dmp differ diff --git a/sounds/sid/sid4/Intro_Collection_part_4.dmp b/sounds/sid/sid4/Intro_Collection_part_4.dmp new file mode 100644 index 0000000..55135ac Binary files /dev/null and b/sounds/sid/sid4/Intro_Collection_part_4.dmp differ diff --git a/sounds/sid/sid4/Intro_Collection_part_6.dmp b/sounds/sid/sid4/Intro_Collection_part_6.dmp new file mode 100644 index 0000000..cc6da1e Binary files /dev/null and b/sounds/sid/sid4/Intro_Collection_part_6.dmp differ diff --git a/sounds/sid/sid4/Intro_Music.dmp b/sounds/sid/sid4/Intro_Music.dmp new file mode 100644 index 0000000..0d6147f Binary files /dev/null and b/sounds/sid/sid4/Intro_Music.dmp differ diff --git a/sounds/sid/sid4/Iron_Men.dmp b/sounds/sid/sid4/Iron_Men.dmp new file mode 100644 index 0000000..f7f8aa8 Binary files /dev/null and b/sounds/sid/sid4/Iron_Men.dmp differ diff --git a/sounds/sid/sid4/Its_a_Sin_02.dmp b/sounds/sid/sid4/Its_a_Sin_02.dmp new file mode 100644 index 0000000..cae2fd0 Binary files /dev/null and b/sounds/sid/sid4/Its_a_Sin_02.dmp differ diff --git a/sounds/sid/sid4/Jabdah.dmp b/sounds/sid/sid4/Jabdah.dmp new file mode 100644 index 0000000..a85c81e Binary files /dev/null and b/sounds/sid/sid4/Jabdah.dmp differ diff --git a/sounds/sid/sid4/Jackal.dmp b/sounds/sid/sid4/Jackal.dmp new file mode 100644 index 0000000..4c95343 Binary files /dev/null and b/sounds/sid/sid4/Jackal.dmp differ diff --git a/sounds/sid/sid4/Jazzy.dmp b/sounds/sid/sid4/Jazzy.dmp new file mode 100644 index 0000000..679d3f3 Binary files /dev/null and b/sounds/sid/sid4/Jazzy.dmp differ diff --git a/sounds/sid/sid4/Jetta.dmp b/sounds/sid/sid4/Jetta.dmp new file mode 100644 index 0000000..578e551 Binary files /dev/null and b/sounds/sid/sid4/Jetta.dmp differ diff --git a/sounds/sid/sid4/Juliet_Bravo.dmp b/sounds/sid/sid4/Juliet_Bravo.dmp new file mode 100644 index 0000000..eead1dd Binary files /dev/null and b/sounds/sid/sid4/Juliet_Bravo.dmp differ diff --git a/sounds/sid/sid4/Keymaster.dmp b/sounds/sid/sid4/Keymaster.dmp new file mode 100644 index 0000000..a835581 Binary files /dev/null and b/sounds/sid/sid4/Keymaster.dmp differ diff --git a/sounds/sid/sid4/Kikstart_II.dmp b/sounds/sid/sid4/Kikstart_II.dmp new file mode 100644 index 0000000..b5e900f Binary files /dev/null and b/sounds/sid/sid4/Kikstart_II.dmp differ diff --git a/sounds/sid/sid4/Klamany_Zutass.dmp b/sounds/sid/sid4/Klamany_Zutass.dmp new file mode 100644 index 0000000..78bd7ec Binary files /dev/null and b/sounds/sid/sid4/Klamany_Zutass.dmp differ diff --git a/sounds/sid/sid4/Knight_Rider.dmp b/sounds/sid/sid4/Knight_Rider.dmp new file mode 100644 index 0000000..8beeddd Binary files /dev/null and b/sounds/sid/sid4/Knight_Rider.dmp differ diff --git a/sounds/sid/sid4/Krakout.dmp b/sounds/sid/sid4/Krakout.dmp new file mode 100644 index 0000000..e3c89e6 Binary files /dev/null and b/sounds/sid/sid4/Krakout.dmp differ diff --git a/sounds/sid/sid4/Krakout1.dmp b/sounds/sid/sid4/Krakout1.dmp new file mode 100644 index 0000000..d3223ca Binary files /dev/null and b/sounds/sid/sid4/Krakout1.dmp differ diff --git a/sounds/sid/sid4/Krakout2.dmp b/sounds/sid/sid4/Krakout2.dmp new file mode 100644 index 0000000..50526dd Binary files /dev/null and b/sounds/sid/sid4/Krakout2.dmp differ diff --git a/sounds/sid/sid4/Krakout3.dmp b/sounds/sid/sid4/Krakout3.dmp new file mode 100644 index 0000000..0e6f53e Binary files /dev/null and b/sounds/sid/sid4/Krakout3.dmp differ diff --git a/sounds/sid/sid4/Krakow.dmp b/sounds/sid/sid4/Krakow.dmp new file mode 100644 index 0000000..51683c7 Binary files /dev/null and b/sounds/sid/sid4/Krakow.dmp differ diff --git a/sounds/sid/sid4/L_E_D_Storm.dmp b/sounds/sid/sid4/L_E_D_Storm.dmp new file mode 100644 index 0000000..fa6acae Binary files /dev/null and b/sounds/sid/sid4/L_E_D_Storm.dmp differ diff --git a/sounds/sid/sid4/Lambada.dmp b/sounds/sid/sid4/Lambada.dmp new file mode 100644 index 0000000..da0d1bf Binary files /dev/null and b/sounds/sid/sid4/Lambada.dmp differ diff --git a/sounds/sid/sid4/Lambada2.dmp b/sounds/sid/sid4/Lambada2.dmp new file mode 100644 index 0000000..2501331 Binary files /dev/null and b/sounds/sid/sid4/Lambada2.dmp differ diff --git a/sounds/sid/sid4/Lambada_Intro.dmp b/sounds/sid/sid4/Lambada_Intro.dmp new file mode 100644 index 0000000..f603e85 Binary files /dev/null and b/sounds/sid/sid4/Lambada_Intro.dmp differ diff --git a/sounds/sid/sid4/Lamebada.dmp b/sounds/sid/sid4/Lamebada.dmp new file mode 100644 index 0000000..4a0d7d8 Binary files /dev/null and b/sounds/sid/sid4/Lamebada.dmp differ diff --git a/sounds/sid/sid4/Last_Ninja.dmp b/sounds/sid/sid4/Last_Ninja.dmp new file mode 100644 index 0000000..0afb25a Binary files /dev/null and b/sounds/sid/sid4/Last_Ninja.dmp differ diff --git a/sounds/sid/sid4/Last_Ninja2.dmp b/sounds/sid/sid4/Last_Ninja2.dmp new file mode 100644 index 0000000..77e1d7b Binary files /dev/null and b/sounds/sid/sid4/Last_Ninja2.dmp differ diff --git a/sounds/sid/sid4/Last_Ninja_3.dmp b/sounds/sid/sid4/Last_Ninja_3.dmp new file mode 100644 index 0000000..4a124c9 Binary files /dev/null and b/sounds/sid/sid4/Last_Ninja_3.dmp differ diff --git a/sounds/sid/sid4/Lax_Up.dmp b/sounds/sid/sid4/Lax_Up.dmp new file mode 100644 index 0000000..da5f891 Binary files /dev/null and b/sounds/sid/sid4/Lax_Up.dmp differ diff --git a/sounds/sid/sid4/Lazy_Jones.dmp b/sounds/sid/sid4/Lazy_Jones.dmp new file mode 100644 index 0000000..8f1c65b Binary files /dev/null and b/sounds/sid/sid4/Lazy_Jones.dmp differ diff --git a/sounds/sid/sid4/Lets_Swing.dmp b/sounds/sid/sid4/Lets_Swing.dmp new file mode 100644 index 0000000..61ff3a9 Binary files /dev/null and b/sounds/sid/sid4/Lets_Swing.dmp differ diff --git a/sounds/sid/sid4/Lightforce.dmp b/sounds/sid/sid4/Lightforce.dmp new file mode 100644 index 0000000..063bcb9 Binary files /dev/null and b/sounds/sid/sid4/Lightforce.dmp differ diff --git a/sounds/sid/sid4/Magic_Disk_64_intro.dmp b/sounds/sid/sid4/Magic_Disk_64_intro.dmp new file mode 100644 index 0000000..714a9d6 Binary files /dev/null and b/sounds/sid/sid4/Magic_Disk_64_intro.dmp differ diff --git a/sounds/sid/sid4/Magic_Flute.dmp b/sounds/sid/sid4/Magic_Flute.dmp new file mode 100644 index 0000000..23250eb Binary files /dev/null and b/sounds/sid/sid4/Magic_Flute.dmp differ diff --git a/sounds/sid/sid4/Mario_v2.dmp b/sounds/sid/sid4/Mario_v2.dmp new file mode 100644 index 0000000..53dff61 Binary files /dev/null and b/sounds/sid/sid4/Mario_v2.dmp differ diff --git a/sounds/sid/sid4/Master_Sample.dmp b/sounds/sid/sid4/Master_Sample.dmp new file mode 100644 index 0000000..5f19542 Binary files /dev/null and b/sounds/sid/sid4/Master_Sample.dmp differ diff --git a/sounds/sid/sid4/Master_of_Magic.dmp b/sounds/sid/sid4/Master_of_Magic.dmp new file mode 100644 index 0000000..d0652c6 Binary files /dev/null and b/sounds/sid/sid4/Master_of_Magic.dmp differ diff --git a/sounds/sid/sid4/Maxitrime.dmp b/sounds/sid/sid4/Maxitrime.dmp new file mode 100644 index 0000000..68195f3 Binary files /dev/null and b/sounds/sid/sid4/Maxitrime.dmp differ diff --git a/sounds/sid/sid4/Mendelssohn.dmp b/sounds/sid/sid4/Mendelssohn.dmp new file mode 100644 index 0000000..53277a1 Binary files /dev/null and b/sounds/sid/sid4/Mendelssohn.dmp differ diff --git a/sounds/sid/sid4/Midnight_Resistance.dmp b/sounds/sid/sid4/Midnight_Resistance.dmp new file mode 100644 index 0000000..c543ac9 Binary files /dev/null and b/sounds/sid/sid4/Midnight_Resistance.dmp differ diff --git a/sounds/sid/sid4/Monday.dmp b/sounds/sid/sid4/Monday.dmp new file mode 100644 index 0000000..acb4fac Binary files /dev/null and b/sounds/sid/sid4/Monday.dmp differ diff --git a/sounds/sid/sid4/Monster_Show.dmp b/sounds/sid/sid4/Monster_Show.dmp new file mode 100644 index 0000000..a63d976 Binary files /dev/null and b/sounds/sid/sid4/Monster_Show.dmp differ diff --git a/sounds/sid/sid4/Monty_on_the_Run.dmp b/sounds/sid/sid4/Monty_on_the_Run.dmp new file mode 100644 index 0000000..1080805 Binary files /dev/null and b/sounds/sid/sid4/Monty_on_the_Run.dmp differ diff --git a/sounds/sid/sid4/More_Human.dmp b/sounds/sid/sid4/More_Human.dmp new file mode 100644 index 0000000..c1ae13f Binary files /dev/null and b/sounds/sid/sid4/More_Human.dmp differ diff --git a/sounds/sid/sid4/Motorway_4.dmp b/sounds/sid/sid4/Motorway_4.dmp new file mode 100644 index 0000000..0aa5e30 Binary files /dev/null and b/sounds/sid/sid4/Motorway_4.dmp differ diff --git a/sounds/sid/sid4/Mr_Marvellous.dmp b/sounds/sid/sid4/Mr_Marvellous.dmp new file mode 100644 index 0000000..189fb6a Binary files /dev/null and b/sounds/sid/sid4/Mr_Marvellous.dmp differ diff --git a/sounds/sid/sid4/Music_Taste.dmp b/sounds/sid/sid4/Music_Taste.dmp new file mode 100644 index 0000000..c12af24 Binary files /dev/null and b/sounds/sid/sid4/Music_Taste.dmp differ diff --git a/sounds/sid/sid4/Mysteries.dmp b/sounds/sid/sid4/Mysteries.dmp new file mode 100644 index 0000000..de0c672 Binary files /dev/null and b/sounds/sid/sid4/Mysteries.dmp differ diff --git a/sounds/sid/sid4/Myth_mix.dmp b/sounds/sid/sid4/Myth_mix.dmp new file mode 100644 index 0000000..4a910af Binary files /dev/null and b/sounds/sid/sid4/Myth_mix.dmp differ diff --git a/sounds/sid/sid4/NWCUG_Demo_2_Outro.dmp b/sounds/sid/sid4/NWCUG_Demo_2_Outro.dmp new file mode 100644 index 0000000..fd973ce Binary files /dev/null and b/sounds/sid/sid4/NWCUG_Demo_2_Outro.dmp differ diff --git a/sounds/sid/sid4/Nemesis_the_Warlock.dmp b/sounds/sid/sid4/Nemesis_the_Warlock.dmp new file mode 100644 index 0000000..07c956a Binary files /dev/null and b/sounds/sid/sid4/Nemesis_the_Warlock.dmp differ diff --git a/sounds/sid/sid4/Never_Ending_Story.dmp b/sounds/sid/sid4/Never_Ending_Story.dmp new file mode 100644 index 0000000..332e976 Binary files /dev/null and b/sounds/sid/sid4/Never_Ending_Story.dmp differ diff --git a/sounds/sid/sid4/New_Bencor_Brothers_Intro.dmp b/sounds/sid/sid4/New_Bencor_Brothers_Intro.dmp new file mode 100644 index 0000000..6b3de74 Binary files /dev/null and b/sounds/sid/sid4/New_Bencor_Brothers_Intro.dmp differ diff --git a/sounds/sid/sid4/Night_Breed.dmp b/sounds/sid/sid4/Night_Breed.dmp new file mode 100644 index 0000000..c872b0a Binary files /dev/null and b/sounds/sid/sid4/Night_Breed.dmp differ diff --git a/sounds/sid/sid4/Nikita.dmp b/sounds/sid/sid4/Nikita.dmp new file mode 100644 index 0000000..2d0b56e Binary files /dev/null and b/sounds/sid/sid4/Nikita.dmp differ diff --git a/sounds/sid/sid4/Ninounekimo.dmp b/sounds/sid/sid4/Ninounekimo.dmp new file mode 100644 index 0000000..4b76799 Binary files /dev/null and b/sounds/sid/sid4/Ninounekimo.dmp differ diff --git a/sounds/sid/sid4/Nykyinen_Virta.dmp b/sounds/sid/sid4/Nykyinen_Virta.dmp new file mode 100644 index 0000000..4e1c89c Binary files /dev/null and b/sounds/sid/sid4/Nykyinen_Virta.dmp differ diff --git a/sounds/sid/sid4/Obliging.dmp b/sounds/sid/sid4/Obliging.dmp new file mode 100644 index 0000000..123c26e Binary files /dev/null and b/sounds/sid/sid4/Obliging.dmp differ diff --git a/sounds/sid/sid4/Ocean_Loader_2.dmp b/sounds/sid/sid4/Ocean_Loader_2.dmp new file mode 100644 index 0000000..9b70fa9 Binary files /dev/null and b/sounds/sid/sid4/Ocean_Loader_2.dmp differ diff --git a/sounds/sid/sid4/Ocean_Loader_5.dmp b/sounds/sid/sid4/Ocean_Loader_5.dmp new file mode 100644 index 0000000..6b20ba8 Binary files /dev/null and b/sounds/sid/sid4/Ocean_Loader_5.dmp differ diff --git a/sounds/sid/sid4/Oej_Oej_Oej-2001.dmp b/sounds/sid/sid4/Oej_Oej_Oej-2001.dmp new file mode 100644 index 0000000..2b15e35 Binary files /dev/null and b/sounds/sid/sid4/Oej_Oej_Oej-2001.dmp differ diff --git a/sounds/sid/sid4/One_and_Only.dmp b/sounds/sid/sid4/One_and_Only.dmp new file mode 100644 index 0000000..4ac9ebd Binary files /dev/null and b/sounds/sid/sid4/One_and_Only.dmp differ diff --git a/sounds/sid/sid4/One_man_and_his_droid.dmp b/sounds/sid/sid4/One_man_and_his_droid.dmp new file mode 100644 index 0000000..76aabde Binary files /dev/null and b/sounds/sid/sid4/One_man_and_his_droid.dmp differ diff --git a/sounds/sid/sid4/OtherSIDe.dmp b/sounds/sid/sid4/OtherSIDe.dmp new file mode 100644 index 0000000..edf30f6 Binary files /dev/null and b/sounds/sid/sid4/OtherSIDe.dmp differ diff --git a/sounds/sid/sid4/OutrunRemix.dmp b/sounds/sid/sid4/OutrunRemix.dmp new file mode 100644 index 0000000..aff83b0 Binary files /dev/null and b/sounds/sid/sid4/OutrunRemix.dmp differ diff --git a/sounds/sid/sid4/Oxygen_4.dmp b/sounds/sid/sid4/Oxygen_4.dmp new file mode 100644 index 0000000..bdb51fb Binary files /dev/null and b/sounds/sid/sid4/Oxygen_4.dmp differ diff --git a/sounds/sid/sid4/Oxyron_Party_v2_Invitation.dmp b/sounds/sid/sid4/Oxyron_Party_v2_Invitation.dmp new file mode 100644 index 0000000..635fada Binary files /dev/null and b/sounds/sid/sid4/Oxyron_Party_v2_Invitation.dmp differ diff --git a/sounds/sid/sid4/PP_Hammer.dmp b/sounds/sid/sid4/PP_Hammer.dmp new file mode 100644 index 0000000..7db0776 Binary files /dev/null and b/sounds/sid/sid4/PP_Hammer.dmp differ diff --git a/sounds/sid/sid4/Paperboy.dmp b/sounds/sid/sid4/Paperboy.dmp new file mode 100644 index 0000000..529fbdc Binary files /dev/null and b/sounds/sid/sid4/Paperboy.dmp differ diff --git a/sounds/sid/sid4/Parallax.dmp b/sounds/sid/sid4/Parallax.dmp new file mode 100644 index 0000000..535f782 Binary files /dev/null and b/sounds/sid/sid4/Parallax.dmp differ diff --git a/sounds/sid/sid4/Paranoid_5_part_4.dmp b/sounds/sid/sid4/Paranoid_5_part_4.dmp new file mode 100644 index 0000000..2c82053 Binary files /dev/null and b/sounds/sid/sid4/Paranoid_5_part_4.dmp differ diff --git a/sounds/sid/sid4/Pitfall_II-Lost_Caverns.dmp b/sounds/sid/sid4/Pitfall_II-Lost_Caverns.dmp new file mode 100644 index 0000000..0114f4a Binary files /dev/null and b/sounds/sid/sid4/Pitfall_II-Lost_Caverns.dmp differ diff --git a/sounds/sid/sid4/Plastic_Pop.dmp b/sounds/sid/sid4/Plastic_Pop.dmp new file mode 100644 index 0000000..a8fd32d Binary files /dev/null and b/sounds/sid/sid4/Plastic_Pop.dmp differ diff --git a/sounds/sid/sid4/Power_Drift.dmp b/sounds/sid/sid4/Power_Drift.dmp new file mode 100644 index 0000000..bb6ea87 Binary files /dev/null and b/sounds/sid/sid4/Power_Drift.dmp differ diff --git a/sounds/sid/sid4/Puppets.dmp b/sounds/sid/sid4/Puppets.dmp new file mode 100644 index 0000000..7b7cbfd Binary files /dev/null and b/sounds/sid/sid4/Puppets.dmp differ diff --git a/sounds/sid/sid4/Purple_Haze_part_8.dmp b/sounds/sid/sid4/Purple_Haze_part_8.dmp new file mode 100644 index 0000000..925fe6f Binary files /dev/null and b/sounds/sid/sid4/Purple_Haze_part_8.dmp differ diff --git a/sounds/sid/sid4/R-Type.dmp b/sounds/sid/sid4/R-Type.dmp new file mode 100644 index 0000000..8f4bd83 Binary files /dev/null and b/sounds/sid/sid4/R-Type.dmp differ diff --git a/sounds/sid/sid4/Rasputin.dmp b/sounds/sid/sid4/Rasputin.dmp new file mode 100644 index 0000000..1b5d0d8 Binary files /dev/null and b/sounds/sid/sid4/Rasputin.dmp differ diff --git a/sounds/sid/sid4/Reptilia_1.dmp b/sounds/sid/sid4/Reptilia_1.dmp new file mode 100644 index 0000000..9b38008 Binary files /dev/null and b/sounds/sid/sid4/Reptilia_1.dmp differ diff --git a/sounds/sid/sid4/Rick_Dangerous_II.dmp b/sounds/sid/sid4/Rick_Dangerous_II.dmp new file mode 100644 index 0000000..3633ed3 Binary files /dev/null and b/sounds/sid/sid4/Rick_Dangerous_II.dmp differ diff --git a/sounds/sid/sid4/Robocop.dmp b/sounds/sid/sid4/Robocop.dmp new file mode 100644 index 0000000..78b535e Binary files /dev/null and b/sounds/sid/sid4/Robocop.dmp differ diff --git a/sounds/sid/sid4/Robocop3.dmp b/sounds/sid/sid4/Robocop3.dmp new file mode 100644 index 0000000..a4d82e0 Binary files /dev/null and b/sounds/sid/sid4/Robocop3.dmp differ diff --git a/sounds/sid/sid4/Rolling_Ronny.dmp b/sounds/sid/sid4/Rolling_Ronny.dmp new file mode 100644 index 0000000..b9405fe Binary files /dev/null and b/sounds/sid/sid4/Rolling_Ronny.dmp differ diff --git a/sounds/sid/sid4/Russian.dmp b/sounds/sid/sid4/Russian.dmp new file mode 100644 index 0000000..01eb45f Binary files /dev/null and b/sounds/sid/sid4/Russian.dmp differ diff --git a/sounds/sid/sid4/S_O_S.dmp b/sounds/sid/sid4/S_O_S.dmp new file mode 100644 index 0000000..77d9101 Binary files /dev/null and b/sounds/sid/sid4/S_O_S.dmp differ diff --git a/sounds/sid/sid4/Sagyrs_Castle.dmp b/sounds/sid/sid4/Sagyrs_Castle.dmp new file mode 100644 index 0000000..8229e2b Binary files /dev/null and b/sounds/sid/sid4/Sagyrs_Castle.dmp differ diff --git a/sounds/sid/sid4/Sanforized_5_intro.dmp b/sounds/sid/sid4/Sanforized_5_intro.dmp new file mode 100644 index 0000000..4fb5e4c Binary files /dev/null and b/sounds/sid/sid4/Sanforized_5_intro.dmp differ diff --git a/sounds/sid/sid4/Se_Gitai_O_Ilios.dmp b/sounds/sid/sid4/Se_Gitai_O_Ilios.dmp new file mode 100644 index 0000000..b960295 Binary files /dev/null and b/sounds/sid/sid4/Se_Gitai_O_Ilios.dmp differ diff --git a/sounds/sid/sid4/Sevenfunk.dmp b/sounds/sid/sid4/Sevenfunk.dmp new file mode 100644 index 0000000..1b9bf08 Binary files /dev/null and b/sounds/sid/sid4/Sevenfunk.dmp differ diff --git a/sounds/sid/sid4/Shadow_of_the_Beast.dmp b/sounds/sid/sid4/Shadow_of_the_Beast.dmp new file mode 100644 index 0000000..f906882 Binary files /dev/null and b/sounds/sid/sid4/Shadow_of_the_Beast.dmp differ diff --git a/sounds/sid/sid4/Speedball.dmp b/sounds/sid/sid4/Speedball.dmp new file mode 100644 index 0000000..5af1cf2 Binary files /dev/null and b/sounds/sid/sid4/Speedball.dmp differ diff --git a/sounds/sid/sid4/Spy_Hunter.dmp b/sounds/sid/sid4/Spy_Hunter.dmp new file mode 100644 index 0000000..2f7d5ac Binary files /dev/null and b/sounds/sid/sid4/Spy_Hunter.dmp differ diff --git a/sounds/sid/sid4/Star_Wars_Music.dmp b/sounds/sid/sid4/Star_Wars_Music.dmp new file mode 100644 index 0000000..9c5ca62 Binary files /dev/null and b/sounds/sid/sid4/Star_Wars_Music.dmp differ diff --git a/sounds/sid/sid4/Stepper.dmp b/sounds/sid/sid4/Stepper.dmp new file mode 100644 index 0000000..0820be8 Binary files /dev/null and b/sounds/sid/sid4/Stepper.dmp differ diff --git a/sounds/sid/sid4/Stop_Coders_Naughtiness_4.dmp b/sounds/sid/sid4/Stop_Coders_Naughtiness_4.dmp new file mode 100644 index 0000000..c7b3e6e Binary files /dev/null and b/sounds/sid/sid4/Stop_Coders_Naughtiness_4.dmp differ diff --git a/sounds/sid/sid4/Storm.dmp b/sounds/sid/sid4/Storm.dmp new file mode 100644 index 0000000..ca37018 Binary files /dev/null and b/sounds/sid/sid4/Storm.dmp differ diff --git a/sounds/sid/sid4/Stormlord_V2.dmp b/sounds/sid/sid4/Stormlord_V2.dmp new file mode 100644 index 0000000..ef70e7d Binary files /dev/null and b/sounds/sid/sid4/Stormlord_V2.dmp differ diff --git a/sounds/sid/sid4/Style_Intro.dmp b/sounds/sid/sid4/Style_Intro.dmp new file mode 100644 index 0000000..be64f9d Binary files /dev/null and b/sounds/sid/sid4/Style_Intro.dmp differ diff --git a/sounds/sid/sid4/Synth_Sample.dmp b/sounds/sid/sid4/Synth_Sample.dmp new file mode 100644 index 0000000..183b369 Binary files /dev/null and b/sounds/sid/sid4/Synth_Sample.dmp differ diff --git a/sounds/sid/sid4/TCA_Intro.dmp b/sounds/sid/sid4/TCA_Intro.dmp new file mode 100644 index 0000000..2d19191 Binary files /dev/null and b/sounds/sid/sid4/TCA_Intro.dmp differ diff --git a/sounds/sid/sid4/Tepelrups_part3_3.dmp b/sounds/sid/sid4/Tepelrups_part3_3.dmp new file mode 100644 index 0000000..44a6021 Binary files /dev/null and b/sounds/sid/sid4/Tepelrups_part3_3.dmp differ diff --git a/sounds/sid/sid4/Terrys_Big_Adventure.dmp b/sounds/sid/sid4/Terrys_Big_Adventure.dmp new file mode 100644 index 0000000..9a512b6 Binary files /dev/null and b/sounds/sid/sid4/Terrys_Big_Adventure.dmp differ diff --git a/sounds/sid/sid4/TestDump.dmp b/sounds/sid/sid4/TestDump.dmp new file mode 100644 index 0000000..26fc6e4 Binary files /dev/null and b/sounds/sid/sid4/TestDump.dmp differ diff --git a/sounds/sid/sid4/Theme_From_S-Express.dmp b/sounds/sid/sid4/Theme_From_S-Express.dmp new file mode 100644 index 0000000..8258fe4 Binary files /dev/null and b/sounds/sid/sid4/Theme_From_S-Express.dmp differ diff --git a/sounds/sid/sid4/Theres_That_Light_Again.dmp b/sounds/sid/sid4/Theres_That_Light_Again.dmp new file mode 100644 index 0000000..5e7bc3e Binary files /dev/null and b/sounds/sid/sid4/Theres_That_Light_Again.dmp differ diff --git a/sounds/sid/sid4/Thing_on_a_Spring.dmp b/sounds/sid/sid4/Thing_on_a_Spring.dmp new file mode 100644 index 0000000..e055494 Binary files /dev/null and b/sounds/sid/sid4/Thing_on_a_Spring.dmp differ diff --git a/sounds/sid/sid4/Think_Twice_I.dmp b/sounds/sid/sid4/Think_Twice_I.dmp new file mode 100644 index 0000000..7b45ad2 Binary files /dev/null and b/sounds/sid/sid4/Think_Twice_I.dmp differ diff --git a/sounds/sid/sid4/Thrust.dmp b/sounds/sid/sid4/Thrust.dmp new file mode 100644 index 0000000..f2e1c1a Binary files /dev/null and b/sounds/sid/sid4/Thrust.dmp differ diff --git a/sounds/sid/sid4/Thunder_Intro.dmp b/sounds/sid/sid4/Thunder_Intro.dmp new file mode 100644 index 0000000..dc92159 Binary files /dev/null and b/sounds/sid/sid4/Thunder_Intro.dmp differ diff --git a/sounds/sid/sid4/Thundercats.dmp b/sounds/sid/sid4/Thundercats.dmp new file mode 100644 index 0000000..df1b868 Binary files /dev/null and b/sounds/sid/sid4/Thundercats.dmp differ diff --git a/sounds/sid/sid4/Time_Operator_tune_3.dmp b/sounds/sid/sid4/Time_Operator_tune_3.dmp new file mode 100644 index 0000000..b127005 Binary files /dev/null and b/sounds/sid/sid4/Time_Operator_tune_3.dmp differ diff --git a/sounds/sid/sid4/Tom_Sawyer.dmp b/sounds/sid/sid4/Tom_Sawyer.dmp new file mode 100644 index 0000000..6acd5c0 Binary files /dev/null and b/sounds/sid/sid4/Tom_Sawyer.dmp differ diff --git a/sounds/sid/sid4/Transputer.dmp b/sounds/sid/sid4/Transputer.dmp new file mode 100644 index 0000000..b710771 Binary files /dev/null and b/sounds/sid/sid4/Transputer.dmp differ diff --git a/sounds/sid/sid4/Tribute_to_Chris_Huelsbeck.dmp b/sounds/sid/sid4/Tribute_to_Chris_Huelsbeck.dmp new file mode 100644 index 0000000..21d1e26 Binary files /dev/null and b/sounds/sid/sid4/Tribute_to_Chris_Huelsbeck.dmp differ diff --git a/sounds/sid/sid4/Turrican.dmp b/sounds/sid/sid4/Turrican.dmp new file mode 100644 index 0000000..3cf8fbe Binary files /dev/null and b/sounds/sid/sid4/Turrican.dmp differ diff --git a/sounds/sid/sid4/TurricanJetPak.dmp b/sounds/sid/sid4/TurricanJetPak.dmp new file mode 100644 index 0000000..5912fcb Binary files /dev/null and b/sounds/sid/sid4/TurricanJetPak.dmp differ diff --git a/sounds/sid/sid4/Turrican_2-The_Final_Fight.dmp b/sounds/sid/sid4/Turrican_2-The_Final_Fight.dmp new file mode 100644 index 0000000..7dfee19 Binary files /dev/null and b/sounds/sid/sid4/Turrican_2-The_Final_Fight.dmp differ diff --git a/sounds/sid/sid4/Unknown_103.dmp b/sounds/sid/sid4/Unknown_103.dmp new file mode 100644 index 0000000..b879c25 Binary files /dev/null and b/sounds/sid/sid4/Unknown_103.dmp differ diff --git a/sounds/sid/sid4/Unknown_108.dmp b/sounds/sid/sid4/Unknown_108.dmp new file mode 100644 index 0000000..01b2184 Binary files /dev/null and b/sounds/sid/sid4/Unknown_108.dmp differ diff --git a/sounds/sid/sid4/Unknown_115.dmp b/sounds/sid/sid4/Unknown_115.dmp new file mode 100644 index 0000000..c52d19a Binary files /dev/null and b/sounds/sid/sid4/Unknown_115.dmp differ diff --git a/sounds/sid/sid4/Unknown_116.dmp b/sounds/sid/sid4/Unknown_116.dmp new file mode 100644 index 0000000..bb6e349 Binary files /dev/null and b/sounds/sid/sid4/Unknown_116.dmp differ diff --git a/sounds/sid/sid4/Unknown_71.dmp b/sounds/sid/sid4/Unknown_71.dmp new file mode 100644 index 0000000..5fb97ea Binary files /dev/null and b/sounds/sid/sid4/Unknown_71.dmp differ diff --git a/sounds/sid/sid4/Unknown_83.dmp b/sounds/sid/sid4/Unknown_83.dmp new file mode 100644 index 0000000..8814a9b Binary files /dev/null and b/sounds/sid/sid4/Unknown_83.dmp differ diff --git a/sounds/sid/sid4/Unknown_85.dmp b/sounds/sid/sid4/Unknown_85.dmp new file mode 100644 index 0000000..d0a2a72 Binary files /dev/null and b/sounds/sid/sid4/Unknown_85.dmp differ diff --git a/sounds/sid/sid4/Utter_Ego_Demo.dmp b/sounds/sid/sid4/Utter_Ego_Demo.dmp new file mode 100644 index 0000000..7911104 Binary files /dev/null and b/sounds/sid/sid4/Utter_Ego_Demo.dmp differ diff --git a/sounds/sid/sid4/Valley_of_Dreams.dmp b/sounds/sid/sid4/Valley_of_Dreams.dmp new file mode 100644 index 0000000..070b4f6 Binary files /dev/null and b/sounds/sid/sid4/Valley_of_Dreams.dmp differ diff --git a/sounds/sid/sid4/Voluntary.dmp b/sounds/sid/sid4/Voluntary.dmp new file mode 100644 index 0000000..ecbb76a Binary files /dev/null and b/sounds/sid/sid4/Voluntary.dmp differ diff --git a/sounds/sid/sid4/When_Im_64.dmp b/sounds/sid/sid4/When_Im_64.dmp new file mode 100644 index 0000000..2b18cad Binary files /dev/null and b/sounds/sid/sid4/When_Im_64.dmp differ diff --git a/sounds/sid/sid4/Winner_Takes_All.dmp b/sounds/sid/sid4/Winner_Takes_All.dmp new file mode 100644 index 0000000..82f5d4a Binary files /dev/null and b/sounds/sid/sid4/Winner_Takes_All.dmp differ diff --git a/sounds/sid/sid4/X-Out_PSID.dmp b/sounds/sid/sid4/X-Out_PSID.dmp new file mode 100644 index 0000000..ef23d6d Binary files /dev/null and b/sounds/sid/sid4/X-Out_PSID.dmp differ diff --git a/sounds/sid/sid4/lastV8.dmp b/sounds/sid/sid4/lastV8.dmp new file mode 100644 index 0000000..2773269 Binary files /dev/null and b/sounds/sid/sid4/lastV8.dmp differ diff --git a/sounds/sid/sid4/mule.dmp b/sounds/sid/sid4/mule.dmp new file mode 100644 index 0000000..bc640c7 Binary files /dev/null and b/sounds/sid/sid4/mule.dmp differ diff --git a/sounds/sid/sid4/ninja.dmp b/sounds/sid/sid4/ninja.dmp new file mode 100644 index 0000000..a1434b0 Binary files /dev/null and b/sounds/sid/sid4/ninja.dmp differ diff --git a/sounds/wav/alien3.wav b/sounds/wav/alien3.wav new file mode 100644 index 0000000..f9bcda9 Binary files /dev/null and b/sounds/wav/alien3.wav differ diff --git a/sounds/wav/hfunk.wav b/sounds/wav/hfunk.wav new file mode 100644 index 0000000..ef9229d Binary files /dev/null and b/sounds/wav/hfunk.wav differ diff --git a/sounds/wav/test/wavtest.wav b/sounds/wav/test/wavtest.wav new file mode 100644 index 0000000..affc89e Binary files /dev/null and b/sounds/wav/test/wavtest.wav differ diff --git a/sounds/wav/woodz.wav b/sounds/wav/woodz.wav new file mode 100644 index 0000000..4bac9c1 Binary files /dev/null and b/sounds/wav/woodz.wav differ diff --git a/source/3dmulti/3dmulti.spin b/source/3dmulti/3dmulti.spin new file mode 100644 index 0000000..232b8d6 --- /dev/null +++ b/source/3dmulti/3dmulti.spin @@ -0,0 +1,228 @@ +{ + Multi core transform sample + + derived from "3D Graphics DEMO" by Beau Schwabe (Parallax) +} + +CON + ' enable multi core transform calculation + MultiCoreTranform = true + + ZX = 180 + ZY = 240 + + MaxPoints = 50 + + _CLKMODE = XTAL1 + PLL16X + _XINFREQ = 5_000_000 + _stack = ($3000 + $3000 + 100) >> 2 + + x_tiles = 16 + y_tiles = 12 + + paramcount = 14 + bitmap_base = $2000 + display_base = $5000 + + +VAR + long tv_status '0/1/2 = off/visible/invisible read-only + long tv_enable '0/? = off/on write-only + long tv_pins '%ppmmm = pins write-only + long tv_mode '%ccinp = chroma,interlace,ntsc/pal,swap write-only + long tv_screen 'pointer to screen (words) write-only + long tv_colors 'pointer to colors (longs) write-only + long tv_hc 'horizontal cells write-only + long tv_vc 'vertical cells write-only + long tv_hx 'horizontal cell expansion write-only + long tv_vx 'vertical cell expansion write-only + long tv_ho 'horizontal offset write-only + long tv_vo 'vertical offset write-only + long tv_broadcast 'broadcast frequency (Hz) write-only + long tv_auralcog 'aural fm cog write-only + + word screen[x_tiles * y_tiles] + long colors[64] + + long cogStack[40 * 5] + long pointData[MaxPoints * 5] + byte frame + + +OBJ + tv : "bel-tv" + gr : "pf_graphics" + +PUB start | i,dx,dy + + 'start tv + longmove(@tv_status, @tvparams, paramcount) + tv_screen := @screen + tv_colors := @colors + tv.start(@tv_status) + + 'init colors + repeat i from 0 to 63 + colors[i] := $ad02ad06 + + 'init tile screen + i := 0 + repeat dy from 0 to tv_vc - 1 + repeat dx from 0 to tv_hc - 1 + screen[i++] := display_base >> 6 + dy + dx * tv_vc + (dy << 10) + + 'start and setup graphics + gr.start + gr.setup(tv_hc, tv_vc, tv_hc<<3, tv_vc<<3, bitmap_base) + + 'Start transform routines (per object) + if MultiCoreTranform + repeat i from 0 to 4 + cognew( Polyobj(@pointData[ MaxPoints * i ], @PostureData + i * 20), @cogStack[i * 40] ) + + MainLoop + + +PRI MainLoop | i, n, t + n := 0 + t := cnt & |<27 + repeat + gr.clear + gr.width(0) + + repeat i from 0 to n + if !MultiCoreTranform + TranslatePoints( @pointData[ MaxPoints * i ], @PostureData + i * 20, @PointSrc, constant((@PointSrc_End - @PointSrc)/3) ) + repeat until ( word[ @PostureData + i * 20 + 18] == frame ) + gr.lineseq( @pointData[MaxPoints * i], @SeqData) + + gr.copy(display_base) + frame++ + + if ( t <> cnt & |<27 ) + t := cnt & |<27 + n := (n + 1) <# 4 + + 'wait Vsync + repeat until ( tv_status == 1 ) + + +PRI PolyObj(destAddr, postureAddr) + repeat + repeat while word[ postureAddr + 18 ] == frame + TranslatePoints( destAddr, postureAddr, @PointSrc, constant((@PointSrc_End - @PointSrc)/3) ) + + +PRI TranslatePoints( destAddr, postureAddr, pointAddr, numPoints ) | i,dst,px,py,pz,tx,ty,tz,dx,dy,dz,S1,S2,S3,C1,C2,C3,x,y,z + tx := ( word[ postureAddr + 6 ] += word[ postureAddr + 12 ] ) + ty := ( word[ postureAddr + 8 ] += word[ postureAddr + 14 ] ) + tz := ( word[ postureAddr + 10 ] += word[ postureAddr + 16 ] ) + + S1 := Sin(tx) + S2 := Sin(ty) + S3 := Sin(tz) + + C1 := Cos(tx) + C2 := Cos(ty) + C3 := Cos(tz) + + x := ~word[ postureAddr + 0 ] + y := ~word[ postureAddr + 2 ] + z := word[ postureAddr + 4 ] + (C1 ~> 9) ' add C1~>9 for test + + repeat i from 0 to numPoints + px := ~byte[pointAddr++] + py := ~byte[pointAddr++] + pz := ~byte[pointAddr++] + + tx := ( px * C2 - pz * S2 ) ~> 16 + tz := ( px * S2 + pz * C2 ) ~> 16 + ty := ( tz * S1 + py * C1 ) ~> 16 + + dx := ( tx * C3 + ty * S3 ) ~> 16 + x + dy := ( ty * C3 - tx * S3 ) ~> 16 + y + dz := ( tz * C1 - py * S1 ) ~> 16 + z + + word[destAddr ] := dx * ZX / dz + word[destAddr+2] := dy * ZY / dz + destAddr += 4 + + word[ postureAddr + 18 ] := frame + + +pri cos(angle) : x + x := sin(angle + $800) + + +pri sin(angle) : y + '' Get sine of angle (0-8191) + y := angle << 1 & $FFE ' address + if angle & $800 + y := word[$F000 - y] + else + y := word[$E000 + y] + if angle & $1000 + -y + + +DAT +PostureData + ' trans rot rotspeed sync + word 0, 0, 400, 0, 0, 0, 0, 0, 200, 0 + word -120, -80, 400, 0, 0, 0, 50, 30, 40, 0 + word -120, 80, 400, 0, 0, 0, 40, 50, 30, 0 + word 120, -80, 400, 0, 0, 0, 30, 50, 40, 0 + word 120, 80, 400, 0, 0, 0, 50, 40, 30, 0 + +PointSrc + byte -20,-20,-20 + byte -20,-20, 20 + byte -20, 20, 20 + byte -20, 20,-20 + byte 20,-20,-20 + byte 20,-20, 20 + byte 20, 20, 20 + byte 20, 20,-20 + + byte -40,-40,-40 + byte -40,-40, 40 + byte -40, 40, 40 + byte -40, 40,-40 + byte 40,-40,-40 + byte 40,-40, 40 + byte 40, 40, 40 + byte 40, 40,-40 + + byte -70, 0, 0 + byte 70, 0, 0 +PointSrc_End + +SeqData + ' orange thing + byte 13, 1, 16, 0, 4, 17, 5, 1, 16, 2, 6, 17, 7, 3, 16 + byte 5, 1, 0, 1, 2, 3, 0 + byte 5, 1, 4, 5, 6, 7, 4 + ' black cube + byte 10, 2, 8, 9,10,11, 8,12,13,14,15,12 + byte 2, 2, 9,13 + byte 2, 2,10,14 + byte 2, 2,11,15 + byte 0 + + +tvparams long 0 'status + long 1 'enable + 'long %011_0000 'pins Old Board + long %010_0101 'pins New Board + long %0000 'mode + long 0 'screen + long 0 'colors + long x_tiles 'hc + long y_tiles 'vc + long 10 'hx + long 1 'vx + long 0 'ho + long 0 'vo + long 60_000_000 '_xinfreq<<4 'broadcast + long 0 'auralcog + diff --git a/source/3dmulti/pf_graphics.spin b/source/3dmulti/pf_graphics.spin new file mode 100644 index 0000000..0451046 --- /dev/null +++ b/source/3dmulti/pf_graphics.spin @@ -0,0 +1,1731 @@ +''*************************************** +''* Graphics Driver v1.0 * +''* Author: Chip Gracey * +''* Copyright (c) 2005 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +'' +'' Theory of Operation: +'' +'' A cog is launched which processes commands via the PUB routines. +'' +'' Points, lines, arcs, sprites, text, and polygons are rasterized into +'' a specified stretch of memory which serves as a generic bitmap buffer. +'' +'' The bitmap can be displayed by the TV.SRC or VGA.SRC driver. +'' +'' See GRAPHICS_DEMO.SRC for usage example. +'' + +CON + + #1, _setup, _color, _width, _plot, _line, _arc, _vec, _vecarc, {_pix, _pixarc,} _text, _textarc, _textmode, _fill, _lineseq, _loop + +VAR + + long cog + + long command + + long bitmap_base 'bitmap data + long bitmap_longs + word bases[32] + + long pixel_width 'pixel data + long slices[8] + + long text_xs, text_ys, text_sp, text_just 'text data (these 4 must be contiguous) + + +PUB start : okay + +'' Start graphics driver - starts a cog +'' returns false if no cog available + + fontptr := @font 'set font pointer (same for all instances) + + stop + okay := cog := cognew(@loop, @command) + 1 + + +PUB stop + +'' Stop graphics driver - frees a cog + + if cog + cogstop(cog~ - 1) + + command~ + + +PUB setup(x_tiles, y_tiles, x_origin, y_origin, base_ptr) | bases_ptr, slices_ptr + +'' Set bitmap parameters +'' +'' x_tiles - number of x tiles (tiles are 16x16 pixels each) +'' y_tiles - number of y tiles +'' x_origin - relative-x center pixel +'' y_origin - relative-y center pixel +'' base_ptr - base address of bitmap + + setcommand(_loop, 0) 'make sure last command finished + + repeat bases_ptr from 0 to x_tiles - 1 <# 31 'write bases + bases[bases_ptr] := base_ptr + bases_ptr * y_tiles << 6 + + y_tiles <<= 4 'adjust arguments and do setup command + y_origin := y_tiles - y_origin - 1 + bases_ptr := @bases + slices_ptr := @slices + setcommand(_setup, @x_tiles) + + bitmap_base := base_ptr 'retain high-level bitmap data + bitmap_longs := x_tiles * y_tiles + + +PUB clear + +'' Clear bitmap + + setcommand(_loop, 0) 'make sure last command finished + + longfill(bitmap_base, 0, bitmap_longs) 'clear bitmap + + +PUB copy(dest_ptr) + +'' Copy bitmap +'' use for double-buffered display (flicker-free) +'' +'' dest_ptr - base address of destination bitmap + + setcommand(_loop, 0) 'make sure last command finished + + longmove(dest_ptr, bitmap_base, bitmap_longs) 'copy bitmap + + +PUB color(c) + +'' Set pixel color to two-bit pattern +'' +'' c - color code in bits[1..0] + + setcommand(_color, @colors[c & 3]) 'set color + + +PUB width(w) | pixel_passes, r, i, p + +'' Set pixel width +'' actual width is w[3..0] + 1 +'' +'' w - 0..15 for round pixels, 16..31 for square pixels + + r := not w & $10 'determine pixel shape/width + w &= $F + pixel_width := w + pixel_passes := w >> 1 + 1 + + setcommand(_width, @w) 'do width command now to avoid updating slices when busy + + p := w ^ $F 'update slices to new shape/width + repeat i from 0 to w >> 1 + slices[i] := true >> (p << 1) << (p & $E) + if r and pixels[w] & |< i + p += 2 + if r and i == pixel_passes - 2 + p += 2 + + +PUB colorwidth(c, w) + +'' Set pixel color and width + + color(c) + width(w) + + +PUB plot(x, y) + +'' Plot point +'' +'' x,y - point + + setcommand(_plot, @x) + + +PUB line(x, y) + +'' Draw a line to point +'' +'' x,y - endpoint + + setcommand(_line, @x) + + +PUB arc(x, y, xr, yr, angle, anglestep, steps, arcmode) + +'' Draw an arc +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - initial angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' anglestep - angle step in bits[12..0] +'' steps - number of steps (0 just leaves (x,y) at initial arc position) +'' arcmode - 0: plot point(s) +'' 1: line to point(s) +'' 2: line between points +'' 3: line from point(s) to center + + setcommand(_arc, @x) + + +PUB vec(x, y, vecscale, vecangle, vecdef_ptr) + +'' Draw a vector sprite +'' +'' x,y - center of vector sprite +'' vecscale - scale of vector sprite ($100 = 1x) +'' vecangle - rotation angle of vector sprite in bits[12..0] +'' vecdef_ptr - address of vector sprite definition +'' +'' +'' Vector sprite definition: +'' +'' word $8000|$4000+angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) +'' word length 'vector length +'' ... 'more vectors +'' ... +'' word 0 'end of definition + + setcommand(_vec, @x) + + +PUB vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) + +'' Draw a vector sprite at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' vecscale - scale of vector sprite ($100 = 1x) +'' vecangle - rotation angle of vector sprite in bits[12..0] +'' vecdef_ptr - address of vector sprite definition + + setcommand(_vecarc, @x) + + +PUB lineseq(vecdef_ptr, seqdef_ptr) + +'' Draw a line sequence +'' vecdef_ptr - address of vector definition +'' seqdef_ptr - address of sequence definition + + setcommand(_lineseq, @vecdef_ptr) + + +{ +PUB pix(x, y, pixrot, pixdef_ptr) + +'' Draw a pixel sprite +'' +'' x,y - center of vector sprite +'' pixrot - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror +'' pixdef_ptr - address of pixel sprite definition +'' +'' +'' Pixel sprite definition: +'' +'' word 'word align, express dimensions and center, define pixels +'' byte xwords, ywords, xorigin, yorigin +'' word %%xxxxxxxx,%%xxxxxxxx +'' word %%xxxxxxxx,%%xxxxxxxx +'' word %%xxxxxxxx,%%xxxxxxxx +'' ... + + setcommand(_pix, @x) + + +PUB pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) + +'' Draw a pixel sprite at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' pixrot - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror +'' pixdef_ptr - address of pixel sprite definition + + setcommand(_pixarc, @x) +} + +PUB text(x, y, string_ptr) | justx, justy + +'' Draw text +'' +'' x,y - text position (see textmode for sizing and justification) +'' string_ptr - address of zero-terminated string (it may be necessary to call .finish +'' immediately afterwards to prevent subsequent code from clobbering the +'' string as it is being drawn + + justify(string_ptr, @justx) 'justify string and draw text + setcommand(_text, @x) + + +PUB textmode(x_scale, y_scale, spacing, justification) + +'' Set text size and justification +'' +'' x_scale - x character scale, should be 1+ +'' y_scale - y character scale, should be 1+ +'' spacing - character spacing, 6 is normal +'' justification - bits[1..0]: 0..3 = left, center, right, left +'' bits[3..2]: 0..3 = bottom, center, top, bottom + + longmove(@text_xs, @x_scale, 4) 'retain high-level text data + + setcommand(_textmode, @x_scale) 'set text mode + + +PUB box(x, y, box_width, box_height) | x2, y2, pmin, pmax + +'' Draw a box with round/square corners, according to pixel width +'' +'' x,y - box left, box bottom + + if box_width > pixel_width and box_height > pixel_width + + pmax := pixel_width - (pmin := pixel_width >> 1) 'get pixel-half-min and pixel-half-max + + x += pmin 'adjust coordinates to accomodate width + y += pmin + x2 := x + box_width - 1 - pixel_width + y2 := y + box_height - 1 - pixel_width + + plot(x, y) 'plot round/square corners + plot(x, y2) + plot(x2, y) + plot(x2, y2) + + fill(x, y2 + pmax, 0, (x2 - x) << 16, 0, 0, pmax) 'fill gaps + fill(x, y, 0, (x2 - x) << 16, 0, 0, pmin) + fill(x - pmin, y2, 0, (x2 - x + pixel_width) << 16, 0, 0, y2 - y) + + +PUB quad(x1, y1, x2, y2, x3, y3, x4, y4) + +'' Draw a solid quadrilateral +'' vertices must be ordered clockwise or counter-clockwise + + tri(x1, y1, x2, y2, x3, y3) 'draw two triangle to make 4-sides polygon + tri(x3, y3, x4, y4, x1, y1) + + +PUB tri(x1, y1, x2, y2, x3, y3) | xy[2] + +'' Draw a solid triangle + +' reorder vertices by descending y + + case (y1 => y2) & %100 | (y2 => y3) & %010 | (y1 => y3) & %001 + %000: + longmove(@xy, @x1, 2) + longmove(@x1, @x3, 2) + longmove(@x3, @xy, 2) + %010: + longmove(@xy, @x1, 2) + longmove(@x1, @x2, 4) + longmove(@x3, @xy, 2) + %011: + longmove(@xy, @x1, 2) + longmove(@x1, @x2, 2) + longmove(@x2, @xy, 2) + %100: + longmove(@xy, @x3, 2) + longmove(@x2, @x1, 4) + longmove(@x1, @xy, 2) + %101: + longmove(@xy, @x2, 2) + longmove(@x2, @x3, 2) + longmove(@x3, @xy, 2) + +' draw triangle + + fill(x1, y1, (x3 - x1) << 16 / (y1 - y3 + 1), (x2 - x1) << 16 / (y1 - y2 + 1), (x3 - x2) << 16 / (y2 - y3 + 1), y1 - y2, y1 - y3) + + +PUB finish + +'' Wait for any current graphics command to finish +'' use this to insure that it is safe to manually manipulate the bitmap + + setcommand(_loop, 0) 'make sure last command finished + + +PRI fill(x, y, da, db, db2, linechange, lines_minus_1) + + setcommand(_fill, @x) + + +PRI justify(string_ptr, justptr) | x + + x := (strsize(string_ptr) - 1) * text_xs * text_sp + text_xs * 5 - 1 + long[justptr] := -lookupz(text_just >> 2 & 3: 0, x >> 1, x, 0) + long[justptr][1] := -lookupz(text_just & 3: 0, text_ys << 3, text_ys << 4, 0) + + +PRI setcommand(cmd, argptr) + + command := cmd << 16 + argptr 'write command and pointer + repeat while command 'wait for command to be cleared, signifying receipt + + +CON + + ' Vector font primitives + + xa0 = %000 << 0 'x line start / arc center + xa1 = %001 << 0 + xa2 = %010 << 0 + xa3 = %011 << 0 + xa4 = %100 << 0 + xa5 = %101 << 0 + xa6 = %110 << 0 + xa7 = %111 << 0 + + ya0 = %0000 << 3 'y line start / arc center + ya1 = %0001 << 3 + ya2 = %0010 << 3 + ya3 = %0011 << 3 + ya4 = %0100 << 3 + ya5 = %0101 << 3 + ya6 = %0110 << 3 + ya7 = %0111 << 3 + ya8 = %1000 << 3 + ya9 = %1001 << 3 + yaA = %1010 << 3 + yaB = %1011 << 3 + yaC = %1100 << 3 + yaD = %1101 << 3 + yaE = %1110 << 3 + yaF = %1111 << 3 + + xb0 = %000 << 7 'x line end + xb1 = %001 << 7 + xb2 = %010 << 7 + xb3 = %011 << 7 + xb4 = %100 << 7 + xb5 = %101 << 7 + xb6 = %110 << 7 + xb7 = %111 << 7 + + yb0 = %0000 << 10 'y line end + yb1 = %0001 << 10 + yb2 = %0010 << 10 + yb3 = %0011 << 10 + yb4 = %0100 << 10 + yb5 = %0101 << 10 + yb6 = %0110 << 10 + yb7 = %0111 << 10 + yb8 = %1000 << 10 + yb9 = %1001 << 10 + ybA = %1010 << 10 + ybB = %1011 << 10 + ybC = %1100 << 10 + ybD = %1101 << 10 + ybE = %1110 << 10 + ybF = %1111 << 10 + + ax1 = %0 << 7 'x arc radius + ax2 = %1 << 7 + + ay1 = %00 << 8 'y arc radius + ay2 = %01 << 8 + ay3 = %10 << 8 + ay4 = %11 << 8 + + a0 = %0000 << 10 'arc start/length + a1 = %0001 << 10 'bits[1..0] = start (0..3 = 0°, 90°, 180°, 270°) + a2 = %0010 << 10 'bits[3..2] = length (0..3 = 360°, 270°, 180°, 90°) + a3 = %0011 << 10 + a4 = %0100 << 10 + a5 = %0101 << 10 + a6 = %0110 << 10 + a7 = %0111 << 10 + a8 = %1000 << 10 + a9 = %1001 << 10 + aA = %1010 << 10 + aB = %1011 << 10 + aC = %1100 << 10 + aD = %1101 << 10 + aE = %1110 << 10 + aF = %1111 << 10 + + fline = %0 << 14 'line command + farc = %1 << 14 'arc command + + more = %1 << 15 'another arc/line + + +DAT + +' Color codes + +colors long %%0000000000000000 + long %%1111111111111111 + long %%2222222222222222 + long %%3333333333333333 + +' Round pixel recipes + +pixels byte %00000000,%00000000,%00000000,%00000000 '0,1,2,3 + byte %00000000,%00000000,%00000010,%00000101 '4,5,6,7 + byte %00001010,%00001010,%00011010,%00011010 '8,9,A,B + byte %00110100,%00111010,%01110100,%01110100 'C,D,E,F + +' Vector font - standard ascii characters ($21-$7E) + +font word fline + xa2 + yaC + xb2 + yb7 + more '! + word fline + xa2 + ya5 + xb2 + yb4 + + word fline + xa1 + yaD + xb1 + ybC + more '" + word fline + xa3 + yaD + xb3 + ybC + + word fline + xa1 + yaA + xb1 + yb6 + more '# + word fline + xa3 + yaA + xb3 + yb6 + more + word fline + xa0 + ya9 + xb4 + yb9 + more + word fline + xa0 + ya7 + xb4 + yb7 + + word farc + xa2 + ya9 + a9 + ax2 + ay1 + more '$ + word farc + xa2 + ya7 + aB + ax2 + ay1 + more + word fline + xa0 + ya6 + xb2 + yb6 + more + word fline + xa2 + yaA + xb4 + ybA + more + word fline + xa2 + yaA + xb2 + ybB + more + word fline + xa2 + ya6 + xb2 + yb5 + + word farc + xa1 + yaA + a0 + ax1 + ay1 + more '% + word farc + xa3 + ya6 + a0 + ax1 + ay1 + more + word fline + xa0 + ya6 + xb4 + ybA + + word farc + xa2 + yaA + a7 + ax1 + ay1 + more '& + word farc + xa2 + ya7 + a5 + ax2 + ay2 + more + word fline + xa1 + yaA + xb4 + yb5 + + word fline + xa2 + yaD + xb2 + ybC ' ' + + word farc + xa3 + ya9 + aD + ax1 + ay4 + more '( + word farc + xa3 + ya7 + aE + ax1 + ay4 + more + word fline + xa2 + ya7 + xb2 + yb9 + + word farc + xa1 + ya9 + aC + ax1 + ay4 + more ') + word farc + xa1 + ya7 + aF + ax1 + ay4 + more + word fline + xa2 + ya7 + xb2 + yb9 + + word fline + xa4 + ya6 + xb0 + ybA + more '* + word fline + xa0 + ya6 + xb4 + ybA + more + word fline + xa2 + yaB + xb2 + yb5 + + word fline + xa0 + ya8 + xb4 + yb8 + more '+ + word fline + xa2 + yaA + xb2 + yb6 + + word fline + xa2 + ya4 + xb1 + yb3 ', + + word fline + xa0 + ya8 + xb4 + yb8 '- + + word fline + xa2 + ya5 + xb2 + yb4 '. + + word fline + xa0 + ya4 + xb4 + ybC '/ + + word farc + xa2 + ya8 + a0 + ax2 + ay4 '0 + + word fline + xa0 + ya4 + xb4 + yb4 + more '1 + word fline + xa2 + ya4 + xb2 + ybC + more + word fline + xa0 + yaA + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more '2 + word farc + xa2 + yaA + aF + ax2 + ay3 + more + word farc + xa2 + ya4 + aD + ax2 + ay3 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa2 + yaA + a7 + ax2 + ay2 + more '3 + word farc + xa2 + ya6 + a6 + ax2 + ay2 + + word fline + xa2 + yaC + xb0 + yb7 + more '4 + word fline + xa0 + ya7 + xb4 + yb7 + more + word fline + xa3 + ya4 + xb3 + yb8 + + word farc + xa2 + ya6 + aB + ax2 + ay2 + more '5 + word fline + xa4 + yaC + xb0 + ybC + more + word fline + xa0 + yaC + xb0 + yb8 + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + ya4 + xb2 + yb4 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more '6 + word farc + xa2 + ya8 + aD + ax2 + ay4 + more + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa2 + yaC + xb3 + ybC + + word fline + xa0 + yaC + xb4 + ybC + more '7 + word fline + xa1 + ya4 + xb4 + ybC + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more '8 + word farc + xa2 + yaA + a0 + ax2 + ay2 + + word farc + xa2 + yaA + a0 + ax2 + ay2 + more '9 + word farc + xa2 + ya8 + aF + ax2 + ay4 + more + word fline + xa4 + ya8 + xb4 + ybA + more + word fline + xa1 + ya4 + xb2 + yb4 + + word fline + xa2 + ya6 + xb2 + yb7 + more ': + word fline + xa2 + yaA + xb2 + yb9 + + word fline + xa2 + ya4 + xb1 + yb3 + more '; + word fline + xa2 + ya8 + xb2 + yb7 + + word fline + xa0 + ya8 + xb4 + ybA + more '< + word fline + xa0 + ya8 + xb4 + yb6 + + word fline + xa0 + yaA + xb4 + ybA + more '= + word fline + xa0 + ya6 + xb4 + yb6 + + word fline + xa4 + ya8 + xb0 + ybA + more '> + word fline + xa4 + ya8 + xb0 + yb6 + + word farc + xa2 + yaB + a8 + ax2 + ay1 + more '? + word farc + xa3 + yaB + aF + ax1 + ay2 + more + word farc + xa3 + ya7 + aD + ax1 + ay2 + more + word fline + xa2 + ya5 + xb2 + yb4 + + word farc + xa2 + ya8 + a0 + ax1 + ay1 + more '@ + word farc + xa2 + ya8 + a4 + ax2 + ay3 + more + word farc + xa3 + ya8 + aF + ax1 + ay1 + more + word farc + xa2 + ya6 + aF + ax2 + ay1 + more + word fline + xa3 + ya7 + xb3 + yb9 + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'A + word fline + xa0 + ya4 + xb0 + ybA + more + word fline + xa4 + ya4 + xb4 + ybA + more + word fline + xa0 + ya8 + xb4 + yb8 + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'B + word farc + xa2 + ya6 + aB + ax2 + ay2 + more + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'C + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + + word farc + xa2 + yaA + aC + ax2 + ay2 + more 'D + word farc + xa2 + ya6 + aF + ax2 + ay2 + more + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa4 + ya6 + xb4 + ybA + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa0 + yaC + xb2 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'E + word fline + xa0 + ya4 + xb4 + yb4 + more + word fline + xa0 + ya8 + xb3 + yb8 + more + word fline + xa0 + yaC + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'F + word fline + xa0 + ya8 + xb3 + yb8 + more + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'G + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya4 + xb4 + yb7 + more + word fline + xa3 + ya7 + xb4 + yb7 + + word fline + xa0 + ya4 + xb0 + ybC + more 'H + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa0 + ya8 + xb4 + yb8 + + word fline + xa2 + ya4 + xb2 + ybC + more 'I + word fline + xa0 + ya4 + xb4 + yb4 + more + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'J + word fline + xa4 + ya6 + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'K + word fline + xa4 + yaC + xb0 + yb8 + more + word fline + xa4 + ya4 + xb0 + yb8 + + word fline + xa0 + ya4 + xb0 + ybC + more 'L + word fline + xa0 + ya4 + xb4 + yb4 + + word fline + xa0 + ya4 + xb0 + ybC + more 'M + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa2 + ya8 + xb0 + ybC + more + word fline + xa2 + ya8 + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'N + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa4 + ya4 + xb0 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more '0 + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya6 + xb4 + ybA + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'P + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'Q + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya6 + xb4 + ybA + more + word fline + xa2 + ya6 + xb4 + yb3 + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'R + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + more + word fline + xa4 + ya4 + xb2 + yb8 + + word farc + xa2 + yaA + a4 + ax2 + ay2 + more 'S + word farc + xa2 + ya6 + a6 + ax2 + ay2 + + word fline + xa2 + ya4 + xb2 + ybC + more 'T + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'U + word fline + xa0 + ya6 + xb0 + ybC + more + word fline + xa4 + ya6 + xb4 + ybC + + word fline + xa2 + ya4 + xb0 + ybC + more 'V + word fline + xa2 + ya4 + xb4 + ybC + + word fline + xa0 + yaC + xb0 + yb4 + more 'W + word fline + xa4 + yaC + xb4 + yb4 + more + word fline + xa2 + ya8 + xb0 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb4 + + word fline + xa4 + ya4 + xb0 + ybC + more 'X + word fline + xa0 + ya4 + xb4 + ybC + + word fline + xa0 + yaC + xb2 + yb8 + more 'Y + word fline + xa4 + yaC + xb2 + yb8 + more + word fline + xa2 + ya4 + xb2 + yb8 + + word fline + xa0 + yaC + xb4 + ybC + more 'Z + word fline + xa0 + ya4 + xb4 + ybC + more + word fline + xa0 + ya4 + xb4 + yb4 + + word fline + xa2 + yaD + xb2 + yb3 + more '[ + word fline + xa2 + yaD + xb4 + ybD + more + word fline + xa2 + ya3 + xb4 + yb3 + + word fline + xa4 + ya4 + xb0 + ybC '\ + + word fline + xa2 + yaD + xb2 + yb3 + more '[ + word fline + xa2 + yaD + xb0 + ybD + more + word fline + xa2 + ya3 + xb0 + yb3 + + word fline + xa2 + yaA + xb0 + yb6 + more '^ + word fline + xa2 + yaA + xb4 + yb6 + + word fline + xa0 + ya1 + xa4 + yb1 '_ + + word fline + xa1 + ya9 + xb3 + yb7 '` + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'a + word fline + xa4 + ya4 + xb4 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'b + word fline + xa0 + ya4 + xb0 + ybC + + word farc + xa2 + ya6 + a9 + ax2 + ay2 + more 'c + word fline + xa2 + ya4 + xb4 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'd + word fline + xa4 + ya4 + xb4 + ybC + + word farc + xa2 + ya6 + a4 + ax2 + ay2 + more 'e + word fline + xa0 + ya6 + xb4 + yb6 + more + word fline + xa2 + ya4 + xb4 + yb4 + + word farc + xa4 + yaA + aD + ax2 + ay2 + more 'f + word fline + xa0 + ya8 + xb4 + yb8 + more + word fline + xa2 + ya4 + xb2 + ybA + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'g + word farc + xa2 + ya3 + aF + ax2 + ay2 + more + word fline + xa4 + ya3 + xb4 + yb8 + more + word fline + xa1 + ya1 + xb2 + yb1 + + word farc + xa2 + ya6 + a8 + ax2 + ay2 + more 'h + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa4 + ya4 + xb4 + yb6 + + word fline + xa1 + ya4 + xb3 + yb4 + more 'i + word fline + xa2 + ya4 + xb2 + yb8 + more + word fline + xa1 + ya8 + xb2 + yb8 + more + word fline + xa2 + yaB + xb2 + ybA + + word farc + xa0 + ya3 + aF + ax2 + ay2 + more 'j + word fline + xa2 + ya3 + xb2 + yb8 + more + word fline + xa1 + ya8 + xb2 + yb8 + more + word fline + xa2 + yaB + xb2 + ybA + + word fline + xa0 + ya4 + xb0 + ybC + more 'k + word fline + xa0 + ya6 + xb2 + yb6 + more + word fline + xa2 + ya6 + xb4 + yb8 + more + word fline + xa2 + ya6 + xb4 + yb4 + + word fline + xa1 + ya4 + xb3 + yb4 + more 'l + word fline + xa2 + ya4 + xb2 + ybC + more + word fline + xa1 + yaC + xb2 + ybC + + word farc + xa1 + ya7 + a8 + ax1 + ay1 + more 'm + word farc + xa3 + ya7 + a8 + ax1 + ay1 + more + word fline + xa0 + ya4 + xb0 + yb8 + more + word fline + xa2 + ya4 + xb2 + yb7 + more + word fline + xa4 + ya4 + xb4 + yb7 + + word farc + xa2 + ya6 + a8 + ax2 + ay2 + more 'n + word fline + xa0 + ya4 + xb0 + yb8 + more + word fline + xa4 + ya4 + xb4 + yb6 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 'o + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'p + word fline + xa0 + ya1 + xb0 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'q + word fline + xa4 + ya1 + xb4 + yb8 + + word farc + xa2 + ya7 + a8 + ax2 + ay1 + more 'r + word fline + xa0 + ya4 + xb0 + yb8 + + word farc + xa2 + ya7 + a9 + ax2 + ay1 + more 's + word farc + xa2 + ya5 + aB + ax2 + ay1 + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb8 + + word farc + xa4 + ya6 + aE + ax2 + ay2 + more 't + word fline + xa0 + ya8 + xb4 + yb8 + more + word fline + xa2 + ya6 + xb2 + ybA + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'u + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa4 + ya4 + xb4 + yb8 + + word fline + xa0 + ya8 + xb2 + yb4 + more 'v + word fline + xa4 + ya8 + xb2 + yb4 + + word farc + xa1 + ya5 + aA + ax1 + ay1 + more 'w + word farc + xa3 + ya5 + aA + ax1 + ay1 + more + word fline + xa0 + ya5 + xb0 + yb8 + more + word fline + xa2 + ya5 + xb2 + yb6 + more + word fline + xa4 + ya5 + xb4 + yb8 + + word fline + xa0 + ya8 + xb4 + yb4 + more 'x + word fline + xa0 + ya4 + xb4 + yb8 + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'y + word farc + xa2 + ya3 + aF + ax2 + ay2 + more + word fline + xa4 + ya3 + xb4 + yb8 + more + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa1 + ya1 + xb2 + yb1 + + word fline + xa0 + ya8 + xb4 + yb8 + more 'z + word fline + xa4 + ya8 + xb0 + yb4 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa3 + yaA + aD + ax1 + ay3 + more '{ + word farc + xa1 + ya6 + aC + ax1 + ay2 + more + word farc + xa1 + yaA + aF + ax1 + ay2 + more + word farc + xa3 + ya6 + aE + ax1 + ay3 + + word fline + xa2 + ya3 + xb2 + ybD '| + + word farc + xa1 + yaA + aC + ax1 + ay3 + more '} + word farc + xa3 + ya6 + aD + ax1 + ay2 + more + word farc + xa3 + yaA + aE + ax1 + ay2 + more + word farc + xa1 + ya6 + aF + ax1 + ay3 + + word farc + xa1 + ya8 + a8 + ax1 + ay1 + more '~ + word farc + xa3 + ya8 + aA + ax1 + ay1 + +' Vector font - custom characters ($7F+) + + word fline + xa2 + ya9 + xb0 + yb4 + more 'delta + word fline + xa2 + ya9 + xb4 + yb4 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa2 + ya7 + a8 + ax2 + ay2 + more 'omega + word farc + xa1 + ya7 + aE + ax1 + ay2 + more + word farc + xa3 + ya7 + aF + ax1 + ay2 + more + word fline + xa1 + ya5 + xb1 + yb4 + more + word fline + xa3 + ya5 + xb3 + yb4 + more + word fline + xa0 + ya4 + xb1 + yb4 + more + word fline + xa4 + ya4 + xb3 + yb4 + + word farc + xa2 + ya8 + a0 + ax1 + ay1 'bullet + +CON fx = 3 'number of custom characters + +DAT + +'************************************* +'* Assembly language graphics driver * +'************************************* + + org +' +' +' Graphics driver - main loop +' +loop rdlong t1,par wz 'wait for command + if_z jmp #loop + + movd :arg,#arg0 'get 8 arguments + mov t2,t1 + mov t3,#8 +:arg rdlong arg0,t2 + add :arg,d0 + add t2,#4 + djnz t3,#:arg + + wrlong zero,par 'zero command to signify received + + call #setd 'set dx,dy from arg0,arg1 + + ror t1,#16+2 'lookup command address + add t1,#jumps + movs :table,t1 + rol t1,#2 + shl t1,#3 +:table mov t2,0 + shr t2,t1 + and t2,#$FF + jmp t2 'jump to command + + +jumps byte 0 '0 + byte setup_ '1 + byte color_ '2 + byte width_ '3 + byte plot_ '4 + byte line_ '5 + byte arc_ '6 + byte vec_ '7 + byte vecarc_ '8 +' byte pix_ '9 +' byte pixarc_ 'A + byte text_ 'B + byte textarc_ 'C + byte textmode_ 'D + byte fill_ 'E + byte lineseq_ + byte loop 'F +' +' +' setup(x_tiles, y_tiles*16, x_origin, y_origin, base_ptr) bases_ptr, slices_ptr +' +setup_ mov xlongs,arg0 'set xlongs, ylongs + mov ylongs,arg1 + mov xorigin,arg2 'set xorigin, yorigin + mov yorigin,arg3 + mov basesptr,arg5 'set pointers + mov slicesptr,arg6 + + jmp #loop +' +' +' color(c) +' +color_ mov pcolor,arg0 'set pixel color + + jmp #loop +' +' +' width(w) pixel_passes +' +width_ mov pwidth,arg0 'set pixel width + mov passes,arg1 'set pixel passes + + jmp #loop +' +' +' plot(x, y) +' +plot_ call #plotd + + jmp #loop +' +' +' line(x, y) +' +line_ call #linepd + + jmp #loop +' +' +' arc(x, y, xr, yr, angle, anglestep, iterations, mode) +' +arc_ and arg7,#3 'limit mode + +:loop call #arca 'get arc dx,dy + + cmp arg7,#1 wz 'if not mode 1, set px,py + if_nz mov px,dx + if_nz mov py,dy + + tjz arg6,#loop 'if no points exit with new px,py + + cmp arg7,#3 wz 'if mode 3, set center + if_z call #setd + + test arg7,#1 wz 'if mode 0 or 2, plot point + if_z call #plotp + + test arg7,#1 wz 'if mode 1 or 3, plot line + if_nz call #linepd + + cmp arg7,#2 wz 'if mode 2, set mode 1 + if_z mov arg7,#1 + + add arg4,arg5 'step angle + djnz arg6,#:loop 'loop if more iterations + + jmp #loop +' +' +' vec(x, y, vecscale, vecangle, vecdef_ptr) +' vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) +' +' vecdef: word $8000/$4000+angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) +' word length 'vector length +' ... 'more vectors +' ... +' word 0 'end of definition +' +vecarc_ call #arcmod + +vec_ tjz arg2,#loop 'if scale 0, exit + +:loop rdword t7,arg4 wz 'get vector mode+angle + add arg4,#2 + + if_z jmp #loop 'if mode+angle 0, exit + + rdword t1,arg4 'get vector length + add arg4,#2 + + abs t2,arg2 wc 'add/sub vector angle to/from angle + mov t6,arg3 + sumc t6,t7 + + call #multiply 'multiply length by scale + add t1,#$80 'round up 1/2 lsb + shr t1,#8 + + mov t4,t1 'get arc dx,dy + mov t5,t1 + call #arcd + + test t7,h8000 wc 'plot pixel or draw line? + if_nc call #plotd + test t7,h8000 wc + if_c call #linepd + + jmp #:loop 'get next vector + +' +' +' pix(x, y, pixrot, pixdef_ptr) +' pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) +' +' pixdef: word +' byte xwords, ywords, xorigin, yorigin +' word %%xxxxxxxx,%%xxxxxxxx +' word %%xxxxxxxx,%%xxxxxxxx +' word %%xxxxxxxx,%%xxxxxxxx +' ... +' +pixarc_ call #arcmod + +pix_ +{ + mov t6,pcolor 'save color + + mov px,dx 'get center into px,py + mov py,dy + + mov sy,pwidth 'get actual pixel width + add sy,#1 + + rdbyte dx,arg3 'get dimensions into dx,dy + add arg3,#1 + rdbyte dy,arg3 + add arg3,#1 + + rdbyte t1,arg3 'get origin and adjust px,py + add arg3,#1 + rdbyte t2,arg3 + add arg3,#1 + neg t2,t2 + sub t2,#1 + add t2,dy + mov t3,sy +:adjust test arg2,#%001 wz + test arg2,#%110 wc + if_z sumnc px,t1 + if_nz sumc py,t1 + test arg2,#%010 wc + if_nz sumnc px,t2 + if_z sumnc py,t2 + djnz t3,#:adjust + +:yline mov sx,#0 'plot entire pix + mov t3,dx +:xword rdword t4,arg3 'read next pix word + add arg3,#2 + shl t4,#16 + mov t5,#8 +:xpixel rol t4,#2 'plot pixel within word + test t4,#1 wc 'set color + muxc pcolor,color1 + test t4,#2 wc + muxc pcolor,color2 wz '(z=1 if color=0) + if_nz call #plotp + test arg2,#%001 wz 'update px,py for next x + test arg2,#%110 wc + if_z sumc px,sy + if_nz sumnc py,sy + add sx,sy + djnz t5,#:xpixel 'another x pixel? + djnz t3,#:xword 'another x word? + if_z sumnc px,sx 'update px,py for next y + if_nz sumc py,sx + test arg2,#%010 wc + if_nz sumc px,sy + if_z sumc py,sy + djnz dy,#:yline 'another y line? + + mov pcolor,t6 'restore color +} + jmp #loop +' +' +' text(x, y, @string) justx, justy +' textarc(x, y, xr, yr, angle, @string) justx, justy +' +textarc_ call #arcmod + +text_ add arg3,arg0 'add x into justx + add arg4,arg1 'add y into justy + +:chr rdbyte t1,arg2 wz 'get chr + add arg2,#1 + + if_z jmp #loop 'if 0, done + + sub t1,#$21 'if chr out of range, skip + cmp t1,#$7F-$21+fx wc + if_nc jmp #:skip + + mov arg5,fontptr 'scan font for chr definition +:scan tjz t1,#:def + rdword t2,arg5 + add arg5,#2 + test t2,h8000 wc + if_nc sub t1,#1 + jmp #:scan + +:def rdword t7,arg5 'get font definition word + add arg5,#2 + + call #fontxy 'extract initial x,y + + test t7,#$80 wc 'arc or line? + if_nc jmp #:line + + + mov t2,textsx 'arc, extract x radius + mov t3,#%0001_0001_1 + call #fontb + mov t4,t1 + + mov t2,textsy 'extract y radius + mov t3,#%0010_0011_1 + call #fontb + mov t5,t1 + + mov t2,#1 'extract starting angle + mov t3,#%0010_0011_0 + call #fontb + shl t1,#11 + + mov t6,t1 'extract angle sweep + mov t3,#%0010_0011_0 + call #fontb + neg arg6,t1 + shl arg6,#4 + add arg6,#65 + + call #arcd 'plot initial arc point + call #plotd + +:arc call #arcd 'connect subsequent arc points with lines + call #linepd + add t6,#$80 + djnz arg6,#:arc + + jmp #:more + + +:line call #plotd 'line, plot initial x,y + + call #fontxy 'extract terminal x,y + + call #linepd 'draw line + + +:more test t7,#$02 wc 'more font definition? + if_c jmp #:def + +:skip mov t1,textsp 'advance x to next chr position + mov t2,textsx + call #multiply + add arg3,t1 + + jmp #:chr 'get next chr + + +fontxy mov t2,textsx 'extract x + mov t3,#%0011_0111_0 + call #fontb + mov arg0,t1 + add arg0,arg3 + + mov t2,textsy 'extract y + mov t3,#%0100_1111_0 + call #fontb + mov arg1,t1 + add arg1,arg4 + +setd mov dx,xorigin 'set dx,dy from arg0,arg1 + add dx,arg0 + mov dy,yorigin + sub dy,arg1 +setd_ret +fontxy_ret ret + + +fontb mov t1,t7 'extract bitrange from font word + shr t3,#1 wc + and t1,t3 + if_c add t1,#1 + shr t3,#4 + shr t7,t3 + + shl t1,#32-4 'multiply t1[3..0] by t2 + mov t3,#4 +:loop shl t1,#1 wc + if_c add t1,t2 + djnz t3,#:loop + +fontb_ret ret +' +' +' textmode(x_scale, y_scale, spacing, justification) +' +textmode_ mov textsx,arg0 'set text x scale + mov textsy,arg1 'set text y scale + mov textsp,arg2 'set text spacing + + jmp #loop +' +' +' fill(x, y, da, db, db2, linechange, lines_minus_1) +' +fill_ + + shl dx,#16 'get left and right fractions + or dx,h8000 + mov t1,dx + + mov t2,xlongs 'get x pixels + shl t2,#4 + + add arg6,#1 'pre-increment line counter + +:yloop add dx,arg2 'adjust left and right fractions + add t1,arg3 + + cmps dx,t1 wc 'get left and right integers + if_c mov base0,dx + if_c mov base1,t1 + if_nc mov base0,t1 + if_nc mov base1,dx + sar base0,#16 + sar base1,#16 + + cmps base0,t2 wc 'left out of range? + if_c cmps hFFFFFFFF,base1 wc 'right out of range? + if_c cmp dy,ylongs wc 'y out of range? + if_nc jmp #:skip 'if any, skip + + mins base0,#0 'limit left and right + maxs base1,t2 wc + if_nc sub base1,#1 + + shl base0,#1 'make left mask + neg mask0,#1 + shl mask0,base0 + shr base0,#5 + + shl base1,#1 'make right mask + xor base1,#$1E + neg mask1,#1 + shr mask1,base1 + shr base1,#5 + + sub base1,base0 wz 'ready long count + add base1,#1 + + if_z and mask0,mask1 'if single long, merge masks + + shl base0,#1 'get long base + add base0,basesptr + rdword base0,base0 + shl dy,#2 + add base0,dy + shr dy,#2 + + mov bits0,mask0 'ready left mask +:xloop mov bits1,pcolor 'make color mask + and bits1,bits0 + rdlong pass,base0 'read-modify-write long + andn pass,bits0 + or pass,bits1 + wrlong pass,base0 + shl ylongs,#2 'advance to next long + add base0,ylongs + shr ylongs,#2 + cmp base1,#2 wz 'one more? + if_nz neg bits0,#1 'if not, ready full mask + if_z mov bits0,mask1 'if one more, ready right mask + djnz base1,#:xloop 'loop if more longs + +:skip sub arg5,#1 wc 'delta change? + if_c mov arg3,arg4 'if so, set new deltas +:same + add dy,#1 'adjust y + djnz arg6,#:yloop 'another y? + + jmp #loop +' +' lineseq +' +lineseq_ + mov t6,pcolor 'save color +:loop1 rdbyte t7,arg1 wz + add arg1,#1 + if_z jmp #:end + + rdbyte pcolor,arg1 + add arg1,#1 + + mov t5, pcolor + shl t5, #2 + or pcolor, t5 + + mov t5, pcolor + shl t5, #4 + or pcolor, t5 + + mov t5, pcolor + shl t5, #8 + or pcolor, t5 + + mov t5, pcolor + shl t5, #16 + or pcolor, t5 + + call #readseq + call #plotd + sub t7,#1 + +:loop2 call #readseq + call #linepd + djnz t7, #:loop2 + jmp #:loop1 +:end + mov pcolor,t6 + jmp #loop + +' +' +' Plot line from px,py to dx,dy +' +linepd cmps dx,px wc, wr 'get x difference + negc sx,#1 'set x direction + + cmps dy,py wc, wr 'get y difference + negc sy,#1 'set y direction + + abs dx,dx 'make differences absolute + abs dy,dy + + cmp dx,dy wc 'determine dominant axis + if_nc tjz dx,#:last 'if both differences 0, plot single pixel + if_nc mov count,dx 'set pixel count + if_c mov count,dy + mov ratio,count 'set initial ratio + shr ratio,#1 + if_c jmp #:yloop 'x or y dominant? + + +:xloop call #plotp 'dominant x line + add px,sx + sub ratio,dy wc + if_c add ratio,dx + if_c add py,sy + djnz count,#:xloop + + jmp #:last 'plot last pixel + + +:yloop call #plotp 'dominant y line + add py,sy + sub ratio,dx wc + if_c add ratio,dy + if_c add px,sx + djnz count,#:yloop + +:last call #plotp 'plot last pixel + +linepd_ret ret +' +' +' Plot pixel at px,py +' +plotd mov px,dx 'set px,py to dx,dy + mov py,dy + +plotp tjnz pwidth,#wplot 'if width > 0, do wide plot + + mov t1,px 'compute pixel mask + shl t1,#1 + mov mask0,#%11 + shl mask0,t1 + shr t1,#5 + + cmp t1,xlongs wc 'if x or y out of bounds, exit + if_c cmp py,ylongs wc + if_nc jmp #plotp_ret + + mov bits0,pcolor 'compute pixel bits + and bits0,mask0 + + shl t1,#1 'get address of pixel long + add t1,basesptr + mov t2,py + rdword t1,t1 + shl t2,#2 + add t1,t2 + + rdlong t2,t1 'write pixel + andn t2,mask0 + or t2,bits0 + wrlong t2,t1 +plotp_ret +plotd_ret ret +' +' +' Plot wide pixel +' +wplot mov t1,py 'if y out of bounds, exit + add t1,#7 + mov t2,ylongs + add t2,#7+8 + cmp t1,t2 wc + if_nc jmp #plotp_ret + + mov t1,px 'determine x long pair + sub t1,#8 + sar t1,#4 + cmp t1,xlongs wc + muxc jumps,#%01 '(use jumps[1..0] to store writes) + add t1,#1 + cmp t1,xlongs wc + muxc jumps,#%10 + + test jumps,#%11 wz 'if x out of bounds, exit + if_z jmp #plotp_ret + + shl t1,#1 'get base pair + add t1,basesptr + rdword base1,t1 + sub t1,#2 + rdword base0,t1 + + mov t1,px 'determine pair shifts + shl t1,#1 + movs :shift1,t1 + xor :shift1,#7<<1 + add t1,#9<<1 + movs :shift0,t1 + test t1,#$F<<1 wz '(account for special case) + if_z andn jumps,#%01 + + mov pass,#0 'ready to plot slices + mov slice,slicesptr + +:loop rdlong mask0,slice 'get next slice + mov mask1,mask0 + +:shift0 shl mask0,#0 'position slice +:shift1 shr mask1,#0 + + mov bits0,pcolor 'colorize slice + and bits0,mask0 + mov bits1,pcolor + and bits1,mask1 + + mov t1,py 'plot lower slice + add t1,pass + cmp t1,ylongs wc + if_c call #wslice + + mov t1,py 'plot upper slice + test pwidth,#1 wc + subx t1,pass + cmp t1,ylongs wc + if_c call #wslice + + add slice,#4 'next slice + add pass,#1 + cmp pass,passes wz + if_nz jmp #:loop + + jmp #plotp_ret +' +' +' Plot wide pixel slice +' +wslice shl t1,#2 'ready long offset + + add base0,t1 'plot left slice + test jumps,#%01 wc + if_c rdlong t2,base0 + if_c andn t2,mask0 + if_c or t2,bits0 + if_c wrlong t2,base0 + + add base1,t1 'plot right slice + test jumps,#%10 wc + if_c rdlong t2,base1 + if_c andn t2,mask1 + if_c or t2,bits1 + if_c wrlong t2,base1 + + sub base0,t1 'restore bases + sub base1,t1 + +wslice_ret ret +' +' +' Get arc point from args and then move args 5..7 to 2..4 +' +arcmod call #arca 'get arc using first 5 args + + mov arg0,dx 'set arg0,arg1 + sub arg0,xorigin + mov arg1,yorigin + sub arg1,dy + + mov arg2,arg5 'move args 5..7 to 2..4 + mov arg3,arg6 + mov arg4,arg7 + +arcmod_ret ret +' +' +' Get arc dx,dy from arg0,arg1 +' +' in: arg0,arg1 = center x,y +' arg2/t4 = x length +' arg3/t5 = y length +' arg4/t6 = 13-bit angle +' +' out: dx,dy = arc point +' +arca mov t4,arg2 'use args + mov t5,arg3 + mov t6,arg4 + +arcd call #setd 'reset dx,dy to arg0,arg1 + + mov t1,t6 'get arc dx + mov t2,t4 + call #polarx + add dx,t1 + + mov t1,t6 'get arc dy + mov t2,t5 + call #polary + sub dy,t1 +arcd_ret +arca_ret ret +' +' +' Polar to cartesian +' +' in: t1 = 13-bit angle +' t2 = 16-bit length +' +' out: t1 = x|y +' +polarx add t1,sine_90 'cosine, add 90° for sine lookup +polary test t1,sine_180 wz 'get sine quadrant 3|4 into nz + test t1,sine_90 wc 'get sine quadrant 2|4 into c + negc t1,t1 'if sine quadrant 2|4, negate table offset + or t1,sine_table 'or in sine table address >> 1 + shl t1,#1 'shift left to get final word address + rdword t1,t1 'read sine/cosine word + call #multiply 'multiply sine/cosine by length to get x|y + add t1,h8000 'add 1/2 lsb to round up x|y fraction + shr t1,#16 'justify x|y integer + negnz t1,t1 'if sine quadrant 3|4, negate x|y +polary_ret +polarx_ret ret + +sine_90 long $0800 '90° bit +sine_180 long $1000 '180° bit +sine_table long $E000 >> 1 'sine table address shifted right +' +' +' Multiply +' +' in: t1 = 16-bit multiplicand (t1[31..16] must be 0) +' t2 = 16-bit multiplier +' +' out: t1 = 32-bit product +' +multiply mov t3,#16 + shl t2,#16 + shr t1,#1 wc + +:loop if_c add t1,t2 wc + rcr t1,#1 wc + djnz t3,#:loop + +multiply_ret ret + +' +' readseq +' +readseq + rdbyte t1,arg1 + add arg1,#1 + shl t1,#2 + add t1,arg0 + rdword dx,t1 + add t1,#2 + rdword dy,t1 + shl dx,#16 + shl dy,#16 + sar dx,#16 + sar dy,#16 + add dx,xorigin + add dy,yorigin +readseq_ret ret + +' +' +' Defined data +' +zero long 0 'constants +d0 long $200 +h8000 long $8000 +hFFFFFFFF long $FFFFFFFF +hFFFF0000 long $FFFF0000 +color1 long %%1111111111111111 +color2 long %%2222222222222222 + +fontptr long 0 'font pointer (set before cognew command) + +pcolor long %%1111111111111111 'pixel color +pwidth long 0 'pixel width +passes long 1 'pixel passes +textsx long 1 'text scale x +textsy long 1 'text scale y +textsp long 6 'text spacing +' +' +' Undefined data +' +t1 res 1 'temps +t2 res 1 +t3 res 1 +t4 res 1 +t5 res 1 +t6 res 1 +t7 res 1 + +arg0 res 1 'arguments passed from high-level +arg1 res 1 +arg2 res 1 +arg3 res 1 +arg4 res 1 +arg5 res 1 +arg6 res 1 +arg7 res 1 + +basesptr res 1 'pointers +slicesptr res 1 + +xlongs res 1 'bitmap metrics +ylongs res 1 +xorigin res 1 +yorigin res 1 + +dx res 1 'line/plot coordinates +dy res 1 +px res 1 +py res 1 + +sx res 1 'line +sy res 1 +count res 1 +ratio res 1 + +pass res 1 'plot +slice res 1 +base0 res 1 +base1 res 1 +mask0 res 1 +mask1 res 1 +bits0 res 1 +bits1 res 1 + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/source/boulder/bellatrix/Boulderdash_Tile_TV.spin b/source/boulder/bellatrix/Boulderdash_Tile_TV.spin new file mode 100644 index 0000000..d71bb49 --- /dev/null +++ b/source/boulder/bellatrix/Boulderdash_Tile_TV.spin @@ -0,0 +1 @@ +'' 2-bit paletted tile-based video driver'' Based on the NTSC Spectrum-like TV Video Driver'' ──────────────────────────────────────────────────────────────────────────────────'' Version story:'''' 2007-11-25 2.0 Tiled Version (Spork Frog)'' 2007-12-05 1.0 First version (José Luis Cebrián)'' 2009-11-12 Halved tile horizontal resolution (Héctor Peraza)'' to eliminate redundant pixel pairs'' (BoulderDash uses 8x16 tiles).'' This also halves tile memory requirements.'' Fixed vertical sync pulse generation.'' 2009-11-13 Changed pixel clock settings (Héctor Peraza)'' in order to display 20 tiles per line,'' as in the classic C64 BoulderDash.'' 2009-11-14 Reverse pixel order before waitvid (Héctor Peraza)'' to avoid having to define mirrored tiles.'' 2009-11-15 Added an optional status line. (Héctor Peraza)'' 2009-11-17 Video config parameters can be passed (Héctor Peraza)'' on driver startup, to allow for different'' configurations and/or platforms.'' 2009-11-18 Implemented PAL mode. Color seems to (Héctor Peraza)'' be a bit off in PAL mode.'' 2009-12-05 Added the possibilty to halve tile (Héctor Peraza)'' height (we need that for the title screen,'' since it has text on the bottom part'' and characters are half-size)'' '' ──────────────────────────────────────────────────────────────────────────────────'' This code is in the public domain. Feel free to use it in any way you like.'''' The screen for this driver is composed of two major parts:'''' 1. Tile map'' Each of these entries is 1 byte long, representing the tile number.'' There are 880 words total for a 40 by 22 tile screen. The displayed'' area is 20 x 12 in NTSC mode, 20 x 14 in PAL mode.'''' 2. Tiles'' Each tile is made up of 16 words with 2 bit color encoding on'' each tile. You can define as few or as many tiles as you want,'' but be sure not to use any tiles that you don't define.'''' There is also an optional status line at the top of the screen that does not'' scroll with the rest. It is also composed of tiles, but these are only 8 pixels'' high. Two empty raster lines separate the status from the main screen. The'' foreground color can be set per character basis. '''' 80Mhz is *required* in order to output pixels fast enough.CON ' Border offset, to center the image HorizBorderOffset = 9 ' positive values move the screen to the right VertBorderOffset = 10 ' positive values move the screen down ' Counter Module Configuration ' • CTRMode - Operating mode (0001 for Video Mode) ' • PLLDiv - Divisor for the VCO frequency (111: use VCO value as-is) '┌─────────── CTRMode '│ ┌───── PLLDiv CTRA_TVGEN = %00001_111 ' NTSC Color frequency in Hz ' ' This is the 'base' clock rate for all our NTSC timings. At start, the ' driver will program the FRQA register to output at this rate. Our base ' clock value is 1/16 of the NTSC clock rate, or approximately 0.01746 µs. NTSC_ClockFreq = 3_579_545 ' NTSC Timings table ' Time Clocks Output ' Total horizontal timing: 63.5 µs 3638 ' Horizontal blanking period: 10.9 µs 624 ' Front porch: 1.5 µs 86 * Black ($02) ' Synchronizing pulse: 4.7 µs 269 * Blank ($00) ' Back porch: 4.7 µs 269 ' Breeze away: 0.6 µs 34 * Black ($02) ' Colour burst: 2.5 µs 144 * Y Hue ($8A) ' Wait to data: 1.6 µs 92 * Black ($02) ' Visible line 52.6 µs 3008 ' Left border 2.5 µs 146 * Black ($00) ' Pixel data 47.5 µs 2720 ' Character (x20) 2.4 µs 136 * Data ' Right border 2.6 µs 146 * Black ($00) ' Half visible line ¹ 20.8 µs 1195 ' ' Lines marked with * are the actual parts of a visible line as sent to the TV. ' ' ¹ The vertical sync pulse is a series of half lines with inverted horizontal sync ' pulses (the so-called equalization pulses). These half lines should have a length ' of 3638/2 = 1819 clocks (that is, a 624-clocks HSync followed by about 1195 clocks ' of visible data). VSCL_NTSC_FrontPorch = 85 VSCL_NTSC_SynchronizingPulse = 270 VSCL_NTSC_BackPorch = 34 + 144 + 92 VSCL_NTSC_BreezeAway = 34 VSCL_NTSC_ColourBurst = 144 VSCL_NTSC_WaitToData = 92 VSCL_NTSC_VisibleLine = 3008 VSCL_NTSC_HalfLine = 1192 ' NTSC Half line VSCL_NTSC_LeftBorder = 146 + HorizBorderOffset VSCL_NTSC_RightBorder = 146 - HorizBorderOffset VSCL_NTSC_Character = (17 << 12) + 136 ' Eight double-width pixels NTSC_VerticalLines = 262 - 9 NTSC_TopLine = (NTSC_VerticalLines + 192) / 2 - VertBorderOffset NTSC_BottomLine = (NTSC_VerticalLines - 192) / 2 - VertBorderOffset ' PAL Color frequency in Hz ' ' This is the 'base' clock rate for all the PAL timings. At start, the ' driver will program the FRQA register to output at this rate. Our base ' clock value is 1/16 of the PAL clock rate, or approximately 0.014097 µs PAL_ClockFreq = 4_433_618 ' PAL Timings table ' Time Clocks Output ' Total horizontal timing: 64.0 µs 4540 ' Horizontal blanking period: 12.0 µs 851 ' Front porch: 1.6 µs 113 * Black ($02) ' Synchronizing pulse: 4.7 µs 333 * Blank ($00) ' Back porch: 5.7 µs 404 ' Breeze away: 0.9 µs 64 * Black ($02) ' Colour burst: 2.3 µs 160 * Y Hue ($8A) ' Wait to data: 2.5 µs 180 * Black ($02) ' Visible line 52.0 µs 3689 ' Left border 3.4 µs 244 * Black ($00) ' Pixel data 45.1 µs 3200 ' Character (x20) 2.3 µs 160 * Data ' Right border 3.4 µs 245 * Black ($00) ' Half visible line ¹ 20.0 µs 1419 ' ' Lines marked with * are the actual parts of a visible line as sent to the TV. ' ' ¹ The vertical sync pulse is a series of half lines with inverted horizontal sync ' pulses (the so-called equalization pulses). These half lines should have a length ' of 4540/2 = 2270 clocks (that is, a 851-clocks HSync followed by about 1419 clocks ' of visible data). VSCL_PAL_FrontPorch = 114 VSCL_PAL_SynchronizingPulse = 332 VSCL_PAL_BackPorch = 64 + 160 + 180 VSCL_PAL_BreezeAway = 64 VSCL_PAL_ColourBurst = 160 VSCL_PAL_WaitToData = 180 VSCL_PAL_VisibleLine = 3689 VSCL_PAL_HalfLine = 1419 ' PAL Half line VSCL_PAL_LeftBorder = 244 + HorizBorderOffset VSCL_PAL_RightBorder = 245 - HorizBorderOffset VSCL_PAL_Character = (20 << 12) + 160 ' Eight double-width pixels PAL_VerticalLines = 312 - 9 PAL_TopLine = (PAL_VerticalLines + 224) / 2 - VertBorderOffset PAL_BottomLine = (PAL_VerticalLines - 224) / 2 - VertBorderOffset PUB Start(vParam)'' Starts the TV driver and begins the output of NTSC video.'' Uses a Cog.'''' Parameters:'' vParam → Array with video parameters:'' [0] → VCFG mode'' [1] → Pingroup for VCFG pins'' [2] → Pinmask for VCFG pins'' [3] → Pinmask for output pins'' [4] → Color standard: 0 = NTSC, 1 = PAL'' [5] → Tile map address'' [6] → Address of a vsync flag byte in HUB memory cognew(@Entry, vParam) DAT org $000 Entry jmp #StartDriver ' ───────────────────────────────────────── ' Data section ' ───────────────────────────────────────── ' Colors used in waitvid COLOR_SYNC long $00 ' Sync level is below black COLOR_BLACK long $02 COLOR_YHUE_NTSC long $8A ' NTSC color burst COLOR_YHUE_PAL_1 long $7A ' PAL swinging color burst COLOR_YHUE_PAL_2 long $AA ' " " " " COLOR_BORDER long $02 ' Black border ' The following constants are too big to use in-place, so we need to ' reserve some registers to put them here _ScreenSize long 40 * 28 ' Tile map size _NTSC_ClockFreq long NTSC_ClockFreq _VSCL_NTSC_Character long VSCL_NTSC_Character _VSCL_NTSC_VisibleLine long VSCL_NTSC_VisibleLine _VSCL_NTSC_HalfLine long VSCL_NTSC_HalfLine _PAL_ClockFreq long PAL_ClockFreq _VSCL_PAL_Character long VSCL_PAL_Character _VSCL_PAL_VisibleLine long VSCL_PAL_VisibleLine _VSCL_PAL_HalfLine long VSCL_PAL_HalfLine ' Other constants TrueWord long $FFFF ' ───────────────────────────────────────── ' Code section ' ─────────────────────────────────────────StartDriver ' Configure the Cog generators mov R0, PAR rdlong _VCFG_Mode, R0 add R0, #4 rdlong _VCFG_PinGroup, R0 add R0, #4 rdlong _VCFG_PinMask, R0 add R0, #4 rdlong _PortMask, R0 add R0, #4 rdlong VideoMode, R0 add R0, #4 rdlong ScreenPtr, R0 add R0, #4 rdlong VSyncPtr, R0 test VideoMode, #1 wz if_z mov _ClockFreq, _NTSC_ClockFreq if_nz mov _ClockFreq, _PAL_ClockFreq if_z mov _VSCL_Character, _VSCL_NTSC_Character if_nz mov _VSCL_Character, _VSCL_PAL_Character if_z mov _VSCL_VisibleLine, _VSCL_NTSC_VisibleLine if_nz mov _VSCL_VisibleLine, _VSCL_PAL_VisibleLine if_z mov _VSCL_HalfLine, _VSCL_NTSC_HalfLine if_nz mov _VSCL_HalfLine, _VSCL_PAL_HalfLine if_z mov _VSCL_LeftBorder, #VSCL_NTSC_LeftBorder if_nz mov _VSCL_LeftBorder, #VSCL_PAL_LeftBorder if_z mov _VSCL_RightBorder, #VSCL_NTSC_RightBorder if_nz mov _VSCL_RightBorder, #VSCL_PAL_RightBorder if_z mov _VSCL_FrontPorch, #VSCL_NTSC_FrontPorch if_nz mov _VSCL_FrontPorch, #VSCL_PAL_FrontPorch if_z mov _VSCL_SynchronizingPulse, #VSCL_NTSC_SynchronizingPulse if_nz mov _VSCL_SynchronizingPulse, #VSCL_PAL_SynchronizingPulse if_z mov _VSCL_BreezeAway, #VSCL_NTSC_BreezeAway if_nz mov _VSCL_BreezeAway, #VSCL_PAL_BreezeAway if_z mov _VSCL_ColourBurst, #VSCL_NTSC_ColourBurst if_nz mov _VSCL_ColourBurst, #VSCL_PAL_ColourBurst if_z mov _VSCL_BackPorch, #VSCL_NTSC_BackPorch if_nz mov _VSCL_BackPorch, #VSCL_PAL_BackPorch if_z mov _VSCL_WaitToData, #VSCL_NTSC_WaitToData if_nz mov _VSCL_WaitToData, #VSCL_PAL_WaitToData if_z mov _VerticalLines, #NTSC_VerticalLines if_nz mov _VerticalLines, #PAL_VerticalLines if_z mov _TopLine, #NTSC_TopLine if_nz mov _TopLine, #PAL_TopLine if_z mov _BottomLine, #NTSC_BottomLine if_nz mov _BottomLine, #PAL_BottomLine if_z mov _Burst1, COLOR_YHUE_NTSC if_nz mov _Burst1, COLOR_YHUE_PAL_1 if_z mov _Burst2, COLOR_YHUE_NTSC if_nz mov _Burst2, COLOR_YHUE_PAL_2 movs VCFG, _VCFG_PinMask ' VCFG'S = pinmask (pin31: 0000_0111 : pin24) movd VCFG, _VCFG_PinGroup ' VCFG'D = pingroup (grp. 3 i.e. pins 24-31) movi VCFG, _VCFG_Mode ' Baseband video on bottom nibble, 2-bit color, enable chroma on baseband or DIRA, _PortMask ' Setup the port mask for DAC access (set DAC pins to output) movi CTRA, #CTRA_TVGEN ' Setup the Counter Module Generator A mov R1, _ClockFreq ' R1 := Video Clock Frequency in Hz rdlong R2, #0 ' R2 := Current CPU Clock Frequency in Hz call #Divide ' R3 := R1÷R2 (fractional part) mov FRQA, R3 ' Setup the Counter Module Generator frequency mov phaseflip, #0 ' Frame loop :Frame mov LineCounter, _VerticalLines ' LineCounter := Number of vertical lines mov CharacterRows, #0 ' Copy the screen parameters to local variables in Cog memory mov AttribPtr, ScreenPtr mov TilePtr, AttribPtr add TilePtr, _ScreenSize rdlong COLORS, TilePtr add TilePtr, #4 rdlong OffsetX, TilePtr mov OffsetY, OffsetX shr OffsetX, #16 and OffsetY, TrueWord add TilePtr, #4 rdlong Status, TilePtr add TilePtr, #4 mov StatusPtr, TilePtr add TilePtr, #20*2 ' Y Offset Calculations mov R0, OffsetY test Status, #2 wz if_z and OffsetY, #%1111 if_nz and OffsetY, #%111 shl OffsetY, #1 mov CharacterRows, OffsetY if_z shr R0, #4 if_nz shr R0, #3 add R0, #1:AddLoop add AttribPtr, #40 djnz R0, #:AddLoop sub AttribPtr, #40 ' X Offset Calculations mov R0, OffsetX and OffsetX, #%111 shl OffsetX, #1 mov R5, #16 sub R5, OffsetX shr R0, #3 add AttribPtr, R0 ' Status Line row count mov R6, #0 ' Visible line loop:ScanLine call #HSync ' Check if the current line is in the top or bottom border cmp LineCounter, _BottomLine wc if_c jmp #:EmptyLine cmp LineCounter, _TopLine wc if_nc jmp #:CheckStat jmp #:DataLine:CheckStat test Status, #1 wz if_z jmp #:EmptyLine mov R0, _TopLine add R0, #10 cmp LineCounter, R0 wc if_nc jmp #:EmptyLine cmp R6, #16 wz if_z jmp #:EmptyLine ' Draw the status line mov VSCL, _VSCL_LeftBorder waitvid COLOR_BORDER, #0 ' Character rendering loop mov VSCL, _VSCL_Character mov R0, #20 ' R0 := Character counter (per line) mov R1, StatusPtr ' R1 := Pointer to status line mov R4, R1 add R4, R0 ' R4 := Pointer to foreground color:StatusChar rdbyte R3, R1 ' R3 := Tile description add R1, #1 ' Advance the attribute pointer for the next character shl R3, #4 ' Multiply by bitmap size to form an address add R3, R6 ' Add the row offset for each tile add R3, TilePtr ' R3 := Address of the bitmap word to read rdword PIXELS, R3 ' Set pixels to the proper data rev PIXELS, #16 ' Reverse bit order to output pixels MSB first rdbyte R3, R4 ' R3 := foreground color add R4, #1 ' Advance the color pointer for the next character mov R2, COLORS shl R2, #8 or R2, R3 ' Only foreground color is set, background remains the same from palette ror R2, #8 test VideoMode, #1 wz if_nz xor R2, phaseflip ' Flip color phase if PAL mode waitvid R2, PIXELS ' Output our video djnz R0, #:StatusChar ' and loop mov VSCL, _VSCL_RightBorder waitvid COLOR_BORDER, #0 ' Output the right border add R6, #2 djnz LineCounter, #:ScanLine ' Next line (note that here LineCounter is always > 0)' jmp #:EmptyLine ' Draw a data line:DataLine mov VSCL, _VSCL_LeftBorder waitvid COLOR_BORDER, #0 ' Output the left border ' Character rendering loop mov VSCL, _VSCL_Character mov R0, #20 ' R0 := Character counter (per line) mov R1, AttribPtr ' R1 := Pointer to attribute (tile) area:Character rdbyte R2, R1 ' R2 := Tile description long add R1, #1 ' Advance the attribute pointer for the next character test Status, #2 wz if_z shl R2, #5 ' Multiply by bitmap size to form an address if_nz shl R2, #4 add R2, CharacterRows ' Add the row offset for each tile add R2, TilePtr ' R2 := Address of the bitmap word to read rdword PIXELS, R2 ' Set pixels to the proper data cmp OffsetX, #0 wz if_z jmp #:Output shl PIXELS, OffsetX rdbyte R2, R1 test Status, #2 wz if_z shl R2, #5 ' Multiply by bitmap size to form an address if_nz shl R2, #4 add R2, CharacterRows ' Add the row offset for each tile add R2, TilePtr ' R2 := Address of the bitmap word to read rdword R3, R2 shr R3, R5 or PIXELS, R3:Output rev PIXELS, #16 ' Reverse bit order to output pixels MSB first mov R2, COLORS test VideoMode, #1 wz if_nz xor R2, phaseflip ' Flip color phase if PAL mode waitvid R2, PIXELS ' Output our video djnz R0, #:Character ' and loop mov VSCL, _VSCL_RightBorder waitvid COLOR_BORDER, #0 ' Output the right border ' Calculate the address of the next attribute line add CharacterRows, #2 test Status, #2 wz if_z mov R2, #32 if_nz mov R2, #16 cmp CharacterRows, R2 wz if_z mov CharacterRows, #0 ' Advance to the next line of attributes if the sub-character counter if_z add AttribPtr, #40 ' reaches the end of character, and reset it to 8 djnz LineCounter, #:ScanLine ' Next line (note that here LineCounter is always > 0) ' Empty (border only) lines :EmptyLine mov VSCL, _VSCL_VisibleLine ' Output an entire visible line of BORDER color waitvid COLOR_BORDER, #0 djnz LineCounter, #:ScanLine ' Next line: note that this may be the last one ' VSync mov R0, #$FF wrbyte R0, VSyncPtr test VideoMode, #1 wz if_nz xor phaseflip, phasemask call #VSyncHigh ' VSync procedure: 6 half-lines of HSync-only values (3 lines) call #VSyncLow ' 6 half-lines inverted from the previous ones (3 lines) call #VSyncHigh ' 6 half-lines more of HSync-only values (3 lines) mov R0, #0 wrbyte R0, VSyncPtr jmp #:Frame ' Next frame ' ───────────────────────────────────────── ' Synchronization subroutines ' ─────────────────────────────────────────HSync mov VSCL, _VSCL_FrontPorch waitvid COLOR_BLACK, #0 mov VSCL, _VSCL_SynchronizingPulse waitvid COLOR_SYNC, #0 mov VSCL, _VSCL_BreezeAway waitvid COLOR_BLACK, #0 mov VSCL, _VSCL_ColourBurst test VideoMode, #1 wz if_nz xor phaseflip, phasemask wz ' Swing color burst if PAL if_z mov R0, _Burst1 if_nz mov R0, _Burst2 waitvid R0, #0 mov VSCL, _VSCL_WaitToData waitvid COLOR_BLACK, #0HSync_Ret retVSyncHigh mov R0, #6:Loop mov VSCL, _VSCL_FrontPorch waitvid COLOR_BLACK, #0 mov R1, _VSCL_SynchronizingPulse shr R1, #1 ' Half-length pulses mov VSCL, R1 waitvid COLOR_SYNC, #0 mov VSCL, R1 waitvid COLOR_BLACK, #0 mov VSCL, _VSCL_BackPorch ' BackPorch = BreezeAway + ColourBurst + WaitToData waitvid COLOR_BLACK, #0 mov VSCL, _VSCL_HalfLine waitvid COLOR_BLACK, #0 djnz R0, #:LoopVSyncHigh_Ret retVSyncLow mov R0, #6:Loop mov VSCL, _VSCL_FrontPorch waitvid COLOR_BLACK, #0 mov VSCL, _VSCL_HalfLine waitvid COLOR_SYNC, #0 mov VSCL, _VSCL_BackPorch ' BackPorch = BreezeAway + ColourBurst + WaitToData waitvid COLOR_SYNC, #0 mov VSCL, _VSCL_FrontPorch waitvid COLOR_SYNC, #0 mov R1, _VSCL_SynchronizingPulse sub R1, _VSCL_FrontPorch mov VSCL, R1' mov VSCL, _VSCL_SynchronizingPulse waitvid COLOR_BLACK, #0 djnz R0, #:Loop VSyncLow_Ret ret ' ───────────────────────────────────────── ' Utility subroutines ' ───────────────────────────────────────── ' Divide R1 by R2 and return the result in R3 with 32 bits of decimal precision ' Input: R1 → Dividend ' R2 → Divisor (it is required that R1 < R2) ' Output: R3 → (R1/R2) << 32 Divide mov R0, #33:Loop cmpsub R1, R2 wc rcl R3, #1 shl R1, #1 djnz R0, #:LoopDivide_Ret retphaseflip long $00000000phasemask long $F0F0F0F0 ' invert hue portion of color ' ───────────────────────────────────────── ' Uninitialized data ' ───────────────────────────────────────── R0 res 1 R1 res 1 R2 res 1 R3 res 1 R4 res 1 R5 res 1 R6 res 1 COLORS res 1 PIXELS res 1 _VCFG_PinMask res 1 _VCFG_PinGroup res 1 _VCFG_Mode res 1 _PortMask res 1 _ClockFreq res 1 _VSCL_Character res 1 _VSCL_VisibleLine res 1 _VSCL_HalfLine res 1 _VSCL_LeftBorder res 1 _VSCL_RightBorder res 1 _VSCL_FrontPorch res 1 _VSCL_SynchronizingPulse res 1 _VSCL_BreezeAway res 1 _VSCL_ColourBurst res 1 _VSCL_BackPorch res 1 _VSCL_WaitToData res 1 _VerticalLines res 1 _TopLine res 1 _BottomLine res 1 _Burst1 res 1 _Burst2 res 1 LineCounter res 1 CharacterRows res 1 TilePtr res 1 AttribPtr res 1 ScreenPtr res 1 StatusPtr res 1 VSyncPtr res 1 PAddr res 1 PCtr res 1 OffsetX res 1 OffsetY res 1 Status res 1 VideoMode res 1 fit \ No newline at end of file diff --git a/source/boulder/bellatrix/Game_controller.spin b/source/boulder/bellatrix/Game_controller.spin new file mode 100644 index 0000000..941a977 --- /dev/null +++ b/source/boulder/bellatrix/Game_controller.spin @@ -0,0 +1 @@ +con GP_RIGHT = %00000001 GP_LEFT = %00000010 GP_DOWN = %00000100 GP_UP = %00001000 GP_START = %00010000 GP_SELECT = %00100000 GP_B = %01000000 GP_A = %10000000 var long stack[6] long nes_bitspub start nes_bits := 0 'cognew(process, @stack)pub read 'return nes_bits return processpub process | i, bits ' set I/O ports to proper direction ' P3 = JOY_CLK (4) ' P4 = JOY_SH/LDn (5) ' P5 = JOY_DATAOUT0 (6) ' P6 = JOY_DATAOUT1 (7) ' NES Bit Encoding ' step 1: set I/Os DIRA[3] := 1 ' output DIRA[4] := 1 ' output DIRA[5] := 0 ' input DIRA[6] := 0 ' input repeat ' step 2: set clock and latch to 0 OUTA[3] := 0 ' JOY_CLK = 0 OUTA[4] := 0 ' JOY_SH/LDn = 0 'Delay(1) ' step 3: set latch to 1 OUTA[4] := 1 ' JOY_SH/LDn = 1 'Delay(1) ' step 4: set latch to 0 OUTA[4] := 0 ' JOY_SH/LDn = 0 ' step 5: read first bit of each game pad ' data is now ready to shift out ' first bit is ready ' left controller bits := INA[5] | (INA[6] << 8) ' step 7: read next 7 bits repeat i from 0 to 6 OUTA[3] := 1 ' JOY_CLK = 1 'Delay(1) OUTA[3] := 0 ' JOY_CLK = 0 bits := (bits << 1) bits := bits | INA[5] | (INA[6] << 8) 'Delay(1) ' invert bits to make positive logic and store result nes_bits := (!bits & $FFFF) return nes_bits \ No newline at end of file diff --git a/source/boulder/bellatrix/Keyboard.spin b/source/boulder/bellatrix/Keyboard.spin new file mode 100644 index 0000000..c9ec831 --- /dev/null +++ b/source/boulder/bellatrix/Keyboard.spin @@ -0,0 +1 @@ +''***************************************''* PS/2 Keyboard Driver v1.0.1 *''* Author: Chip Gracey *''* Copyright (c) 2004 Parallax, Inc. *''* See end of file for terms of use. *''***************************************{-----------------REVISION HISTORY----------------- v1.0.1 - Updated 6/15/2006 to work with Propeller Tool 0.96} VAR long cog long par_tail 'key buffer tail read/write (19 contiguous longs) long par_head 'key buffer head read-only long par_present 'keyboard present read-only long par_states[8] 'key states (256 bits) read-only long par_keys[8] 'key buffer (16 words) read-only (also used to pass initial parameters)PUB start(dpin, cpin) : okay'' Start keyboard driver - starts a cog'' returns false if no cog available'''' dpin = data signal on PS/2 jack'' cpin = clock signal on PS/2 jack'''' use 100-ohm resistors between pins and jack'' use 10K-ohm resistors to pull jack-side signals to VDD'' connect jack-power to 5V, jack-gnd to VSS'''' all lock-keys will be enabled, NumLock will be initially 'on','' and auto-repeat will be set to 15cps with a delay of .5s okay := startx(dpin, cpin, %0_000_100, %01_01000)PUB startx(dpin, cpin, locks, auto) : okay'' Like start, but allows you to specify lock settings and auto-repeat'''' locks = lock setup'' bit 6 disallows shift-alphas (case set soley by CapsLock)'' bits 5..3 disallow toggle of NumLock/CapsLock/ScrollLock state'' bits 2..0 specify initial state of NumLock/CapsLock/ScrollLock'' (eg. %0_001_100 = disallow ScrollLock, NumLock initially 'on')'''' auto = auto-repeat setup'' bits 6..5 specify delay (0=.25s, 1=.5s, 2=.75s, 3=1s)'' bits 4..0 specify repeat rate (0=30cps..31=2cps)'' (eg %01_00000 = .5s delay, 30cps repeat) stop longmove(@par_keys, @dpin, 4) okay := cog := cognew(@entry, @par_tail) + 1PUB stop'' Stop keyboard driver - frees a cog if cog cogstop(cog~ - 1) longfill(@par_tail, 0, 19)PUB present : truefalse'' Check if keyboard present - valid ~2s after start'' returns t|f truefalse := -par_presentPUB key : keycode'' Get key (never waits)'' returns key (0 if buffer empty) if par_tail <> par_head keycode := par_keys.word[par_tail] par_tail := ++par_tail & $FPUB getkey : keycode'' Get next key (may wait for keypress)'' returns key repeat until (keycode := key)PUB newkey : keycode'' Clear buffer and get new key (always waits for keypress)'' returns key par_tail := par_head keycode := getkeyPUB gotkey : truefalse'' Check if any key in buffer'' returns t|f truefalse := par_tail <> par_headPUB clearkeys'' Clear key buffer par_tail := par_headPUB keystate(k) : state'' Get the state of a particular key'' returns t|f state := -(par_states[k >> 5] >> k & 1)DAT'******************************************'* Assembly language PS/2 keyboard driver *'****************************************** org''' Entry'entry movd :par,#_dpin 'load input parameters _dpin/_cpin/_locks/_auto mov x,par add x,#11*4 mov y,#4:par rdlong 0,x add :par,dlsb add x,#4 djnz y,#:par mov dmask,#1 'set pin masks shl dmask,_dpin mov cmask,#1 shl cmask,_cpin test _dpin,#$20 wc 'modify port registers within code muxc _d1,dlsb muxc _d2,dlsb muxc _d3,#1 muxc _d4,#1 test _cpin,#$20 wc muxc _c1,dlsb muxc _c2,dlsb muxc _c3,#1 mov _head,#0 'reset output parameter _head''' Reset keyboard'reset mov dira,#0 'reset directions mov dirb,#0 movd :par,#_present 'reset output parameters _present/_states[8] mov x,#1+8:par mov 0,#0 add :par,dlsb djnz x,#:par mov stat,#8 'set reset flag''' Update parameters'update movd :par,#_head 'update output parameters _head/_present/_states[8] mov x,par add x,#1*4 mov y,#1+1+8:par wrlong 0,x add :par,dlsb add x,#4 djnz y,#:par test stat,#8 wc 'if reset flag, transmit reset command if_c mov data,#$FF if_c call #transmit''' Get scancode'newcode mov stat,#0 'reset state:same call #receive 'receive byte from keyboard cmp data,#$83+1 wc 'scancode? if_nc cmp data,#$AA wz 'powerup/reset? if_nc_and_z jmp #configure if_nc cmp data,#$E0 wz 'extended? if_nc_and_z or stat,#1 if_nc_and_z jmp #:same if_nc cmp data,#$F0 wz 'released? if_nc_and_z or stat,#2 if_nc_and_z jmp #:same if_nc jmp #newcode 'unknown, ignore''' Translate scancode and enter into buffer' test stat,#1 wc 'lookup code with extended flag rcl data,#1 call #look cmp data,#0 wz 'if unknown, ignore if_z jmp #newcode mov t,_states+6 'remember lock keys in _states mov x,data 'set/clear key bit in _states shr x,#5 add x,#_states movd :reg,x mov y,#1 shl y,data test stat,#2 wc:reg muxnc 0,y if_nc cmpsub data,#$F0 wc 'if released or shift/ctrl/alt/win, done if_c jmp #update mov y,_states+7 'get shift/ctrl/alt/win bit pairs shr y,#16 cmpsub data,#$E0 wc 'translate keypad, considering numlock if_c test _locks,#%100 wz if_c_and_z add data,#@keypad1-@table if_c_and_nz add data,#@keypad2-@table if_c call #look if_c jmp #:flags cmpsub data,#$DD wc 'handle scrlock/capslock/numlock if_c mov x,#%001_000 if_c shl x,data if_c andn x,_locks if_c shr x,#3 if_c shr t,#29 'ignore auto-repeat if_c andn x,t wz if_c xor _locks,x if_c add data,#$DD if_c_and_nz or stat,#4 'if change, set configure flag to update leds test y,#%11 wz 'get shift into nz if_nz cmp data,#$60+1 wc 'check shift1 if_nz_and_c cmpsub data,#$5B wc if_nz_and_c add data,#@shift1-@table if_nz_and_c call #look if_nz_and_c andn y,#%11 if_nz cmp data,#$3D+1 wc 'check shift2 if_nz_and_c cmpsub data,#$27 wc if_nz_and_c add data,#@shift2-@table if_nz_and_c call #look if_nz_and_c andn y,#%11 test _locks,#%010 wc 'check shift-alpha, considering capslock muxnc :shift,#$20 test _locks,#$40 wc if_nz_and_nc xor :shift,#$20 cmp data,#"z"+1 wc if_c cmpsub data,#"a" wc:shift if_c add data,#"A" if_c andn y,#%11:flags ror data,#8 'add shift/ctrl/alt/win flags mov x,#4 '+$100 if shift:loop test y,#%11 wz '+$200 if ctrl shr y,#2 '+$400 if alt if_nz or data,#1 '+$800 if win ror data,#1 djnz x,#:loop rol data,#12 rdlong x,par 'if room in buffer and key valid, enter sub x,#1 and x,#$F cmp x,_head wz if_nz test data,#$FF wz if_nz mov x,par if_nz add x,#11*4 if_nz add x,_head if_nz add x,_head if_nz wrword data,x if_nz add _head,#1 if_nz and _head,#$F test stat,#4 wc 'if not configure flag, done if_nc jmp #update 'else configure to update leds''' Configure keyboard'configure mov data,#$F3 'set keyboard auto-repeat call #transmit mov data,_auto and data,#%11_11111 call #transmit mov data,#$ED 'set keyboard lock-leds call #transmit mov data,_locks rev data,#-3 & $1F test data,#%100 wc rcl data,#1 and data,#%111 call #transmit mov x,_locks 'insert locks into _states and x,#%111 shl _states+7,#3 or _states+7,x ror _states+7,#3 mov _present,#1 'set _present jmp #update 'done''' Lookup byte in table'look ror data,#2 'perform lookup movs :reg,data add :reg,#table shr data,#27 mov x,data:reg mov data,0 shr data,x jmp #rand 'isolate byte''' Transmit byte to keyboard'transmit_c1 or dira,cmask 'pull clock low movs napshr,#13 'hold clock for ~128us (must be >100us) call #nap_d1 or dira,dmask 'pull data low movs napshr,#18 'hold data for ~4us call #nap_c2 xor dira,cmask 'release clock test data,#$0FF wc 'append parity and stop bits to byte muxnc data,#$100 or data,dlsb mov x,#10 'ready 10 bitstransmit_bit call #wait_c0 'wait until clock low shr data,#1 wc 'output data bit_d2 muxnc dira,dmask mov wcond,c1 'wait until clock high call #wait djnz x,#transmit_bit 'another bit? mov wcond,c0d0 'wait until clock and data low call #wait mov wcond,c1d1 'wait until clock and data high call #wait call #receive_ack 'receive ack byte with timed wait cmp data,#$FA wz 'if ack error, reset keyboard if_nz jmp #resettransmit_ret ret''' Receive byte from keyboard'receive test _cpin,#$20 wc 'wait indefinitely for initial clock low waitpne cmask,cmaskreceive_ack mov x,#11 'ready 11 bitsreceive_bit call #wait_c0 'wait until clock low movs napshr,#16 'pause ~16us call #nap_d3 test dmask,ina wc 'input data bit rcr data,#1 mov wcond,c1 'wait until clock high call #wait djnz x,#receive_bit 'another bit? shr data,#22 'align byte test data,#$1FF wc 'if parity error, reset keyboard if_nc jmp #resetrand and data,#$FF 'isolate bytelook_retreceive_ack_retreceive_ret ret''' Wait for clock/data to be in required state(s)'wait_c0 mov wcond,c0 '(wait until clock low)wait mov y,tenms 'set timeout to 10mswloop movs napshr,#18 'nap ~4us call #nap_c3 test cmask,ina wc 'check required state(s)_d4 test dmask,ina wz 'loop until got state(s) or timeoutwcond if_never djnz y,#wloop '(replaced with c0/c1/c0d0/c1d1) tjz y,#reset 'if timeout, reset keyboardwait_retwait_c0_ret retc0 if_c djnz y,#wloop '(if_never replacements)c1 if_nc djnz y,#wloopc0d0 if_c_or_nz djnz y,#wloopc1d1 if_nc_or_z djnz y,#wloop''' Nap'nap rdlong t,#0 'get clkfreqnapshr shr t,#18/16/13 'shr scales time min t,#3 'ensure waitcnt won't snag add t,cnt 'add cnt to time waitcnt t,#0 'wait until time elapses (nap)nap_ret ret''' Initialized data''dlsb long 1 << 9tenms long 10_000 / 4''' Lookup table' ascii scan extkey regkey ()=keypad'table word $0000 '00 word $00D8 '01 F9 word $0000 '02 word $00D4 '03 F5 word $00D2 '04 F3 word $00D0 '05 F1 word $00D1 '06 F2 word $00DB '07 F12 word $0000 '08 word $00D9 '09 F10 word $00D7 '0A F8 word $00D5 '0B F6 word $00D3 '0C F4 word $0009 '0D Tab word $0060 '0E ` word $0000 '0F word $0000 '10 word $F5F4 '11 Alt-R Alt-L word $00F0 '12 Shift-L word $0000 '13 word $F3F2 '14 Ctrl-R Ctrl-L word $0071 '15 q word $0031 '16 1 word $0000 '17 word $0000 '18 word $0000 '19 word $007A '1A z word $0073 '1B s word $0061 '1C a word $0077 '1D w word $0032 '1E 2 word $F600 '1F Win-L word $0000 '20 word $0063 '21 c word $0078 '22 x word $0064 '23 d word $0065 '24 e word $0034 '25 4 word $0033 '26 3 word $F700 '27 Win-R word $0000 '28 word $0020 '29 Space word $0076 '2A v word $0066 '2B f word $0074 '2C t word $0072 '2D r word $0035 '2E 5 word $CC00 '2F Apps word $0000 '30 word $006E '31 n word $0062 '32 b word $0068 '33 h word $0067 '34 g word $0079 '35 y word $0036 '36 6 word $CD00 '37 Power word $0000 '38 word $0000 '39 word $006D '3A m word $006A '3B j word $0075 '3C u word $0037 '3D 7 word $0038 '3E 8 word $CE00 '3F Sleep word $0000 '40 word $002C '41 , word $006B '42 k word $0069 '43 i word $006F '44 o word $0030 '45 0 word $0039 '46 9 word $0000 '47 word $0000 '48 word $002E '49 . word $EF2F '4A (/) / word $006C '4B l word $003B '4C ; word $0070 '4D p word $002D '4E - word $0000 '4F word $0000 '50 word $0000 '51 word $0027 '52 ' word $0000 '53 word $005B '54 [ word $003D '55 = word $0000 '56 word $0000 '57 word $00DE '58 CapsLock word $00F1 '59 Shift-R word $EB0D '5A (Enter) Enter word $005D '5B ] word $0000 '5C word $005C '5D \ word $CF00 '5E WakeUp word $0000 '5F word $0000 '60 word $0000 '61 word $0000 '62 word $0000 '63 word $0000 '64 word $0000 '65 word $00C8 '66 BackSpace word $0000 '67 word $0000 '68 word $C5E1 '69 End (1) word $0000 '6A word $C0E4 '6B Left (4) word $C4E7 '6C Home (7) word $0000 '6D word $0000 '6E word $0000 '6F word $CAE0 '70 Insert (0) word $C9EA '71 Delete (.) word $C3E2 '72 Down (2) word $00E5 '73 (5) word $C1E6 '74 Right (6) word $C2E8 '75 Up (8) word $00CB '76 Esc word $00DF '77 NumLock word $00DA '78 F11 word $00EC '79 (+) word $C7E3 '7A PageDn (3) word $00ED '7B (-) word $DCEE '7C PrScr (*) word $C6E9 '7D PageUp (9) word $00DD '7E ScrLock word $0000 '7F word $0000 '80 word $0000 '81 word $0000 '82 word $00D6 '83 F7keypad1 byte $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/"keypad2 byte "0123456789.", $0D, "+-*/"shift1 byte "{|}", 0, 0, "~"shift2 byte $22, 0, 0, 0, 0, "<_>?)!@#$%^&*(", 0, ":", 0, "+"''' Uninitialized data'dmask res 1cmask res 1stat res 1data res 1x res 1y res 1t res 1_head res 1 'write-only_present res 1 'write-only_states res 8 'write-only_dpin res 1 'read-only at start_cpin res 1 'read-only at start_locks res 1 'read-only at start_auto res 1 'read-only at start'''''' _________'' Key Codes'''' 00..DF = keypress and keystate'' E0..FF = keystate only'''''' 09 Tab'' 0D Enter'' 20 Space'' 21 !'' 22 "'' 23 #'' 24 $'' 25 %'' 26 &'' 27 ''' 28 ('' 29 )'' 2A *'' 2B +'' 2C ,'' 2D -'' 2E .'' 2F /'' 30 0..9'' 3A :'' 3B ;'' 3C <'' 3D ='' 3E >'' 3F ?'' 40 @ '' 41..5A A..Z'' 5B ['' 5C \'' 5D ]'' 5E ^'' 5F _'' 60 `'' 61..7A a..z'' 7B {'' 7C |'' 7D }'' 7E ~'''' 80-BF (future international character support)'''' C0 Left Arrow'' C1 Right Arrow'' C2 Up Arrow'' C3 Down Arrow'' C4 Home'' C5 End'' C6 Page Up'' C7 Page Down'' C8 Backspace'' C9 Delete'' CA Insert'' CB Esc'' CC Apps'' CD Power'' CE Sleep'' CF Wakeup'''' D0..DB F1..F12'' DC Print Screen'' DD Scroll Lock'' DE Caps Lock'' DF Num Lock'''' E0..E9 Keypad 0..9'' EA Keypad .'' EB Keypad Enter'' EC Keypad +'' ED Keypad -'' EE Keypad *'' EF Keypad /'''' F0 Left Shift'' F1 Right Shift'' F2 Left Ctrl'' F3 Right Ctrl'' F4 Left Alt'' F5 Right Alt'' F6 Left Win'' F7 Right Win'''' FD Scroll Lock State'' FE Caps Lock State'' FF Num Lock State'''' +100 if Shift'' +200 if Ctrl'' +400 if Alt'' +800 if Win'''' eg. Ctrl-Alt-Delete = $6C9'''''' Note: Driver will buffer up to 15 keystrokes, then ignore overflow.{{┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐│ TERMS OF USE: MIT License │ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, ││modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software││is furnished to do so, subject to the following conditions: ││ ││The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.││ ││THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ││WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ││COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ││ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘}} \ No newline at end of file diff --git a/source/boulder/bellatrix/RealRandom.spin b/source/boulder/bellatrix/RealRandom.spin new file mode 100644 index 0000000..d9f2724 --- /dev/null +++ b/source/boulder/bellatrix/RealRandom.spin @@ -0,0 +1 @@ +{{┌───────────────────────────────────────────┬────────────────┬───────────────────────────────────┬───────────────┐│ Real Random v1.2 │ by Chip Gracey │ Copyright (c) 2007 Parallax, Inc. │ 23 March 2007 │├───────────────────────────────────────────┴────────────────┴───────────────────────────────────┴───────────────┤│ ││ This object generates real random numbers by stimulating and tracking CTR PLL jitter. It requires one cog and ││ at least 20MHz. ││ │├────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤│ Background and Detail: ││ ││ A real random number is impossible to generate within a closed digital system. This is because there are no ││ reliably-random states within such a system at power-up, and after power-up, it behaves deterministically. ││ Random values can only be 'earned' by measuring something outside of the digital system. │ │ ││ In your programming, you might have used 'var?' to generate a pseudo-random sequence, but found the same ││ pattern playing every time you ran your program. You might have then used 'cnt' to 'randomly' seed the 'var'. ││ As long as you kept downloading to RAM, you saw consistently 'random' results. At some point, you probably ││ downloaded to EEPROM to set your project free. But what happened nearly every time you powered it up? You were ││ probably dismayed to discover the same sequence playing each time! The problem was that 'cnt' was always ││ powering-up with the same initial value and you were then sampling it at a constant offset. This can make you ││ wonder, "Where's the end to this madness? And will I ever find true randomness?". │ │ ││ In order to have real random numbers, either some external random signal must be input, or some analog system ││ must be used to generate random noise which can be measured. We're in luck here, because it turns out that the ││ Propeller does have sufficiently-analog subsystems which can be exploited for this purpose -- each cog's CTR ││ PLLs. These can be exercised internally to good effect, without any I/O activity. │ │ ││ This object sets up a cog's CTRA PLL to run at the main clock's frequency. It then uses a pseudo-random ││ sequencer to modulate the PLL's target phase. The PLL responds by speeding up and slowing down in a an endless ││ effort to lock. This results in very unpredictable frequency jitter which is fed back into the sequencer to ││ keep the bit salad tossing. The final output is a truly-random 32-bit unbiased value that is fully updated ││ every ~100us, with new bits rotated in every ~3us. This value can be sampled by your application whenever a │ │ random number is needed. ││ │├────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤│ Revision History v1.0 released 21 March 2007 ││ │ │ v1.1 Bias removal has been added to ensure true randomness. Released 22 March 2007. ││ v1.2 Assembly code made more efficient. Documentation improved. Released 23 March 2007. ││ │└────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘}}VAR long cog, random_valuePUB start : okay'' Start real random driver - starts a cog'' returns false if no cog available 'Reset driver stop 'Launch real random cog return cog := cognew(@entry, @random_value) + 1 'allow 5ms to launch and randomize waitcnt(clkfreq / 200 + cnt)PUB stop'' Stop real random driver - frees a cog 'If already running, stop real random cog if cog cogstop(cog~ - 1)PUB random : value'' Returns a new long random value 'wait to insure new random (~200us at 80MHz system clock) waitcnt($4000 + cnt) return random_valuePUB random_ptr : ptr'' Returns the address of the long which receives the random value'''' A random bit is rotated into the long every ~3us, resuling in a'' new long every ~100us, on average, at 80MHz. You may want to double'' these times, though, to be sure that you are getting new bits. The'' timing uncertainty comes from the unbiasing algorithm which throws'' away identical bit pairs, and only outputs the different ones. return @random_valueDAT' ┌─────────────────────────┐' │ Real Random Generator │' └─────────────────────────┘ orgentry movi ctra,#%00001_111 'set ctra to internal pll mode, select x16 tap movi frqa,#$020 'set frqa to system clock frequency / 16 movi vcfg,#$040 'set vcfg to discrete output, but without pins mov vscl,#70 'set vscl to 70 pixel clocks per waitvid:twobits waitvid 0,0 'wait for next 70-pixel mark ± jitter time test phsa,#%10111 wc 'pseudo-randomly sequence phase to induce jitter rcr phsa,#1 '(c holds random bit #1) add phsa,cnt 'mix PLL jitter back into phase rcl par,#1 wz, nr 'transfer c into nz (par shadow register = 0) wrlong _random_value,par 'write random value back to spin variable waitvid 0,0 'wait for next 70-pixel mark ± jitter time test phsa,#%10111 wc 'pseudo-randomly sequence phase to induce jitter rcr phsa,#1 '(c holds random bit #2) add phsa,cnt 'mix PLL jitter back into phase if_z_eq_c rcl _random_value,#1 'only allow different bits (removes bias) jmp #:twobits 'get next two bits_random_value res 1{{┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐│ TERMS OF USE: MIT License │ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, ││modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software││is furnished to do so, subject to the following conditions: ││ ││The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.││ ││THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ││WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ││COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ││ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘}} \ No newline at end of file diff --git a/source/boulder/bellatrix/SIDemu.spin b/source/boulder/bellatrix/SIDemu.spin new file mode 100644 index 0000000..fabffa8 --- /dev/null +++ b/source/boulder/bellatrix/SIDemu.spin @@ -0,0 +1,831 @@ +' Propeller SID (MOS 6581) Emulator. +' Code released to public domain +' H. Peraza. +' +' Changes: +' +' 2009-12-07 - Started with the simple PWM example code from Propeller App Notes. +' - Simple frequency control added. 16-bit phase register used. +' - Added code to generate 3 of the SID waveforms: sawtooth, triangle +' and rectangle (square) wave. Sample uses upper 8 bits of the phase register. +' 2009-12-08 - Added a simple shift-register noise generator. +' - Changed sampling frequency to SID clk/32 = 31.25 KHz and phase register +' size to 19 bits so we can directly use SID frequency values. +' - Two more voices added, using identical code. The voices are simply added +' together to produce the output. +' - Scale waveforms according to an specified amplitude value. +' - "AND" waveforms together when more than one is selected in the control register. +' - Fixed noise generation. Now noise pitch also varies with frequency changes. +' 2009-12-09 - Added variables for all SID register. +' - Added envelope generation in a separate cog. Sounding already familiar! +' - Added a function to set a given SID register, to be used by external programs. +' - Got the BoulderDash main tune working! The transitions of one voice sounds +' somewhat "melted", though. +' - Implemented pulse-width control of the rectangle wave. +' - Added ring modulation option. +' 2009-12-10 - Changed the ring modulation method, hopefully is now closer to what SID does. +' Now harmonics and heterodynes can be heard when sweeping the frequency of +' the modulating generator. +' - Envelope generation is now done in the same main cog. The loop was split in two +' in order to have enough computing time. Waveform is now updated (sampled) at a +' half of the PWM frequency. The phase register is now 18 bits, but sample resolution +' is still the same upper 8 bits. As a side effect, digital artifacts seem less +' noticeable! Envelope is updated every 1.024 msec. +' 2009-12-11 - Track sustain changes while in sustain cycle, but only in the "down" direction. +' - Added main volume control. +' - Scale envelopes down a bit in order to avoid distortion when the three voices +' play simultaneously and the full volume is selected. +' - Had to rewrite the whole envelope generator again, in order to make it track +' the signal levels at any time and at any gate triggering moment. What a pain. +' Still not working correctly in all cases. + +var + + ' The 29 SID registers + + word voice1_Freq ' frequency + word voice1_PW ' 12-bit pulse width for the RECTANGLE waveform + byte voice1_ControlReg ' waveform type and control + byte voice1_AttackDecay ' bits 0-3 decay, 4-7 attack + byte voice1_SustainRelease ' bits 0-3 release, 4-7 sustain + + word voice2_Freq ' frequency + word voice2_PW ' 12-bit pulse width for the RECTANGLE waveform + byte voice2_ControlReg ' waveform type and control + byte voice2_AttackDecay ' bits 0-3 decay, 4-7 attack + byte voice2_SustainRelease ' bits 0-3 release, 4-7 sustain + + word voice3_Freq ' frequency + word voice3_PW ' 12-bit pulse width for the RECTANGLE waveform + byte voice3_ControlReg ' waveform type and control + byte voice3_AttackDecay ' bits 0-3 decay, 4-7 attack + byte voice3_SustainRelease ' bits 0-3 release, 4-7 sustain + + word FC ' filter cutoff/center frequency, not implemented + byte Res_Filt ' bits 0-3 filter on/off selection, bits 4-7 filter resonance, not implemented + byte Mode_Vol ' bits 0-3 volume level, bits 4-6 filter mode, bit 7 voice 3 on/off, filter bits not implemented + byte PotX ' potentiometer X ADC value, not implemented + byte PotY ' potentiometer Y ADC value, not implemented + byte Osc3_Random ' upper 8-bits of voice 3 waveform, not implemented + byte Env3 ' upper 8-bits of voice 3 envelope generator, not implemented + +con + + ' SID voice control register bits + CREG_GATE = %0000_0001 + CREG_SYNC = %0000_0010 + CREG_RINGMOD = %0000_0100 + CREG_TEST = %0000_1000 + CREG_TRIANGLE = %0001_0000 + CREG_SAWTOOTH = %0010_0000 + CREG_RECTANGLE = %0100_0000 + CREG_NOISE = %1000_0000 + + ' SID RES/FILT (reg 23) + FREG_FILT1 = %0000_0001 + FREG_FILT2 = %0000_0010 + FREG_FILT3 = %0000_0100 + + ' SID MODE/VOL (reg 24) + MREG_VOICE3OFF = %1000_0000 + +dat + + ' attack, decay and release envelope timings (msecs) +AttackTimes + word 2, 8, 16, 24 + word 38, 56, 68, 80 + word 100, 250, 500, 800 + word 1000, 3000, 5000, 8000 +DecayReleaseTimes + word 6, 24, 48, 72 + word 114, 168, 204, 240 + word 300, 750, 1500, 2400 + word 3000, 9000, 15000, 24000 + +var + + long param[26] + + word attack_time_1 + word decay_time_1 + word sustain_level_1 + word release_time_1 + + word attack_time_2 + word decay_time_2 + word sustain_level_2 + word release_time_2 + + word attack_time_3 + word decay_time_3 + word sustain_level_3 + word release_time_3 + +pub start(pin) + + param[0] := clkfreq / F_PWM + param[1] := |< pin + param[2] := (%00100 << 26) + pin 'NCO/PWM + pin + + param[3] := @voice1_ControlReg + param[4] := @voice1_Freq + param[5] := @voice1_PW + param[6] := @attack_time_1 + param[7] := @decay_time_1 + param[8] := @sustain_level_1 + param[9] := @release_time_1 + + param[10] := @voice2_ControlReg + param[11] := @voice2_Freq + param[12] := @voice2_PW + param[13] := @attack_time_2 + param[14] := @decay_time_2 + param[15] := @sustain_level_2 + param[16] := @release_time_2 + + param[17] := @voice3_ControlReg + param[18] := @voice3_Freq + param[19] := @voice3_PW + param[20] := @attack_time_3 + param[21] := @decay_time_3 + param[22] := @sustain_level_3 + param[23] := @release_time_3 + + param[24] := @RES_Filt + param[25] := @Mode_Vol + + 'initialize SID registers + + voice1_SustainRelease := $F0 + voice2_SustainRelease := $F0 + voice3_SustainRelease := $F0 + + Mode_Vol := $00 'volume off + + init_envelope1 + init_envelope2 + init_envelope3 + + cognew(@entry, @param) + +pub set_register(regnum, val) + + val &= $FF + + case regnum + 'voice1 + 0: voice1_Freq &= $FF00 + voice1_Freq |= val + 1: voice1_Freq &= $00FF + voice1_Freq |= val << 8 'shall we latch value and update freq only when writing hi-byte? + 2: voice1_PW &= $FF00 + voice1_PW |= val + 3: voice1_PW &= $00FF + voice1_PW |= val << 8 + 4: voice1_ControlReg := val + 5: voice1_AttackDecay := val + init_envelope1 + 6: voice1_SustainRelease := val + init_envelope1 + + 'voice2 + 7: voice2_Freq &= $FF00 + voice2_Freq |= val + 8: voice2_Freq &= $00FF + voice2_Freq |= val << 8 + 9: voice2_PW &= $FF00 + voice2_PW |= val + 10: voice2_PW &= $00FF + voice2_PW |= val << 8 + 11: voice2_ControlReg := val + 12: voice2_AttackDecay := val + init_envelope2 + 13: voice2_SustainRelease := val + init_envelope2 + + 'voice3 + 14: voice3_Freq &= $FF00 + voice3_Freq |= val + 15: voice3_Freq &= $00FF + voice3_Freq |= val << 8 + 16: voice3_PW &= $FF00 + voice3_PW |= val + 17: voice3_PW &= $00FF + voice3_PW |= val << 8 + 18: voice3_ControlReg := val + 19: voice3_AttackDecay := val + init_envelope3 + 20: voice3_SustainRelease := val + init_envelope3 + + 'misc + 21: FC := val + 22: RES_Filt := val + 23: Mode_Vol := val + +con + + F_PWM = 31250 ' PWM osc period is 32µS period, waveform samples are output at half of that rate + MAXLEVEL = 1000 * 16 ' = 16000 max level alloved per voice, must be divisible by 16 + +pri init_envelope1 + + sustain_level_1 := (voice1_SustainRelease >> 4) * constant(MAXLEVEL / 16) + attack_time_1 := word[@AttackTimes + (voice1_AttackDecay >> 4) * 2] + decay_time_1 := word[@DecayReleaseTimes + (voice1_AttackDecay & $0F) * 2] + release_time_1 := word[@DecayReleaseTimes + (voice1_SustainRelease & $0F) * 2] + +pri init_envelope2 + + sustain_level_2 := (voice2_SustainRelease >> 4) * constant(MAXLEVEL / 16) + attack_time_2 := word[@AttackTimes + (voice2_AttackDecay >> 4) * 2] + decay_time_2 := word[@DecayReleaseTimes + (voice2_AttackDecay & $0F) * 2] + release_time_2 := word[@DecayReleaseTimes + (voice2_SustainRelease & $0F) * 2] + +pri init_envelope3 + + sustain_level_3 := (voice3_SustainRelease >> 4) * constant(MAXLEVEL / 16) + attack_time_3 := word[@AttackTimes + (voice3_AttackDecay >> 4) * 2] + decay_time_3 := word[@DecayReleaseTimes + (voice3_AttackDecay & $0F) * 2] + release_time_3 := word[@DecayReleaseTimes + (voice3_SustainRelease & $0F) * 2] + +dat + + org + +entry mov R0, par + movd :load, #period + mov R1, #26 +:load rdlong 0, R0 'copy parameter block + add R0, #4 + add :load, d0 + djnz R1, #:load + + mov dira, diraval 'set APIN to output + mov ctra, ctraval 'establish counter A mode and APIN + mov frqa, #1 'set counter to increment 1 each cycle + + mov switch, #0 + + mov phase1, #0 'init phases + mov phase2, #0 + mov phase3, #0 + + mov level1, #0 'reset envelope levels + mov level2, #0 + mov level3, #0 + + mov level1init, #0 + mov level2init, #0 + mov level3init, #0 + + mov level1acc, #0 + mov level2acc, #0 + mov level3acc, #0 + + mov level1acc, max_level + mov level2acc, max_level + mov level3acc, max_level + + mov t1cnt, #0 + mov t2cnt, #0 + mov t3cnt, #0 + + mov env_cycle, #%111 'all three voices start with attack on next cycle + mov cnt_msec, #1 + + mov time, cnt 'record current time + add time, period 'establish next period + +:loop xor switch, #1 wz + if_z jmp #:L1 + + ' Voice1 + rdword next_phase, voice1freq + add next_phase, phase1 'advance phase + + rdbyte R2, voice1creg 'get control register bits into R2 + mov sig1, #$FF 'set initial sample result to FF, so we could "and" different waveforms together + + test R2, #CREG_NOISE wz 'NOISE waveform? + if_z jmp #:L12 'jump if not + mov R0, next_phase + xor R0, phase1 + test R0, Hex10000 wz + mov R0, noise1 + if_z jmp #:L11 + mov R0, noise + and R0, #$FF + mov noise1, R0 +:L11 and sig1, R0 + +:L12 mov R0, phase1 + shr R0, #10 'we use the upper 8 bits of the 18-bit phase value to generate the waveform + and R0, #$FF 'get the waveform sample value into R0 + mov R3, R0 ' and into R3 (this is already a sawtooth) + + test R2, #CREG_TRIANGLE wz 'TRIANGLE waveform? + if_z jmp #:L14 + test R0, #$80 wz 'sample MSB set? + if_nz xor R0, #$FF 'invert sample if yes + shl R0, #1 'shift left and we have a triangle + test R2, #CREG_RINGMOD wz 'check for ring modulation (allowed only with triangle waveform) + if_z jmp #:L13 'skip if no modulation + mov R4, phase1 'this is as + xor R4, phase3 ' close as I can get + test R4, Hex8000 wz ' to 6581's idea + if_nz xor R0, #$FF ' of ring modulation + +:L13 and sig1, R0 '"and" the waveforms +:L14 test R2, #CREG_SAWTOOTH wz 'SAWTOOTH? + if_nz and sig1, R3 'this is easy + test R2, #CREG_RECTANGLE wz 'RECTANGLE? + if_z jmp #:L15 'skip if not + rdword R0, voice1pw 'get the pulse width into R0 + shr R0, #4 'use only the high 8 bits of the 12-bit value + cmp R0, R3 wc, wz 'compare with sawtooth + if_c_and_z and sig1, #0 'clear output if pw < sawtooth + +:L15 mov R0, sig1 'get resulting sample into R0 + mov R1, level1 'get current envelope amplitude into R1 + call #Mult 'multiply with the current envelope amplitude + shr R1, #12 'shift result to get useful bits + mov sig1, R1 'store result for voice 1 + mov phase1, next_phase 'store new waveform phase + + ' Voice2 + rdword next_phase, voice2freq + add next_phase, phase2 + + rdbyte R2, voice2creg 'get control register bits into R2 + mov sig2, #$FF 'set initial sample value + + test R2, #CREG_NOISE wz 'NOISE waveform? + if_z jmp #:L22 'skip if not + mov R0, next_phase + xor R0, phase2 + test R0, Hex10000 wz + mov R0, noise2 + if_z jmp #:L21 + mov R0, noise + and R0, #$FF + mov noise2, R0 +:L21 and sig2, R0 + +:L22 mov R0, phase2 + shr R0, #10 'get the upper 8 bits of the 18-bit phase value + and R0, #$FF ' into R0 + mov R3, R0 ' and into R3 + + test R2, #CREG_TRIANGLE wz 'TRIANGLE waveform? + if_z jmp #:L24 + test R0, #$80 wz 'MSB set? + if_nz xor R0, #$FF 'invert sample if yes + shl R0, #1 'shift left and we have a triangle + test R2, #CREG_RINGMOD wz 'check for ring modulation + if_z jmp #:L23 'skip if no modulation + mov R4, phase2 + xor R4, phase1 + test R4, Hex8000 wz 'emulate 6581's ring modulation + if_nz xor R0, #$FF + +:L23 and sig2, R0 '"and" the waveforms together +:L24 test R2, #CREG_SAWTOOTH wz 'SAWTOOTH? + if_nz and sig2, R3 'already have it + test R2, #CREG_RECTANGLE wz 'RECTANGLE? + if_z jmp #:L25 'skip if not + rdword R0, voice2pw 'get pulse width into R0 + shr R0, #4 'use upper 8 bits + cmp R0, R3 wc, wz 'compare with sawtooth + if_c_or_z and sig2, #0 'clear output if pw < sawtooth + +:L25 mov R0, sig2 'get resulting sample into R0 + mov R1, level2 'get voice 2 amplitude into R1 + call #Mult 'multiply by envelope amplitude + shr R1, #12 'get useful bits + mov sig2, R1 'store result for voice 2 + mov phase2, next_phase 'store new waveform phase + + ' Voice3 + rdword next_phase, voice3freq + add next_phase, phase3 + + rdbyte R2, voice3creg 'get control bits into R2 + mov sig3, #$FF 'set initial sample value + + test R2, #CREG_NOISE wz 'NOISE waveform? + if_z jmp #:L32 'skip if not + mov R0, next_phase + xor R0, phase3 + test R0, Hex10000 wz + mov R0, noise3 + if_z jmp #:L31 + mov R0, noise + and R0, #$FF + mov noise3, R0 +:L31 and sig3, R0 + +:L32 mov R0, phase3 + shr R0, #10 'get the upper 8 bits of the 16-bit phase value + and R0, #$FF ' into R0 + mov R3, R0 ' and R3 + + test R2, #CREG_TRIANGLE wz 'TRIANGLE waveform? + if_z jmp #:L34 + test R0, #$80 wz 'MSB set? + if_nz xor R0, #$FF 'invert sample if yes + shl R0, #1 'shift left and we have a triangle + test R2, #CREG_RINGMOD wz 'check for ring modulation + if_z jmp #:L33 'skip if no modulation wanted + mov R4, phase3 + xor R4, phase2 + test R4, Hex8000 wz 'emulate SID's ring modulation + if_nz xor R0, #$FF + +:L33 and sig3, R0 'merge the waveforms together +:L34 test R2, #CREG_SAWTOOTH wz 'SAWTOOTH? + if_nz and sig3, R3 'already was in R3 + test R2, #CREG_RECTANGLE wz 'RECTANGLE? + if_z jmp #:L35 'jump if not + rdword R0, voice3pw 'else get pulse width into R0 + shr R0, #4 'leave only the upper 8 bits + cmp R0, R3 wc, wz 'compare with sawtooth + if_c_and_z and sig2, #0 'result is zero if pw < sawtooth + +:L35 mov R0, sig3 'get resulting sample into R0 + mov R1, level3 'get current level of voice 3 into R1 + call #Mult 'multiply by envelope amplitude + shr R1, #12 'get useful bits + mov sig3, R1 'and store result for voice3 + mov phase3, next_phase + + ' Noise generator + mov R0, noise + shl noise, #1 + xor R0, noise + test R0, Hex4000 wz + if_nz or noise, #1 + + jmp #:L2 + +:L1 'Update envelopes + + djnz cnt_msec, #:L41 'jump if not yet time to update envelopes + mov cnt_msec, #16 '1.024 msec + + 'Voice 1 + rdbyte R0, voice1creg 'load values + rdword R1, attack1time + rdword R2, decay1time + rdword R3, sustain1level + rdword R4, release1time + test R0, #CREG_GATE wz 'if gate bit is set then process attack, decay and sustain + if_z jmp #:L42 ' else release + test gate_edge, #%001 wz 'gate just applied? + or gate_edge, #%001 + if_nz jmp #:L40 'jump if yes + or env_cycle, #%001 + mov t1cnt, R1 'else init attack phase, set counter to attack time + mov level1init, level1 'set initial level + mov level1inc, max_level ' and compute increment + sub level1inc, level1init + mov level1acc, #0 'reset accumulator +:L40 test env_cycle, #%001 wz 'attack? + if_z jmp #:L43 'jump to decay/sustain if not + add level1acc, level1inc 'add increment to accum + mov R0, level1acc 'divisor (attack time) already in R1 + call #Divide 'obtain scaled level + and R0, HexFFFF 'get rid of remainder + add R0, level1init ' add to starting level + mov level1, R0 ' and we have the current envelope level + sub t1cnt, #1 'decrement attack time counter + cmp t1cnt, #0 wz 'end of attack phase? + if_nz jmp #:L51 'jump if yes + and env_cycle, #%110 'switch to decay/sustain if yes + mov t1cnt, R2 'set envelope time counter to decay counter + mov level1init, level1 'set initial decay level + mov level1inc, level1init ' and compute increment accordingly + sub level1inc, R3 + mov level1acc, #0 'reset accumulator + jmp #:L51 + +:L43 cmp t1cnt, #0 wz 'end of decay phase? + if_nz jmp #:L45 'jump if not, else sustain + cmp R3, level1 wc 'current level > sustain? + if_nc jmp #:L51 'jump if not + add level1acc, level1 'else track level + jmp #:L47 +:L45 sub t1cnt, #1 'else decrement decay counter + add level1acc, level1inc 'add increment to accumulator +:L47 mov R0, level1acc + mov R1, R2 'get divisor (decay time) into R1 + call #Divide + and R0, HexFFFF 'get rid of remainder + mov level1, level1init + sub level1, R0 'subtract from initial level + mins level1, #0 + jmp #:L51 + +:L42 test gate_edge, #%001 wz 'gate just released? + and gate_edge, #%110 + if_z jmp #:L46 + mov t1cnt, R4 'prepare for release cycle + mov level1init, level1 + mov level1inc, level1 + mov level1acc, #0 +:L46 cmp t1cnt, #0 wz 'end of release cycle? + if_z mov level1, #0 'silence voice if yes + if_z jmp #:L51 ' and skip processing + add level1acc, level1inc + mov R0, level1acc + mov R1, R4 + call #Divide + and R0, HexFFFF + mov level1, level1init + sub level1, R0 + mins level1, #0 'don't go below zero + sub t1cnt, #1 'decrement release counter + +:L51 'Voice 2 + rdbyte R0, voice2creg 'load values + rdword R1, attack2time + rdword R2, decay2time + rdword R3, sustain2level + rdword R4, release2time + test R0, #CREG_GATE wz 'if gate bit is set then process attack, decay and sustain + if_z jmp #:L52 ' else release + test gate_edge, #%010 wz 'gate just applied? + or gate_edge, #%010 + if_nz jmp #:L50 'jump if yes + or env_cycle, #%010 + mov t2cnt, R1 'else init attack phase, set counter to attack time + mov level2init, level2 'set initial level + mov level2inc, max_level ' and compute increment accordingly + sub level2inc, level2init + mov level2acc, #0 'reset accumulator +:L50 test env_cycle, #%010 wz 'attack? + if_z jmp #:L53 'jump to decay/sustain if not + mov R6, R1 'save decay end time in R6 + add level2acc, level2inc 'add increment to accum + mov R0, level2acc 'divisor (attack time) already in R1 + call #Divide 'obtain scaled level + and R0, HexFFFF 'get rid of remainder + add R0, level2init ' add to starting level + mov level2, R0 ' and we have the current envelope level + sub t2cnt, #1 'decrement attack time counter + cmp t2cnt, #0 wz 'end of attack phase? + if_nz jmp #:L61 + and env_cycle, #%101 'switch to decay/sustain if yes + mov t2cnt, R2 'set envelope time counter to decay + mov level2init, level2 'set initial decay level + mov level2inc, level2init ' and compute increment accordingly + sub level2inc, R3 + mov level2acc, #0 'reset accumulator + jmp #:L61 + +:L53 cmp t2cnt, #0 wz 'end of decay phase? + if_nz jmp #:L55 'jump if not, else sustain + cmp R3, level2 wc 'current level > sustain? + if_nc jmp #:L61 'jump if not + add level2acc, level2 'else track level + jmp #:L57 +:L55 sub t2cnt, #1 'else decrement decay counter + add level2acc, level2inc 'add increment to accumulator +:L57 mov R0, level2acc + mov R1, R2 'get divisor (decay time) into R1 + call #Divide + and R0, HexFFFF 'get rid of remainder + mov level2, level2init + sub level2, R0 'subtract from initial level + mins level2, #0 + jmp #:L61 + +:L52 test gate_edge, #%010 wz 'gate just released? + and gate_edge, #%101 + if_z jmp #:L56 + mov t2cnt, R4 'prepare for release cycle + mov level2init, level2 + mov level2inc, level2 + mov level2acc, #0 +:L56 cmp t2cnt, #0 wz 'end of release cycle? + if_z mov level2, #0 'silence voice if yes + if_z jmp #:L61 ' and skip processing + add level2acc, level2inc + mov R0, level2acc + mov R1, R4 + call #Divide + and R0, HexFFFF + mov level2, level2init + sub level2, R0 + mins level2, #0 'don't go below zero + sub t2cnt, #1 'decrease release counter + +:L61 'Voice 3 + rdbyte R0, voice3creg 'load values + rdword R1, attack3time + rdword R2, decay3time + rdword R3, sustain3level + rdword R4, release3time + test R0, #CREG_GATE wz 'if gate bit is set then process attack, decay and sustain + if_z jmp #:L62 ' else release + test gate_edge, #%100 wz 'gate just applied? + or gate_edge, #%100 + if_nz jmp #:L60 'jump if yes + or env_cycle, #%100 + mov t3cnt, R1 'else init attack phase, set envelope time counter to attack + mov level3init, level3 'set initial level + mov level3inc, max_level ' and compute increment + sub level3inc, level3init ' accordingly + mov level3acc, #0 'reset accumulator +:L60 test env_cycle, #%100 wz 'attack? + if_z jmp #:L63 'jump to decay/sustain if not + mov R6, R1 'save decay end time in R6 + add level3acc, level3inc 'add increment to accum + mov R0, level3acc 'divisor (attack time) already in R1 + call #Divide 'obtain scaled level + and R0, HexFFFF 'get rid of remainder + add R0, level3init ' add to starting level + mov level3, R0 ' and we have the current envelope level + sub t3cnt, #1 'decrement attack time counter + cmp t3cnt, #0 wz 'end of attack phase? + if_nz jmp #:L41 + and env_cycle, #%011 'switch to decay/sustain if yes + mov t3cnt, R2 'reset envelope time counter, now decay counter + mov level3init, level3 'set initial decay level + mov level3inc, level3init ' and compute increment accordingly + sub level3inc, R3 + mov level3acc, #0 'reset accumulator + jmp #:L41 + +:L63 cmp t3cnt, #0 wz 'end of decay phase? + if_nz jmp #:L65 'jump if not, else sustain + cmp R3, level3 wc 'current level > sustain? + if_nc jmp #:L41 'jump if not + add level3acc, level3 'else track level + jmp #:L67 +:L65 sub t3cnt, #1 'else decrement decay counter + add level3acc, level3inc 'add increment to accumulator +:L67 mov R0, level3acc + mov R1, R2 'get divisor (decay time) into R1 + call #Divide + and R0, HexFFFF 'get rid of remainder + mov level3, level3init + sub level3, R0 'subtract from initial level + mins level3, #0 + jmp #:L41 + +:L62 test gate_edge, #%100 wz 'gate just released? + and gate_edge, #%011 + if_z jmp #:L66 + mov t3cnt, R4 'prepare for release cycle + mov level3init, level3 + mov level3inc, level3 + mov level3acc, #0 +:L66 cmp t3cnt, #0 wz 'end of release cycle? + if_z mov level3, #0 'silence voice if yes + if_z jmp #:L41 ' and skip processing + add level3acc, level3inc + mov R0, level3acc + mov R1, R4 + call #Divide + and R0, HexFFFF + mov level3, level3init + sub level3, R0 + mins level3, #0 'don't go below zero + sub t3cnt, #1 'decrement release counter + +:L41 ' Mixer (simple adder) + rdbyte R1, modevol 'get mode bits into R3 + mov R0, sig1 + add R0, sig2 + test R1, #MREG_VOICE3OFF wz 'check if voice 3 is disabled + if_z add R0, sig3 + and R1, #$0F 'get main volume bits + call #Mult 'multiply by signal level + shr R1, #4 'scale result + mov value, R1 + +:L2 waitcnt time, period 'wait until next period + neg phsa, value + jmp #:loop 'loop for next cycle + +'──────────────────────────────────────────────────────────────────────────────────────── + +' Multiply R0[15..0] by R1[15..0] (R1[31..16] must be 0) +' On exit, product is in R1[31..0] + +Mult shl R0, #16 'get multiplicand into R0[31..16] + mov R5, #16 'ready for 16 multiplier bits + shr R1, #1 wc 'get initial multiplier bit into c +:m1 if_c add R1, R0 wc 'if c set, add multiplicand to product + rcr R1, #1 wc 'put next multiplier in c, shift prod. + djnz R5, #:m1 'loop until done +Mult_ret ret + +' Divide R0[31..0] by R1[15..0] (R1[16] must be 0) +' On exit, quotient is in R0[15..0] and remainder is in R0[31..16] + +Divide shl R1, #15 'get divisor into R1[30..15] + mov R5, #16 'ready for 16 quotient bits +:d1 cmpsub R0, R1 wc 'R1 =< R0? Subtract it, quotient bit in c + rcl R0, #1 'rotate c into quotient, shift dividend + djnz R5, #:d1 'loop until done +divide_ret ret 'quotient in R0[15..0], remainder in R0[31..16] + +'──────────────────────────────────────────────────────────────────────────────────────── + +d0 long 1 << 9 << 0 + +Hex4000 long $4000 +Hex8000 long $8000 +HexFFFF long $FFFF +Hex10000 long $10000 + +max_level long MAXLEVEL + +noise long $6DE7 + +cnt_msec res 1 + +period res 1 +diraval res 1 '|< pin +ctraval res 1 '%00100 << 26 + pin (NCO/PWM + pin) + +voice1creg res 1 +voice1freq res 1 +voice1pw res 1 +attack1time res 1 +decay1time res 1 +sustain1level res 1 +release1time res 1 + +voice2creg res 1 +voice2freq res 1 +voice2pw res 1 +attack2time res 1 +decay2time res 1 +sustain2level res 1 +release2time res 1 + +voice3creg res 1 +voice3freq res 1 +voice3pw res 1 +attack3time res 1 +decay3time res 1 +sustain3level res 1 +release3time res 1 + +resfilt res 1 +modevol res 1 + +time res 1 +value res 1 + +switch res 1 +next_phase res 1 + +phase1 res 1 +phase2 res 1 +phase3 res 1 + +level1 res 1 +level2 res 1 +level3 res 1 + +level1acc res 1 +level2acc res 1 +level3acc res 1 + +level1inc res 1 +level2inc res 1 +level3inc res 1 + +level1init res 1 +level2init res 1 +level3init res 1 + +sig1 res 1 +sig2 res 1 +sig3 res 1 + +noise1 res 1 +noise2 res 1 +noise3 res 1 + +t1cnt res 1 +t2cnt res 1 +t3cnt res 1 + +env_cycle res 1 'envelope cycle: bits 0..2 set if voice 1..3 starts attack on next gate +gate_edge res 1 'gate edge detection: bits 0..2 if up transition detected for voice 1..3 + +R0 res 1 +R1 res 1 +R2 res 1 +R3 res 1 +R4 res 1 +R5 res 1 +R6 res 1 + + fit \ No newline at end of file diff --git a/source/boulder/bellatrix/Scroller.spin b/source/boulder/bellatrix/Scroller.spin new file mode 100644 index 0000000..1b4471a --- /dev/null +++ b/source/boulder/bellatrix/Scroller.spin @@ -0,0 +1 @@ +' This cog takes care of the smooth scrolling and animates animated objects.' Also:' - flashes the screen when the game target is reached' - signals about new life with random background patternvar long x, y, nx, ny long scroll_addr long tile_addr long palette_addr long stack[12] long rockford_dir long random_addr long vsync_addr byte flash_cnt byte new_life_cnt byte tapping byte blinking byte wall_millingpub start(video_params, rnd_addr) x := 0 y := 0 vsync_addr := long[video_params + constant(6 * 4)] random_addr := rnd_addr palette_addr := long[video_params + constant(5 * 4)] + constant(40 * 28) scroll_addr := palette_addr + 4 tile_addr := scroll_addr + constant(4 + 4 + 20 * 2) rockford_dir := 0 flash_cnt := 0 new_life_cnt := 0 blinking := 0 tapping := 0 wall_milling := 0 cognew(process, @stack)pub scroll_to(sx, sy) nx := sx ny := sypub rockford_reset blinking := 0 tapping := 0pub rockford_go(dir) rockford_dir := dir if rockford_dir <> 0 blinking := 0 tapping := 0pub flash flash_cnt := 6pub new_life new_life_cnt := 400pub milling_on wall_milling := 1pub milling_off wall_milling := 0pub process | i, n, cp, temp n := 0 i := 0 repeat 'wait for vsync repeat while byte[vsync_addr] == 0 repeat while byte[vsync_addr] <> 0 if x <> nx or y <> ny if x > nx x := x - 1 elseif x < nx x := x + 1 if y > ny y := y - 2 elseif y < ny y := y + 2 long[scroll_addr] := (x << 16) + y if i == 0 'rockford if rockford_dir > 0 cp := @rockford_right + n elseif rockford_dir < 0 cp := @rockford_left + n else cp := @rockford if n == 0 if (byte[random_addr] & $03) == 0 blinking := 1 else blinking := 0 if (byte[random_addr] & $0F) == 0 tapping ^= 1 ifnot blinking or tapping wordmove(tile_addr + constant(32 * $38), cp, 16) wordmove(tile_addr + constant(32 * $39), cp, 16) else if blinking cp := @rockford_bored + n wordmove(tile_addr + constant(32 * $38), cp, 8) ' top part only wordmove(tile_addr + constant(32 * $39), cp, 8) if tapping cp := @rockford_bored + 16 + n wordmove(tile_addr + constant(32 * $38 + 16), cp, 8) ' bottom part only wordmove(tile_addr + constant(32 * $39 + 16), cp, 8) ' diamonds cp := @diamonds + n wordmove(tile_addr + constant(32 * $14), cp, 16) ' update all 4 variants wordmove(tile_addr + constant(32 * $15), cp, 16) wordmove(tile_addr + constant(32 * $16), cp, 16) wordmove(tile_addr + constant(32 * $17), cp, 16) ' fireflies cp := @firefly + n wordmove(tile_addr + constant(32 * $08), cp, 16) ' update all 8 variants wordmove(tile_addr + constant(32 * $09), cp, 16) wordmove(tile_addr + constant(32 * $0A), cp, 16) wordmove(tile_addr + constant(32 * $0B), cp, 16) wordmove(tile_addr + constant(32 * $0C), cp, 16) wordmove(tile_addr + constant(32 * $0D), cp, 16) wordmove(tile_addr + constant(32 * $0E), cp, 16) wordmove(tile_addr + constant(32 * $0F), cp, 16) ' butterflies cp := @butterfly + n wordmove(tile_addr + constant(32 * $30), cp, 16) ' update all 8 variants wordmove(tile_addr + constant(32 * $31), cp, 16) wordmove(tile_addr + constant(32 * $32), cp, 16) wordmove(tile_addr + constant(32 * $33), cp, 16) wordmove(tile_addr + constant(32 * $34), cp, 16) wordmove(tile_addr + constant(32 * $35), cp, 16) wordmove(tile_addr + constant(32 * $36), cp, 16) wordmove(tile_addr + constant(32 * $37), cp, 16) ' amoeba cp := @amoeba + n wordmove(tile_addr + constant(32 * $3A), cp, 16) wordmove(tile_addr + constant(32 * $3B), cp, 16) ' magic wall if wall_milling wordmove(tile_addr + constant(32 * $03), @magic_wall + (n & $60), 16) else wordmove(tile_addr + constant(32 * $03), @wall, 16) ' flashing door if n & 128 wordmove(tile_addr + constant(32 * $05), @door_frame, 16) wordmove(tile_addr + constant(32 * $25), @door_frame, 16) else wordmove(tile_addr + constant(32 * $05), tile_addr + constant(32 * $07), 16) wordmove(tile_addr + constant(32 * $25), tile_addr + constant(32 * $07), 16) n += 32 if n => constant(32 * 8) n := 0 i ^= 1 ' scrolling steel wall cp := tile_addr + constant(32 * $3C) temp := word[cp] wordmove(cp, cp + 2, 15) word[cp + 31] := temp if flash_cnt > 0 if --flash_cnt > 0 byte[palette_addr + 0] := $07 else byte[palette_addr + 0] := $02 if i == 0 and new_life_cnt > 0 if new_life_cnt-- == 1 wordfill(tile_addr, $00, 16) else cp := byte[random_addr] byte[tile_addr] := cp byte[tile_addr + 9] := cp cp := byte[random_addr] byte[tile_addr + 8] := cp byte[tile_addr + 1] := cp cp := byte[random_addr] byte[tile_addr + 16] := cp byte[tile_addr + 25] := cp cp := byte[random_addr] byte[tile_addr + 24] := cp byte[tile_addr + 17] := cpdat' animated creatures, 8 frames per each' -- amoebaamoeba word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_3 word %%0_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_3 word %%0_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_2_0 word %%0_2_3_3_3_2_2_0 word %%2_3_3_3_3_3_2_0 word %%3_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_2_0 word %%0_2_3_3_3_2_2_0 word %%2_3_3_3_3_3_2_0 word %%3_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_2_0_0_0_2_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_2_0 word %%3_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_2_0_0_0_2_3 word %%3_3_2_0_0_0_2_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_2_0 word %%3_3_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_2_0_0_0_2_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_3 word %%0_2_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%2_2_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_2_0_2_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_3_3_3_3_3_3_3 word %%0_2_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%2_2_3_3_3_3_3_2 word %%0_2_3_3_3_3_2_0 word %%2_2_3_3_3_3_3_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_2_3_3_3 word %%3_3_3_2_0_2_3_3' -- firefliesfirefly word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_3_3_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_2_2_2_2_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_2_2_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_3_3_3_3_2_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%2_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_0_0_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_2_2_2_2_3_2 word %%2_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_2 word %%2_2_2_2_2_2_2_2 word %%2_2_2_2_2_2_2_2 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_2_2_2_2_2_2_3 word %%3_2_2_2_2_2_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_2_2_2_2_2_3 word %%3_2_2_2_2_2_2_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3 word %%3_2_2_2_2_2_2_3 word %%3_2_2_2_2_2_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_2_2_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_0_0_0_0_2_3 word %%3_2_2_2_2_2_2_3 word %%3_2_2_2_2_2_2_3 word %%3_3_3_3_3_3_3_3 word %%3_3_3_3_3_3_3_3' -- diamondsdiamonds word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_3_3_3_0_0 word %%0_0_1_3_3_2_0_0 word %%0_2_2_2_2_2_3_0 word %%0_1_1_1_1_1_2_0 word %%2_0_0_0_0_0_0_3 word %%1_0_0_0_0_0_0_2 word %%2_1_1_1_1_1_1_3 word %%1_2_2_2_2_2_2_2 word %%0_2_3_3_3_3_3_0 word %%0_1_3_3_3_3_2_0 word %%0_0_2_2_2_3_0_0 word %%0_0_1_1_1_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_3_3_3_0_0 word %%0_0_1_2_2_2_0_0 word %%0_2_1_1_1_1_3_0 word %%0_1_0_0_0_0_2_0 word %%2_0_0_0_0_0_0_3 word %%1_1_1_1_1_1_1_2 word %%2_2_2_2_2_2_2_3 word %%1_3_3_3_3_3_3_2 word %%0_2_3_3_3_3_3_0 word %%0_1_2_2_2_2_2_0 word %%0_0_2_1_1_3_0_0 word %%0_0_1_0_0_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_2_2_3_0_0 word %%0_0_1_1_1_2_0_0 word %%0_2_0_0_0_0_3_0 word %%0_1_0_0_0_0_2_0 word %%2_1_1_1_1_1_1_3 word %%1_2_2_2_2_2_2_2 word %%2_3_3_3_3_3_3_3 word %%1_3_3_3_3_3_3_2 word %%0_2_2_2_2_2_3_0 word %%0_1_1_1_1_1_2_0 word %%0_0_2_0_0_3_0_0 word %%0_0_1_0_0_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_1_1_3_0_0 word %%0_0_1_0_0_2_0_0 word %%0_2_0_0_0_0_3_0 word %%0_1_1_1_1_1_2_0 word %%2_2_2_2_2_2_2_3 word %%1_3_3_3_3_3_3_2 word %%2_3_3_3_3_3_3_3 word %%1_2_2_2_2_2_2_2 word %%0_2_1_1_1_1_3_0 word %%0_1_0_0_0_0_2_0 word %%0_0_2_0_0_3_0_0 word %%0_0_1_1_1_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_0_0_3_0_0 word %%0_0_1_0_0_2_0_0 word %%0_2_1_1_1_1_3_0 word %%0_1_2_2_2_2_2_0 word %%2_3_3_3_3_3_3_3 word %%1_3_3_3_3_3_3_2 word %%2_2_2_2_2_2_2_3 word %%1_1_1_1_1_1_1_2 word %%0_2_0_0_0_0_3_0 word %%0_1_0_0_0_0_2_0 word %%0_0_2_1_1_3_0_0 word %%0_0_1_2_2_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_0_0_3_0_0 word %%0_0_1_1_1_2_0_0 word %%0_2_2_2_2_2_3_0 word %%0_1_3_3_3_3_2_0 word %%2_3_3_3_3_3_3_3 word %%1_2_2_2_2_2_2_2 word %%2_1_1_1_1_1_1_3 word %%1_0_0_0_0_0_0_2 word %%0_2_0_0_0_0_3_0 word %%0_1_1_1_1_1_2_0 word %%0_0_2_2_2_3_0_0 word %%0_0_1_3_3_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_1_1_3_0_0 word %%0_0_1_2_2_2_0_0 word %%0_2_3_3_3_3_3_0 word %%0_1_3_3_3_3_2_0 word %%2_2_2_2_2_2_2_3 word %%1_1_1_1_1_1_1_2 word %%2_0_0_0_0_0_0_3 word %%1_0_0_0_0_0_0_2 word %%0_2_1_1_1_1_3_0 word %%0_1_2_2_2_2_2_0 word %%0_0_2_3_3_3_0_0 word %%0_0_1_3_3_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_2_3_0_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_2_2_2_3_0_0 word %%0_0_1_3_3_2_0_0 word %%0_2_3_3_3_3_3_0 word %%0_1_2_2_2_2_2_0 word %%2_1_1_1_1_1_1_3 word %%1_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_3 word %%1_1_1_1_1_1_1_2 word %%0_2_2_2_2_2_3_0 word %%0_1_3_3_3_3_2_0 word %%0_0_2_3_3_3_0_0 word %%0_0_1_2_2_2_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_1_1_0_0_0' -- butterfliesbutterfly word %%3_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_1 word %%3_3_0_0_0_0_2_3 word %%3_2_0_0_0_0_1_3 word %%2_2_3_0_0_2_2_2 word %%1_1_2_0_0_1_1_1 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%1_1_1_3_2_1_1_1 word %%2_2_2_2_1_2_2_2 word %%3_3_3_0_0_2_3_3 word %%3_3_2_0_0_1_3_3 word %%2_3_0_0_0_0_2_2 word %%1_2_0_0_0_0_1_1 word %%2_0_0_0_0_0_0_1 word %%1_0_0_0_0_0_0_1 word %%3_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_1 word %%3_3_0_0_0_0_2_3 word %%3_2_0_0_0_0_1_3 word %%2_2_3_0_0_2_2_2 word %%1_1_2_0_0_1_1_1 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%1_1_1_3_2_1_1_1 word %%2_2_2_2_1_2_2_2 word %%3_3_3_0_0_2_3_3 word %%3_3_2_0_0_1_3_3 word %%2_3_0_0_0_0_2_2 word %%1_2_0_0_0_0_1_1 word %%2_0_0_0_0_0_0_1 word %%1_0_0_0_0_0_0_1 word %%0_3_0_0_0_0_2_0 word %%0_3_0_0_0_0_2_0 word %%0_2_0_0_0_0_1_0 word %%0_2_0_0_0_0_1_0 word %%0_2_3_0_0_2_2_0 word %%0_1_2_0_0_1_1_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_1_1_3_2_1_1_0 word %%0_2_2_2_1_2_2_0 word %%0_3_3_0_0_2_3_0 word %%0_3_2_0_0_1_3_0 word %%0_3_0_0_0_0_2_0 word %%0_2_0_0_0_0_1_0 word %%0_2_0_0_0_0_2_0 word %%0_1_0_0_0_0_1_0 word %%0_0_3_0_0_2_0_0 word %%0_0_2_0_0_1_0_0 word %%0_0_3_0_0_2_0_0 word %%0_0_2_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_3_0_0_2_0_0 word %%0_0_2_0_0_1_0_0 word %%0_0_3_0_0_2_0_0 word %%0_0_2_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_0_0_0_0_2_0 word %%0_3_0_0_0_0_2_0 word %%0_2_0_0_0_0_1_0 word %%0_2_0_0_0_0_1_0 word %%0_2_3_0_0_2_2_0 word %%0_1_2_0_0_1_1_0 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%0_1_1_3_2_1_1_0 word %%0_2_2_2_1_2_2_0 word %%0_3_3_0_0_2_3_0 word %%0_3_2_0_0_1_3_0 word %%0_3_0_0_0_0_2_0 word %%0_2_0_0_0_0_1_0 word %%0_2_0_0_0_0_2_0 word %%0_1_0_0_0_0_1_0 word %%3_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_1 word %%3_3_0_0_0_0_2_3 word %%3_2_0_0_0_0_1_3 word %%2_2_3_0_0_2_2_2 word %%1_1_2_0_0_1_1_1 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%1_1_1_3_2_1_1_1 word %%2_2_2_2_1_2_2_2 word %%3_3_3_0_0_2_3_3 word %%3_3_2_0_0_1_3_3 word %%2_3_0_0_0_0_2_2 word %%1_2_0_0_0_0_1_1 word %%2_0_0_0_0_0_0_1 word %%1_0_0_0_0_0_0_1 word %%3_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_1 word %%3_3_0_0_0_0_2_3 word %%3_2_0_0_0_0_1_3 word %%2_2_3_0_0_2_2_2 word %%1_1_2_0_0_1_1_1 word %%0_0_0_3_2_0_0_0 word %%0_0_0_2_1_0_0_0 word %%1_1_1_3_2_1_1_1 word %%2_2_2_2_1_2_2_2 word %%3_3_3_0_0_2_3_3 word %%3_3_2_0_0_1_3_3 word %%2_3_0_0_0_0_2_2 word %%1_2_0_0_0_0_1_1 word %%2_0_0_0_0_0_0_1 word %%1_0_0_0_0_0_0_1' rockford' walking leftrockford_left word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_1_0 word %%0_1_0_0_0_0_0_3 word %%0_1_0_0_0_0_0_3 word %%3_3_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_1_0 word %%0_1_0_0_0_0_0_3 word %%0_1_0_0_0_0_0_3 word %%3_3_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_1_3 word %%0_0_1_0_0_0_0_3 word %%0_3_3_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_0_0_0 word %%0_0_1_0_1_1_1_0 word %%0_0_1_0_0_1_3_0 word %%0_3_3_0_0_0_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_0_1_1_3_0_0 word %%0_0_3_3_0_3_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_1_1_1_0_0_0 word %%0_0_1_1_1_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_1_1_1_0_0_0 word %%0_0_1_1_1_0_0_0 word %%0_0_3_3_3_3_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_2_0_2_2_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_3_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_0_0_0 word %%0_0_1_0_1_1_1_0 word %%0_0_1_0_0_1_3_0 word %%0_3_3_0_0_0_3_0' walking rightrockford_right word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_1_1_3_3_1_0_0 word %%3_0_0_0_0_0_1_0 word %%3_0_0_0_0_0_1_0 word %%0_0_0_0_0_0_3_3 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_1_1_3_3_1_0_0 word %%3_0_0_0_0_0_1_0 word %%3_0_0_0_0_0_1_0 word %%0_0_0_0_0_0_3_3 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%3_1_1_1_0_1_0_0 word %%3_0_0_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_1_0_0 word %%0_1_1_1_0_1_0_0 word %%0_3_1_0_0_1_0_0 word %%0_3_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_1_1_0_0_0 word %%0_0_3_1_1_0_0_0 word %%0_0_3_0_3_3_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_1_1_1_0_0 word %%0_0_0_1_1_1_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_1_1_1_0_0 word %%0_0_0_1_1_1_0_0 word %%0_0_3_3_3_3_0_0 word %%0_0_0_0_0_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_0_3_3_1_0_0 word %%0_1_1_1_0_1_0_0 word %%0_3_1_0_0_1_0_0 word %%0_3_0_0_0_3_3_0' blinking eyes / tapping footrockford_bored word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_2_2_2_2_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_2_2_2_2_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_1_0_0 word %%0_0_0_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0 word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_0_3_2_2_3_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0' rockford, standingrockford word %%0_0_0_0_0_0_0_0 word %%0_0_2_0_0_2_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_2_2_0_2_0 word %%0_2_0_2_2_0_2_0 word %%0_0_2_2_2_2_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_2_2_2_2_0_0 word %%0_2_0_3_3_0_2_0 word %%0_3_0_2_2_0_3_0 word %%0_0_0_3_3_0_0_0 word %%0_0_0_2_2_0_0_0 word %%0_0_1_3_3_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_1_0_0_1_0_0 word %%0_3_3_0_0_3_3_0' diamond frame word %%0_0_0_1_1_0_0_0 word %%0_0_0_3_3_0_0_0 word %%0_0_1_0_0_1_0_0 word %%0_0_3_0_0_3_0_0 word %%0_1_0_0_0_0_1_0 word %%0_3_0_0_0_0_3_0 word %%1_0_0_0_0_0_0_1 word %%3_0_0_0_0_0_0_3 word %%1_0_0_0_0_0_0_2 word %%3_0_0_0_0_0_0_3 word %%0_1_0_0_0_0_2_0 word %%0_3_0_0_0_0_3_0 word %%0_0_1_0_0_2_0_0 word %%0_0_3_0_0_3_0_0 word %%0_0_0_1_2_0_0_0 word %%0_0_0_3_3_0_0_0' dummy word %%3_3_0_0_0_0_3_3 word %%0_3_3_3_3_3_3_0 word %%3_3_2_3_3_2_3_3 word %%3_3_2_3_3_2_3_3 word %%3_3_3_3_3_3_3_3 word %%0_3_3_0_0_3_3_0 word %%0_0_3_3_0_3_0_0 word %%0_0_2_2_2_2_0_0 word %%1_1_2_2_2_2_1_0 word %%1_0_2_2_2_2_0_1 word %%0_0_2_2_2_2_1_0 word %%0_3_3_3_3_3_3_0 word %%0_3_3_0_0_3_3_0 word %%0_3_0_0_0_0_3_0 word %%3_3_0_0_0_0_3_0 word %%0_0_0_0_0_0_3_3' wallwall word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_2_2_0_2_2_2 word %%0_0_0_0_0_0_0_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%2_2_0_2_2_2_0_2 word %%0_0_0_0_0_0_0_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_2_2_0_2_2_2 word %%0_0_0_0_0_0_0_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%2_2_0_2_2_2_0_2 word %%0_0_0_0_0_0_0_0' door framedoor_frame word %%2_2_2_2_2_2_2_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_0_0_0_0_0_0_2 word %%2_2_2_2_2_2_2_2' magic wallmagic_wall word %%3_3_3_3_3_3_3_3 word %%3_2_3_3_3_2_3_3 word %%3_2_2_2_3_2_2_2 word %%3_0_0_0_3_0_0_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_3_3_3_0_3 word %%2_2_0_3_2_2_0_3 word %%0_0_0_3_0_0_0_3 word %%3_3_3_3_3_3_3_3 word %%3_2_3_3_3_2_3_3 word %%3_2_2_2_3_2_2_2 word %%3_0_0_0_3_0_0_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_3_3_3_0_3 word %%2_2_0_3_2_2_0_3 word %%0_0_0_3_0_0_0_3 word %%0_3_3_3_0_3_3_3 word %%0_3_3_3_0_3_3_3 word %%0_3_2_2_0_3_2_2 word %%0_3_0_0_0_3_0_0 word %%3_3_3_3_3_3_3_3 word %%3_3_3_2_3_3_3_2 word %%2_2_3_2_2_2_3_2 word %%0_0_3_0_0_0_3_0 word %%0_3_3_3_0_3_3_3 word %%0_3_3_3_0_3_3_3 word %%0_3_2_2_0_3_2_2 word %%0_3_0_0_0_3_0_0 word %%3_3_3_3_3_3_3_3 word %%3_3_3_2_3_3_3_2 word %%2_2_3_2_2_2_3_2 word %%0_0_3_0_0_0_3_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_3_2_0_2_3_2 word %%0_0_3_0_0_0_3_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%2_3_0_2_2_3_0_2 word %%0_3_0_0_0_3_0_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_3_2_0_2_3_2 word %%0_0_3_0_0_0_3_0 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%2_3_0_2_2_3_0_2 word %%0_3_0_0_0_3_0_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_2_3_0_2_2_3 word %%0_0_0_3_0_0_0_3 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%3_2_0_2_3_2_0_2 word %%3_0_0_0_3_0_0_0 word %%0_3_3_3_0_3_3_3 word %%0_2_3_3_0_2_3_3 word %%0_2_2_3_0_2_2_3 word %%0_0_0_3_0_0_0_3 word %%3_3_0_3_3_3_0_3 word %%3_3_0_2_3_3_0_2 word %%3_2_0_2_3_2_0_2 word %%3_0_0_0_3_0_0_0 \ No newline at end of file diff --git a/source/boulder/bellatrix/Sounds.spin b/source/boulder/bellatrix/Sounds.spin new file mode 100644 index 0000000..b49fc6c --- /dev/null +++ b/source/boulder/bellatrix/Sounds.spin @@ -0,0 +1,168 @@ +{ Hive-Soundobjekt für Boulderdash + +} + +'signaldefinitionen bellatrix + +#0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus +#8, BEL_VGABASE 'vga-signale (8pin) +#16, BEL_KEYBC,BEL_KEYBD 'keyboard-signale +#18, BEL_MOUSEC,BEL_MOUSED 'maus-signale +#20, BEL_VIDBASE 'video-signale(3pin) +#23, BEL_SELECT 'belatrix-auswahlsignal +#24, HBEAT 'front-led + BUSCLK 'bustakt + BUS_WR '/wr - schreibsignal + BUS_HS ' '/hs - quittungssignal + +var + +byte sndfx ' Kommando für Administra +byte fcCog ' Flag ob cCog gestartet +long cStack[32] ' Stack für cCog + + +pub Start: Pass + + Pass := (fcCog := cognew(cCog, @cStack)+1) > 0 + +pub cCog | cmd + + bus_init + repeat + repeat until sndfx > 0 'warte bis fx gesendet werden soll + bus_putchar(sndfx~) 'sndfx-Kommando senden + + +CON +' +' hbeat --------+ +' clk -------+| +' /wr ------+|| +' /hs -----+||| +------------------------- /cs +' |||| | -------- d0..d7 +DB_IN = %00001001_00000000_00000000_00000000 'maske: dbus-eingabe +DB_OUT = %00001001_00000000_00000000_11111111 'maske: dbus-ausgabe + +M1 = %00000010_00000000_00000000_00000000 +M2 = %00000010_10000000_00000000_00000000 'busclk=1? & /cs=0? + +M3 = %00000000_00000000_00000000_00000000 +M4 = %00000010_00000000_00000000_00000000 'busclk=0? + + +PUB bus_putchar(zeichen) 'BUS: Ein Byte über BUS ausgeben +{{ein byte über bus ausgeben Belltrix --> Regnatix}} + waitpeq(M1,M2,0) 'busclk=1? & prop2=0? + dira := db_out 'datenbus auf ausgabe stellen + outa[7..0] := zeichen 'daten ausgeben + outa[bus_hs] := 0 'daten gültig + waitpeq(M3,M4,0) 'busclk=0? + dira := db_in 'bus freigeben + outa[bus_hs] := 1 'daten ungültig + +PUB bus_getchar : zeichen 'BUS: Ein Byte über BUS empfangen +{{ein byte über bus empfangen Regnatix --> Bellatrix}} + waitpeq(M1,M2,0) 'busclk=1? & prop2=0? + zeichen := ina[7..0] 'daten einlesen + outa[bus_hs] := 0 'daten quittieren + outa[bus_hs] := 1 + waitpeq(M3,M4,0) 'busclk=0? + +PUB bus_init +{{initialisierung des bussystems}} + dira := db_in 'datenbus auf eingabe schalten + outa[bus_hs] := 1 'handshake inaktiv + + +dat 'soundadapter + +con + +_music_on = 1 +_music_off = 2 +_moving_sound1 = 3 +_moving_sound2 = 4 +_boulder_sound = 5 +_diamond_sound = 6 +_pick_sound = 7 +_explosion_sound = 8 +_crack_sound = 9 +_magic_wall_sound_on = 10 +_magic_wall_sound_off = 11 +_amoeba_sound_on = 12 +_amoeba_sound_off = 13 +_time_ending_sound = 14 +_bonus_point_sound = 15 +_cover_sound = 16 + +pub music_on + sndfx := _music_on + +pub music_off + sndfx := _music_off + +pub moving_sound(surface) + repeat until sndfx == 0 + if surface == $00 + sndfx := _moving_sound1 + else ' $01 + sndfx := _moving_sound2 + repeat until sndfx == 0 + +pub boulder_sound + sndfx := _boulder_sound + +pub diamond_sound + repeat until sndfx == 0 + sndfx := _diamond_sound + repeat until sndfx == 0 + +pub pick_sound + repeat until sndfx == 0 + sndfx := _pick_sound + repeat until sndfx == 0 + +pub explosion_sound + repeat until sndfx == 0 + sndfx := _explosion_sound + repeat until sndfx == 0 + +pub crack_sound + repeat until sndfx == 0 + sndfx := _crack_sound + repeat until sndfx == 0 + +pub magic_wall_sound_on + repeat until sndfx == 0 + sndfx := _magic_wall_sound_on + repeat until sndfx == 0 + +pub magic_wall_sound_off + repeat until sndfx == 0 + sndfx := _magic_wall_sound_off + repeat until sndfx == 0 + +pub amoeba_sound_on + repeat until sndfx == 0 + sndfx := _amoeba_sound_on + repeat until sndfx == 0 + +pub amoeba_sound_off + 'sndfx := _amoeba_sound_off + +pub time_ending_sound(sec_left) + repeat until sndfx == 0 + sndfx := _time_ending_sound + repeat until sndfx == 0 + +pub bonus_point_sound(pts) + repeat until sndfx == 0 + sndfx := _bonus_point_sound + repeat until sndfx == 0 + +pub cover_sound + sndfx := _cover_sound + + + \ No newline at end of file diff --git a/source/boulder/bellatrix/Sounds_old.spin b/source/boulder/bellatrix/Sounds_old.spin new file mode 100644 index 0000000..6be2fa9 --- /dev/null +++ b/source/boulder/bellatrix/Sounds_old.spin @@ -0,0 +1,358 @@ +var + + long vsync_addr + long random_addr + long stack[40] + + byte music + byte mute + byte amoeba + byte magic_wall + byte v1cnt, v1ctl + byte v2cnt, v2ctl + byte v3cnt, v3ctl + +obj + + sd : "SIDemu" + +pub start(video_params, pin, rnd_addr) + + vsync_addr := long[video_params + constant(6 * 4)] + random_addr := rnd_addr + + v1cnt := 0 + v2cnt := 0 + v3cnt := 0 + + mute := false + music := false + amoeba := false + magic_wall := false + + cognew(process, @stack) + + sd.start(pin) + + sd.set_register(23, $07) 'turn main volume half-up + +pub music_on + + v1cnt := 0 + v2cnt := 0 + v3cnt := 0 + + music_init + + music := true + +pub music_off + + sd.set_register(4, sd#CREG_TRIANGLE) 'gate off + sd.set_register(11, sd#CREG_TRIANGLE) 'gate off + + music := false + +pub moving_sound(surface) + + if mute + return + + if surface == $00 + sd.set_register(7, $00) 'freq + sd.set_register(8, $35) + else ' $01 + sd.set_register(7, $00) 'freq + sd.set_register(8, $A5) + sd.set_register(12, $30) 'attack/decay + sd.set_register(13, $C0) 'sustain/release + sd.set_register(11, sd#CREG_NOISE | sd#CREG_GATE) + + v2ctl := sd#CREG_NOISE + v2cnt := 2 + +pub boulder_sound + + if mute + return + + if v1cnt + return + + sd.set_register(0, $32) 'freq + sd.set_register(1, $09) + sd.set_register(5, $00) 'attack/decay + sd.set_register(6, $F9) 'sustain/release + sd.set_register(4, sd#CREG_NOISE | sd#CREG_GATE) + + v1ctl := sd#CREG_NOISE + v1cnt := 1 + +pub diamond_sound + + if mute + return + + if v1cnt + return + + sd.set_register(0, byte[random_addr]) 'freq + sd.set_register(1, $86 + byte[random_addr] & $07) + sd.set_register(5, $00) 'attack/decay + sd.set_register(6, $F0) 'sustain/release + sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) + + v1ctl := sd#CREG_TRIANGLE + v1cnt := 2 + +pub pick_sound + + if mute + return + + if v1cnt + return + + sd.set_register(0, $78) 'freq + sd.set_register(1, $14) + sd.set_register(5, $00) 'attack/decay + sd.set_register(6, $F9) 'sustain/release + sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) + + v1ctl := sd#CREG_TRIANGLE + v1cnt := 1 + +pub explosion_sound + + if mute + return + + if v1cnt + return + + sd.set_register(0, $32) 'freq + sd.set_register(1, $14) + sd.set_register(5, $19) '$1D 'attack/decay + sd.set_register(6, $00) 'sustain/release + sd.set_register(4, sd#CREG_NOISE | sd#CREG_GATE) + + v1ctl := sd#CREG_NOISE + v1cnt := 200 + +pub crack_sound + + if mute + return + + if v3cnt + return + + sd.set_register(19, $19) 'attack/decay + sd.set_register(20, $01) 'sustain/release + sd.set_register(14, $32) 'freq + sd.set_register(15, $2F) + sd.set_register(18, sd#CREG_NOISE | sd#CREG_GATE) + + v3ctl := sd#CREG_NOISE + v3cnt := 80 + +pub magic_wall_sound_on + + if not magic_wall + magic_wall := true + sd.set_register(18, sd#CREG_TRIANGLE) + +pub magic_wall_sound_off + + if magic_wall + magic_wall := false + v3ctl := sd#CREG_TRIANGLE + v3cnt := 1 + +pub amoeba_sound_on + + if not amoeba + amoeba := true + sd.set_register(18, sd#CREG_TRIANGLE) + +pub amoeba_sound_off + + if amoeba + amoeba := false + v3ctl := sd#CREG_TRIANGLE + v3cnt := 1 + +var + + byte last_val + +pub time_ending_sound(sec_left) + + mute := true + + if sec_left == last_val + return + + last_val := sec_left + + if sec_left == 0 + mute := false + + sd.set_register(4, sd#CREG_TRIANGLE) + waitcnt(clkfreq / 1000 + cnt) + + sd.set_register(0, $00) + sd.set_register(1, $27 - sec_left) + sd.set_register(5, $0A) 'attack/decay + sd.set_register(6, $00) 'sustain/release + sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) + + v1cnt := 0 + +pub bonus_point_sound(pts) | i + + sd.set_register(5, $00) 'attack/decay + sd.set_register(6, $A0) 'sustain/release + sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) + repeat i from 2 to 30 step 2 + sd.set_register(0, $00) + sd.set_register(1, $B0 - pts + i) + waitcnt(clkfreq / 500 + cnt) + sd.set_register(4, sd#CREG_TRIANGLE) + +pub cover_sound + + if v2cnt + return + + sd.set_register(12, $05) 'attack/decay + sd.set_register(13, $00) 'sustain/release + sd.set_register(7, $00) + sd.set_register(8, $64 + byte[random_addr] & $7F) 'freq + sd.set_register(11, sd#CREG_TRIANGLE | sd#CREG_GATE) + + v2ctl := sd#CREG_TRIANGLE + v2cnt := 1 + +pub process | r + + repeat + + 'wait for vsync + repeat while byte[vsync_addr] == 0 + repeat while byte[vsync_addr] <> 0 + + if music + play_note + + if v1cnt + if --v1cnt == 0 + sd.set_register(4, v1ctl) + + if v2cnt + if --v2cnt == 0 + sd.set_register(11, v2ctl) + + if v3cnt + if --v3cnt == 0 + sd.set_register(18, v3ctl) + + if amoeba + if mute + sd.set_register(18, sd#CREG_TRIANGLE) + else + sd.set_register(19, $00) 'attack/decay + sd.set_register(20, $40) 'sustain/release + repeat + r := byte[random_addr] & $1F + while r < $07 + sd.set_register(14, $00) 'freq + sd.set_register(15, r) + sd.set_register(18, sd#CREG_TRIANGLE | sd#CREG_GATE) + v3cnt := 2 + + elseif magic_wall + if mute + sd.set_register(18, sd#CREG_TRIANGLE) + else + sd.set_register(19, $00) 'attack/decay + sd.set_register(20, $A0) 'sustain/release + r := byte[random_addr] & $03 + sd.set_register(14, $00) 'freq + sd.set_register(15, $86 + (r << 3)) + sd.set_register(18, sd#CREG_TRIANGLE | sd#CREG_GATE) + v3cnt := 2 + +dat + +notes + byte $16, $22, $1D, $26, $22, $29, $25, $2E, $14, $24, $1F, $27, $20, $29, $27, $30 + byte $12, $2A, $12, $2C, $1E, $2E, $12, $31, $20, $2C, $33, $37, $21, $2D, $31, $35 + byte $16, $22, $16, $2E, $16, $1D, $16, $24, $14, $20, $14, $30, $14, $24, $14, $20 + byte $16, $22, $16, $2E, $16, $1D, $16, $24, $1E, $2A, $1E, $3A, $1E, $2E, $1E, $2A + byte $14, $20, $14, $2C, $14, $1B, $14, $22, $1C, $28, $1C, $38, $1C, $2C, $1C, $28 + byte $11, $1D, $29, $2D, $11, $1F, $29, $2E, $0F, $27, $0F, $27, $16, $33, $16, $27 + byte $16, $2E, $16, $2E, $16, $2E, $16, $2E, $22, $2E, $22, $2E, $16, $2E, $16, $2E + byte $14, $2E, $14, $2E, $14, $2E, $14, $2E, $20, $2E, $20, $2E, $14, $2E, $14, $2E + byte $16, $2E, $32, $2E, $16, $2E, $33, $2E, $22, $2E, $32, $2E, $16, $2E, $33, $2E + byte $14, $2E, $32, $2E, $14, $2E, $33, $2E, $20, $2C, $30, $2C, $14, $2C, $31, $2C + byte $16, $2E, $16, $3A, $16, $2E, $35, $38, $22, $2E, $22, $37, $16, $2E, $31, $35 + byte $14, $2C, $14, $38, $14, $2C, $14, $38, $20, $2C, $20, $33, $14, $2C, $14, $38 + byte $16, $2E, $32, $2E, $16, $2E, $33, $2E, $22, $2E, $32, $2E, $16, $2E, $33, $2E + byte $14, $2E, $32, $2E, $14, $2E, $33, $2E, $20, $2C, $30, $2C, $14, $2C, $31, $2C + byte $2E, $32, $29, $2E, $26, $29, $22, $26, $2C, $30, $27, $2C, $24, $27, $14, $20 + byte $35, $32, $32, $2E, $2E, $29, $29, $26, $27, $30, $24, $2C, $20, $27, $14, $20 + +freqs + word $02DC, $030A, $033A, $036C, $03A0, $03D2, $0412, $044C + word $0492, $04D6, $0520, $056E, $05B8, $0614, $0674, $06D8 + word $0740, $07A4, $0824, $0898, $0924, $09AC, $0A40, $0ADC + word $0B70, $0C28, $0CE8, $0DB0, $0E80, $0F48, $1048, $1130 + word $1248, $1358, $1480, $15B8, $16E0, $1850, $19D0, $1B60 + word $1D00, $1E90, $2090, $2260, $2490, $26B0, $2900, $2B70 + word $2DC0, $0100, $0200, $0101, $0105, $0100, $0101, $0306 + word $0101, $0102, $0101 + +var + + long note + byte v1sr + +pri music_init + + note := 0 + v1sr := $B0 + + sd.set_register(4, sd#CREG_TRIANGLE) + sd.set_register(5, $4F) + sd.set_register(6, $00) + + sd.set_register(11, sd#CREG_TRIANGLE) + sd.set_register(12, $24) '$78) + sd.set_register(13, $75) '$78) + +pub play_note | n, f + + if v1sr == $B0 + sd.set_register(4, sd#CREG_TRIANGLE) + sd.set_register(11, sd#CREG_TRIANGLE) + n := notes.byte[note++] + f := word[@freqs + 2*n - $14] + sd.set_register(0, f & $FF) + sd.set_register(1, f >> 8) + n := notes.byte[note++] + f := word[@freqs + 2*n - $14] + sd.set_register(7, f & $FF) + sd.set_register(8, f >> 8) + v1sr := $A0 + return + + if note == 256 + note := 0 + sd.set_register(6, v1sr | $01) + sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) + sd.set_register(11, sd#CREG_TRIANGLE | sd#CREG_GATE) + v1sr -= $10 + if v1sr < $40 + v1sr := $B0 + \ No newline at end of file diff --git a/source/boulder/bellatrix/Status.spin b/source/boulder/bellatrix/Status.spin new file mode 100644 index 0000000..dd1fb5c --- /dev/null +++ b/source/boulder/bellatrix/Status.spin @@ -0,0 +1 @@ +' This cog handles the status line.' Also keeps the real-time countercon STATUS_NONE, STATUS_PRE, STATUS_GAME, STATUS_PAUSE, STATUS_OUT_OF_TIME, STATUS_GAME_OVERvar long status_addr long stack[20] long vsync_addr long score byte ticks_per_sec byte tick_count byte time byte diamond_count byte diamond_value byte diamonds_needed byte player byte men byte cave byte level byte status_mode byte update byte status_temp[20*2] byte toggle byte decbuf[6]pub start(video_params) vsync_addr := long[video_params + constant(6 * 4)] status_addr := long[video_params + constant(5 * 4)] + constant(40 * 28 + 4 + 4) time := 0 status_mode := STATUS_NONE update := true toggle := 0 if long[video_params + constant(4 * 4)] == 0 ticks_per_sec := 60 'NTSC else ticks_per_sec := 50 'PAL cognew(process, @stack)pub player_params(p, m, c, l, s) player := p men := m cave := c level := l score := s pub cave_params(dn, dv, t) diamonds_needed := dn diamond_value := dv diamond_count := 0 time := t tick_count := ticks_per_secpub set_time(t) tick_count := ticks_per_sec time := t update := truepub get_time return timepub set_mode(m) status_mode := m update := truepub set_score(s) score := s update := truepub set_diamond_value(dv) diamond_value := dv update := truepub set_diamond_count(n) diamond_count := n update := truepub process repeat 'wait for vsync repeat while byte[vsync_addr] == 0 repeat while byte[vsync_addr] <> 0 if update update := false if status_mode == STATUS_NONE long[status_addr] &= !1 else long[status_addr] |= 1 if toggle longmove(status_addr, @status_temp, 10) toggle := 0 if status_mode == STATUS_PRE bytefill(status_addr + constant(4 + 20), $06, 20) if cave > 16 text_out(status_addr + 4, @bonus_life, 20) else text_out(status_addr + 4, @pre, 20) byte[status_addr + constant(4 + 8)] := player + $80 byte[status_addr + constant(4 + 11)] := men + $80 byte[status_addr + constant(4 + 17)] := cave + $90 byte[status_addr + constant(4 + 19)] := level + $81 elseif status_mode == STATUS_GAME byte[status_addr + constant(4 + 0)] := $90 if diamond_count => diamonds_needed byte[status_addr + constant(4 + 1)] := $AC byte[status_addr + constant(4 + 2)] := $AC byte[status_addr + constant(4 + 21)] := $06 byte[status_addr + constant(4 + 22)] := $06 else convert_to_dec(diamonds_needed, 2) byte[status_addr + constant(4 + 1)] := decbuf[1] byte[status_addr + constant(4 + 2)] := decbuf[0] byte[status_addr + constant(4 + 21)] := $9D byte[status_addr + constant(4 + 22)] := $9D byte[status_addr + constant(4 + 3)] := $AC convert_to_dec(diamond_value, 2) byte[status_addr + constant(4 + 4)] := decbuf[1] byte[status_addr + constant(4 + 5)] := decbuf[0] byte[status_addr + constant(4 + 6)] := $90 convert_to_dec(diamond_count, 2) byte[status_addr + constant(4 + 7)] := decbuf[1] byte[status_addr + constant(4 + 8)] := decbuf[0] byte[status_addr + constant(4 + 9)] := $90 convert_to_dec(time, 3) byte[status_addr + constant(4 + 10)] := decbuf[2] byte[status_addr + constant(4 + 11)] := decbuf[1] byte[status_addr + constant(4 + 12)] := decbuf[0] byte[status_addr + constant(4 + 13)] := $90 convert_to_dec(score, 6) byte[status_addr + constant(4 + 14)] := decbuf[5] byte[status_addr + constant(4 + 15)] := decbuf[4] byte[status_addr + constant(4 + 16)] := decbuf[3] byte[status_addr + constant(4 + 17)] := decbuf[2] byte[status_addr + constant(4 + 18)] := decbuf[1] byte[status_addr + constant(4 + 19)] := decbuf[0] byte[status_addr + constant(4 + 27)] := $9D byte[status_addr + constant(4 + 28)] := $9D elseif status_mode == STATUS_GAME_OVER bytefill(status_addr + constant(4 + 20), $06, 20) text_out(status_addr + 4, @game_over, 20) if --tick_count == 0 tick_count := ticks_per_sec if status_mode == STATUS_GAME if time > 0 convert_to_dec(--time, 3) byte[status_addr + constant(4 + 10)] := decbuf[2] byte[status_addr + constant(4 + 11)] := decbuf[1] byte[status_addr + constant(4 + 12)] := decbuf[0] elseif status_mode == STATUS_PAUSE if toggle longmove(status_addr, @status_temp, 10) toggle := 0 else longmove(@status_temp, status_addr, 10) bytefill(status_addr + constant(4 + 20), $06, 20) text_out(status_addr + 4, @pause, 20) toggle := 1 elseif status_mode == STATUS_OUT_OF_TIME 'out of time if toggle longmove(status_addr, @status_temp, 10) toggle := 0 else longmove(@status_temp, status_addr, 10) bytefill(status_addr + constant(4 + 20), $06, 20) text_out(status_addr + 4, @out_of_time, 20) toggle := 1pub convert_to_dec(val, len) | i repeat i from 0 to len-1 decbuf[i] := val // 10 + $80 val /= 10 pub text_out(addr, str, len) | i, c repeat i from 0 to len-1 c := byte[str + i] if c == $20 byte[addr + i] := $90 elseif c == $2C byte[addr + i] := $AF elseif c == $2F byte[addr + i] := $8C else byte[addr + i] := c + $50 datpre byte " PLAYER , MEN / "out_of_time byte " OUT OF TIME "pause byte " SPACEBAR TO RESUME "bonus_life byte " B O N U S L I F E "game_over byte " G A M E O V E R " \ No newline at end of file diff --git a/source/boulder/bellatrix/bd_ntsc.spin b/source/boulder/bellatrix/bd_ntsc.spin new file mode 100644 index 0000000..3cf8733 --- /dev/null +++ b/source/boulder/bellatrix/bd_ntsc.spin @@ -0,0 +1,3812 @@ +'Boulderdash, for Hydra or Demo Board. +'Version 0.95 +'Released to the public domain. + +' Changes: +' 2009-11-10 - Modified for the Demo Board. +' - Added 'readkey' routine to allow playing the game from the keyboard. +' - Rockford now can be moved around and the screen scrolls automatically. +' 2009-11-12 - Halved tile horizontal resolution to eliminate redundant pixel pairs +' (and BoulderDash uses 8x16 tiles anyway). This also halves tile memory +' requirements. +' - The scroller now runs in a separate cog. +' 2009-11-13 - Changed pixel clock settings in order to display 20 tiles per line, +' as in the classic C64/Atari BoulderDash I. +' - Added code to handle boulders and diamonds. Rockford cannot push yet +' boulders or pick-up diamonds. +' 2009-11-14 - Reversed pixel order in video driver in order to avoid having to define +' mirrored tiles. +' - Added more tiles, hopefully all the characters are there. +' - The scroller cog now also handles animated characters. +' - Rockford can pick-up diamonds and the screen flashes when diamond count +' reaches the target. +' - Rockford now walks facing in the right direction and gets "bored". +' 2009-11-15 - Added an optional status line. +' - Added a character font for the status line. +' - Main game loop moved to a separate routine. +' - Boulders can be pushed around. +' - New routines to cover and uncover the screen. +' - Added an infinite loop to the main routine, pressing ESC restarts the +' game. +' 2009-11-16 - Inbox now morphs into Rockford. +' - Rockford can exit through the Outbox. +' 2009-11-17 - Added hardware detection feature (Hydra, Demo Board, etc.) Video driver +' changed accordingly. Not sure if keyboard will work on Hydra. +' - Falling boulders and diamonds now can kill Rockford. +' - Added PAL timings table to video driver, but PAL mode is not working yet. +' 2009-11-18 - Synchronized scroller to vertical sync, scrolling is totally smooth now. +' - PAL mode now works. +' 2009-11-25 - Started adding support for fireflies and butterflies. Had to split the +' case statement in the main game loop into sections due to poor performance. +' - Added code to decode raw cave data of original Atari/C64 BoulderDash I. +' You can now import your favorite caves :) +' 2009-11-26 - Fireflies and butterflies now explode in contact with Rockford. +' - Time counts down, but there is no "out of time" condition yet. +' 2009-11-27 - Implemented the "pick without moving" Rockford trick (use left CTRL key). +' - Stop cave when time runs out. +' - Do not advance to next cave until current one is successfully completed. +' Game is now playable! Use LeftCtrl + LeftShift as a "cheat" to move to +' next cave without finishing the current one. The Escape key restarts the +' current cave. Sorry, no score points yet. +' 2009-11-28 - Status line now handled by a separate cog. +' - Flashing "Out of time" message when time runs out. +' - Space bar now pauses game. +' - Score points implemented. +' - No more unlimited lifes, sorry ;))) +' - New life every 500 points. +' 2009-11-29 - Using a table of codes to reset the 'scanned' flag avoids a second case +' statement and improves performance. +' - Implemented amoebas and magic wall. Now all the original caves work! +' - Added all the original BoulderDash I caves (except the intermissions) +' - Added a Level variable. After successfully finishing the last cave the +' game starts again from the first one of the next difficulty level. +' 2009-11-30 - Fixed a bug in amoeba handling that caused cave M to crash. +' 2009-12-02 - Game controller apparently does not like to be read too fast. +' - Added intermission caves. +' 2009-12-04 - Aborting the current cave will cost you a life. +' - Restart (or exit) automatically the cave if "Out of time" has been +' flashing for more than a minute without user input. +' - Throtle down Rockford a bit in levels 1 and 2 (is running too fast!) +' 2009-12-05 - Added the title screen (had a hard time scrolling the background behind +' those big letters!). +' - Starting cave and level can be selected from the title screen. +' - Run a demo if the title screen has been inactive for about a minute. +' 2009-12-06 - Fixed boulder/diamond rolling off: they must move to the side first, +' not directly diagonally. +' - Added a preliminary sound object. Nothing there yet. +' - Bonus points at the end of the cave increase with difficulty level. +' 2009-12-07 - First steps towards SID emulation via PWM. Single voice waveform generation +' already works (well, sort of). No envelope control yet. +' 2009-12-08 - SID emulator: noise waveform, amplitude control, 3 voices. Envelope +' control using a separate cog (see the ChangeLog in the SIDemu.spin file). +' 2009-12-09 - Integrated the SID emulator into the game, running out of cogs. +' - Got the main tune working. +' - Added a few other sound/noise effects the game. +' - Boulder noise interfers with diamond pick up sound. Which one has the +' preference? +' 2009-12-12 - Added the cover/uncover screen sound. +' - Added the bonus points sound. +' - Added amoeba and magic wall sound. +' +' TODO: +' - Finish it :) +' - Add broadcast TV mode with sound carrier to use the TV antenna input (like in old times :)) +' +' +' Anpassungen f?r den Hive +' +' 09-01-2010 - Entfernung der Hardwareerkennung +' - Anpassung Konfiguration an Hive/Bellatrix +' - Gamecontr. entfernt +' - Auskommentierung Sound +' 12-01-2010 - Scrolltext im Titelscreen +' - Optimierung Soundobjekt + +con + + _clkmode = xtal1 + pll16x + _xinfreq = 5_000_000 + + ' The supported video modes + TV_NTSC = 0 + TV_PAL = 1 + + TV_MODE = TV_NTSC ' <--- Select your TV system here -- NTSC or PAL ---<<< + + ' Game controller codes + GP_RIGHT = %00000001 '(Right arrow) Move right + GP_LEFT = %00000010 '(Left arrow) Move left + GP_DOWN = %00000100 '(Down arrow) Move down + GP_UP = %00001000 '(Up arrow) Move up + GP_START = %00010000 '(Left Shift) Start game. Together with GP_SELECT: go to next cave (cheat) + GP_SELECT = %00100000 '(Left Ctrl) Pick + GP_B = %01000000 '(Space) Pause + GP_A = %10000000 '(Escape) Abort and restart current cave + +var + long nes + long last_dir + long cave_addr + long random_ptr + long screen_height + long sx, sy + long video_params[7] + long sound_pin + long Score + long NextLife + byte temp_cave[40*22] + byte HWType + byte Cave + byte Level + byte CaveNumber + byte DiamondCount + byte DiamondsNeeded + byte DiamondValue + byte ExtraValue + byte CaveTime + byte Men + byte Alive + byte MagicWallStatus + byte MagicWallTime + byte AmoebaStatus + byte AmoebaTime + byte target + byte vsync + byte door_x, door_y + +obj + tv: "Boulderdash_Tile_TV" + kb: "Keyboard" + sc: "Scroller" + st: "Status" + rr: "RealRandom" + sn: "Sounds" + +pub main | success + + video_params[0] := %0_11_101_000 ' Set Mode for VCFG + video_params[1] := 2 ' Set Pingroup used by TV driver. + video_params[2] := %0111_0000 ' Set Pinmask for VCFG pins. + video_params[3] := %0000_0111<<20 ' Set Pinmask for output pins. + + video_params[4] := TV_MODE + video_params[5] := @screen + video_params[6] := @vsync + + if video_params[4] == TV_NTSC + screen_height := 12 + else + screen_height := 14 + + rr.start 'start the real random number generator + random_ptr := rr.random_ptr + + bytefill(@screen, $00, constant(40 * 22)) 'clear screen + + tv.start(@video_params) 'start the TV driver + sc.start(@video_params, random_ptr) 'start the scroller + st.start(@video_params) 'start the status line handler + kb.start(17, 16) 'start the keyboard driver + sn.start 'start the sound engine + + cave_addr := @screen + + repeat + + repeat + success := TitleScreen + + palette.byte[1] := $04 + palette.byte[2] := $4B + palette.byte[3] := $06 + bytefill(@screen, $3C, constant(40 * 22)) 'fill the screen with the scrolling pattern + status := 0 + + Score := 0 + Men := 3 + + if success + quit + else + Demo + + repeat + + sn.music_off + + CaveNumber := byte[@@caves[Cave]] + st.player_params(1, Men, CaveNumber, Level, Score) + st.set_mode(st#STATUS_PRE) + + CreateCave(@@caves[Cave], @temp_cave) + st.cave_params(DiamondsNeeded, DiamondValue, CaveTime) + + last_dir := -1 'last rockford direction + sc.rockford_go(0) 'rockford initially stands still + sc.milling_off + + if CaveNumber > 16 + 'intermission + sx := 0 + sy := 0 + else + 'normal cave + sx := door_x - 10 + sx <#= constant(40 - 20) + sx #>= 0 + sy := door_y - screen_height / 2 + sy <#= 22 - screen_height + sy #>= 0 + sc.scroll_to(sx * 8, sy * 16) + + Uncover 'uncover screen + success := GameLoop + + if not success + if --Men == 0 + st.set_mode(st#STATUS_GAME_OVER) + waitcnt(clkfreq + cnt) + Cover + quit + + if success or CaveNumber > 16 + 'go to next cave only if current one was completed + 'but never restart intermissions + if success and CaveNumber > 16 and Men < 9 + ++Men 'the promised bonus life + if caves[++Cave] == 0 + if Level < 4 + ++Level + Cave := 0 + + st.player_params(1, Men, CaveNumber, Level, Score) + st.set_mode(st#STATUS_PRE) + Cover 'cover screen with scrolling pattern + + +pub TitleScreen | x, y, h, t, i, j, lk, ticks, count, scr + + if TV_MODE == TV_NTSC + h := 24 + t := 2 + ticks := constant(60 * 130 / 2) 'dr235 + else + h := 28 + t := 4 + ticks := constant(50 * 130 / 2) + + scr := 0 + + bytefill(@screen, $00, constant(40 * 28)) 'clear screen + palette.byte[1] := $FC + palette.byte[2] := $FB + palette.byte[3] := $06 + st.set_mode(st#STATUS_NONE) + + Cave := 0 + Level := 0 + CaveNumber := byte[@@caves[Cave]] + + repeat x from 0 to 19 + byte[@screen + x] := $B1 + byte[@screen + x + (h - 6) * 40] := $B1 + repeat y from 1 to h - 7 + byte[@screen + y * 40] := $B5 + repeat x from 1 to 18 + byte[@screen + x + y * 40] := $B0 + byte[@screen + 19 + y * 40] := $B6 + + i := 0 + repeat y from t to t + 6 + repeat x from 1 to 18 + byte[@screen + x + y * 40] := big_boulder.byte[i++] + + i := 0 + repeat y from t + 8 to t + 14 + repeat x from 3 to 15 + byte[@screen + x + y * 40] := big_dash.byte[i++] + + status := 2 + scroll := 0 + 'st.text_out(@screen + (h - 4) * 40, @str1, 20) + scr++ + repeat i from 0 to 19 + 'j := str1.byte[i] + j := scr1.byte[i + scr] + if j == $20 + byte[@screen + (h - 4) * 40 + i] := $90 + else + byte[@screen + (h - 4) * 40 + i] := j + $A0 + st.text_out(@screen + (h - 3) * 40, @str2, 20) + st.text_out(@screen + (h - 2) * 40, @str3, 20) + st.text_out(@screen + (h - 1) * 40, @str4, 20) + + screen.byte[(h - 2) * 40] := $D1 'player(s) + screen.byte[(h - 2) * 40 + 10] := $D1 'joystick(s) + screen.byte[(h - 1) * 40 + 7] := CaveNumber + $E0 + screen.byte[(h - 1) * 40 + 17] := Level + $D1 + + lk := 0 'last key + count := ticks + + sn.music_on + + repeat while count > 0 + + 'wait for vsync, count every other tick + repeat while vsync == 0 + repeat while vsync <> 0 + repeat while vsync == 0 + repeat while vsync <> 0 + --count + + 'scrolltext + scr++ + if (scr>>2) > 318 '(scr2 - scr1) + scr := 0 + repeat i from 0 to 19 + j := scr1.byte[i + (scr>>2)] + if j == $20 + byte[@screen + (h - 4) * 40 + i] := $90 + else + byte[@screen + (h - 4) * 40 + i] := j + $A0 + + ' scrolling background + x := @tiles + constant(16 * $B0) + y := word[x] + wordmove(x, x + 2, 7) + word[x + 15] := y + + repeat i from 0 to 5 + repeat y from 0 to 14 step 2 + x := @tiles + constant(16 * $B0) + y + t := @tiles + constant(16 * $BD) + y + 16 * i + j := @tiles + constant(16 * $B3) + y + 16 * i + word[j] := word[x] | word[t] + repeat y from 0 to 14 step 2 + x := @tiles + constant(16 * $B0) + y + t := @tiles + constant(16 * $C3) + y + j := @tiles + constant(16 * $B9) + y + word[j] := (word[x] & $00FF) | word[t] + repeat y from 0 to 14 step 2 + x := @tiles + constant(16 * $B0) + y + t := @tiles + constant(16 * $C4) + y + j := @tiles + constant(16 * $BA) + y + word[j] := (word[x] & $FF00) | word[t] + repeat y from 0 to 14 step 2 + x := @tiles + constant(16 * $B0) + y + t := @tiles + constant(16 * $C5) + y + j := @tiles + constant(16 * $BB) + y + word[j] := (word[x] & $FF00) | word[t] + + i := read_input + if i <> lk + count := ticks 'reset countdown + if i & GP_START + sn.music_off + return 1 + elseif i & GP_LEFT + if Cave => 5 + Cave -= 5 + CaveNumber := byte[@@caves[Cave]] + screen.byte[(h - 1) * 40 + 7] := CaveNumber + $E0 + elseif i & GP_RIGHT + if Cave =< 10 + Cave += 5 + CaveNumber := byte[@@caves[Cave]] + screen.byte[(h - 1) * 40 + 7] := CaveNumber + $E0 + elseif i & GP_UP + if Level < 4 + ++Level + screen.byte[(h - 1) * 40 + 17] := Level + $D1 + elseif i & GP_DOWN + if Level > 0 + --Level + screen.byte[(h - 1) * 40 + 17] := Level + $D1 + lk := i + + sn.music_off + return 0 + +dat + +big_boulder + byte $B2, $B1, $B7, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0 + byte $B2, $B0, $B9, $B2, $B1, $BA, $B5, $B9, $B2, $B0, $BA, $B1, $B7, $B2, $B1, $BA, $B1, $B7 + byte $B2, $B1, $B8, $B2, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9 + byte $B2, $B1, $B7, $B2, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9, $B2, $B5, $BA, $B1, $B8 + byte $B2, $B0, $B9, $B2, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9, $B2, $B0, $BA, $B1, $B7 + byte $B2, $B1, $B5, $B2, $B1, $BA, $B1, $B5, $B2, $B1, $BA, $B1, $B5, $B2, $B1, $BA, $B5, $B9 + byte $B2, $B1, $B8, $B2, $B1, $BA, $B1, $B5, $B2, $B1, $BA, $B1, $B8, $B2, $B1, $BA, $B5, $B9 + +big_dash + byte $BA, $B1, $B3, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0 + byte $BA, $B5, $BA, $B0, $B2, $B7, $B2, $B1, $BA, $B5, $BA, $BB, $BC + byte $BA, $B5, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $BA, $B0, $B0 + byte $BA, $B5, $BA, $BA, $B1, $B5, $B2, $B1, $BA, $B1, $B1, $B0, $B0 + byte $BA, $B5, $BA, $BA, $B5, $B9, $B0, $B2, $BA, $B5, $BA, $B0, $B0 + byte $BA, $B1, $B1, $BA, $B5, $B9, $B2, $B1, $BA, $B5, $BA, $B0, $B0 + byte $BA, $B1, $B4, $BA, $B5, $B9, $B2, $B1, $BA, $B5, $BA, $B0, $B0 + +str1 byte " HIVE VERSION " +str2 byte "PRESS BUTTON TO PLAY" +str3 byte " PLAYER JOYSTICK" +str4 byte " CAVE: LEVEL: " + +scr1 byte " " + byte "THANKS :SPORK FROGS: :HPG: :AHLE2: AND THE OTHER PROPELLERHEADS FOR THE BASECODE" + byte " " + byte "THANKS PEX :MAHONEY: TUFVESSON FOR THE COOL MUSIC" + byte " " + byte "GRUSS AN ALLE HIVE-DROHNEN" + byte " " + byte "HIVE: WE ARE BORG - RESISTANCE IS FUTILE" + byte " " + byte "DROHNE235: HIVE-VERSION 2010" + byte " " +scr2 byte 0 + +pub Demo + + Score := 0 + Cave := 0 'demo happens on cave A + Level := 0 + CaveNumber := byte[@@caves[Cave]] + st.player_params(1, Men, CaveNumber, Level, Score) + st.set_mode(st#STATUS_PRE) + + CreateCave(@@caves[Cave], @temp_cave) + st.cave_params(DiamondsNeeded, DiamondValue, CaveTime) + + last_dir := -1 'last rockford direction + sc.rockford_go(0) 'rockford initially stands still + sc.milling_off + + sx := door_x - 10 + sx <#= constant(40 - 20) + sx #>= 0 + sy := door_y - screen_height / 2 + sy <#= 22 - screen_height + sy #>= 0 + sc.scroll_to(sx * 8, sy * 16) + + demo_ptr := @demo_data 'set demo data pointer + kcount := 0 + + Uncover 'uncover screen + GameLoop 'play the demo + Cover 'cover screen back + +var + + long demo_ptr + byte kcount, last_key + +dat + +' The low nibble of each byte is the direction of movement: +' $x0 = no movement +' $x1 = Right +' $x2 = Left +' $x3 = Down +' $x4 = Up +' bit 3 ($x8) set means GP_SELECT is pressed (not used here anyway) +' The high nibble is the number of scan frames to apply the movement. +' $00 means end of demo data. + +demo_data + byte $F0, $10, $14, $71, $23, $91, $40, $23 + byte $41, $34, $12, $40, $14, $B1, $13, $21 + byte $40, $63, $11, $43, $32, $40, $13, $12 + byte $41, $32, $40, $44, $52, $34, $52, $43 + byte $32, $50, $34, $A2, $14, $32, $13, $62 + byte $43, $11, $40, $33, $41, $43, $42, $24 + byte $21, $34, $A1, $A1, $13, $41, $13, $41 + byte $23, $50, $51, $44, $51, $60, $13, $00 + +pub readkey : key + + if demo_ptr + if kcount > 0 + --kcount + return last_key + else + key := byte[demo_ptr++] + if key == $00 + demo_ptr := 0 + else + kcount := key / 16 - 1 + case key & $07 + $0: last_key := 0 + $1: last_key := GP_RIGHT + $2: last_key := GP_LEFT + $3: last_key := GP_DOWN + $4: last_key := GP_UP + if key & $08 + last_key |= GP_SELECT + return last_key + + key := 0 + if kb.keystate($C0) + key |= GP_LEFT + if kb.keystate($C1) + key |= GP_RIGHT + if kb.keystate($C2) + key |= GP_UP + if kb.keystate($C3) + key |= GP_DOWN + if kb.keystate($F2) 'left control key + key |= GP_SELECT + if kb.keystate($CB) 'escape key + key |= GP_A + if kb.keystate($20) 'space key + key |= GP_B + if kb.keystate($F0) 'left shift + key |= GP_START + if kb.keystate($0D) 'or enter + key |= GP_START + +pub read_input + + return readkey + + +var + byte RandSeed1, RandSeed2 + +pub GetRandom | temp1, temp2, temp3, cy, r + +'' Generate a pseudo-random number, given a seed +'' The output matches the one used in the original BoulderDash I + + temp1 := (RandSeed1 & 1) << 7 + temp2 := (RandSeed2 & 1) << 7 + temp3 := (RandSeed2 >> 1) & $7F + + r := RandSeed2 + temp2 + if r > $FF + cy := 1 + r &= $FF + else + cy := 0 + + r += cy + $13 + if r > $FF + cy := 1 + r &= $FF + else + cy := 0 + + RandSeed2 := r + + r := RandSeed1 + cy + temp1 + if r > $FF + cy := 1 + r &= $FF + else + cy := 0 + + r += cy + temp3 + RandSeed1 := r & $FF + +dat + +caves long @cave_A, @cave_B, @cave_C, @cave_D, @inter_1 + long @cave_E, @cave_F, @cave_G, @cave_H, @inter_2 + long @cave_I, @cave_J, @cave_K, @cave_L, @inter_3 + long @cave_M, @cave_N, @cave_O, @cave_P, @inter_4 + long 0 + +cave_A byte 1 'cave number + byte 20 'magic wall/amoeba time + byte 10 'initial diamond value + byte 15 'extra diamond value + byte 10, 11, 12, 13, 14 'randomizer seed per level + byte 12, 12, 12, 12, 12 'diamonds needed per level + byte 150, 110, 70, 40, 30 'time per level + byte $08, $0B, $09, $D4, $20 'bg color 1, bg color 2, fg color + byte $00, $10, $14, $00 'random objects + byte $3C, $32, $09, $00 'probability of object + byte $42, $01, $09, $1E, $02 'raw cave data + byte $42, $09, $10, $1E, $02 + byte $25, $03, $04 + byte $04, $26, $12 + byte $FF + +cave_B byte 2 + byte 20 + byte 20, 50 + byte $03, $00, $01, $57, $58 + byte $0A, $0C, $09, $0D, $0A + byte $96, $6E, $46, $46, $46 + byte $0A, $04, $09, $00, $00 + byte $00, $10, $14, $08 + byte $3C, $32, $09, $02 + byte $42, $01, $08, $26, $02, $42, $01, $0F, $26, $02, $42, $08, $03, $14, $04, $42 + byte $10, $03, $14, $04, $42, $18, $03, $14, $04, $42, $20, $03, $14, $04, $40, $01 + byte $05, $26, $02, $40, $01, $0B, $26, $02, $40, $01, $12, $26, $02, $40, $14, $03 + byte $14, $04, $25, $12, $15, $04, $12, $16, $FF + +cave_C byte 3 + byte $00 + byte $0F, $00 + byte $00, $32, $36, $34, $37 + byte $18, $17, $18, $17, $15 + byte $96, $64, $5A, $50, $46 + byte $09, $08, $09, $04, $00 + byte $02, $10, $14, $00 + byte $64, $32, $09, $00 + byte $25, $03, $04, $04, $27, $14, $FF + +cave_D byte 4 + byte $14 + byte $05, $14 + byte $00, $6E, $70, $73, $77 + byte $24, $24, $24, $24, $24 + byte $78, $64, $50, $3C, $32 + byte $04, $08, $09, $00, $00 + byte $10, $00, $00, $00 + byte $14, $00, $00, $00 + byte $25, $01, $03, $04, $26, $16, $81, $08, $0A, $04, $04, $00, $30, $0A, $0B, $81 + byte $10, $0A, $04, $04, $00, $30, $12, $0B, $81, $18, $0A, $04, $04, $00, $30, $1A + byte $0B, $81, $20, $0A, $04, $04, $00, $30, $22, $0B, $FF + +cave_E byte $05, $14, $32, $5A + byte $00, $00, $00, $00, $00 + byte $04, $05, $06, $07, $08 + byte $96, $78, $5A, $3C, $1E + byte $09, $0A, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $25, $01, $03, $04, $27, $16, $80, $08, $0A, $03, $03, $00, $80, $10, $0A, $03 + byte $03, $00, $80, $18, $0A, $03, $03, $00, $80, $20, $0A, $03, $03, $00, $14, $09 + byte $0C, $08, $0A, $0A, $14, $11, $0C, $08, $12, $0A, $14, $19, $0C, $08, $1A, $0A + byte $14, $21, $0C, $08, $22, $0A, $80, $08, $10, $03, $03, $00, $80, $10, $10, $03 + byte $03, $00, $80, $18, $10, $03, $03, $00, $80, $20, $10, $03, $03, $00, $14, $09 + byte $12, $08, $0A, $10, $14, $11, $12, $08, $12, $10, $14, $19, $12, $08, $1A, $10 + byte $14, $21, $12, $08, $22, $10, $FF + +cave_F byte $06, $14, $28, $3C + byte $00, $14, $15, $16, $17 + byte $04, $06, $07, $08, $08 + byte $96, $78, $64, $5A, $50 + byte $0E, $0A, $09, $00, $00 + byte $10, $00, $00, $00 + byte $32, $00, $00, $00 + byte $82, $01, $03, $0A, $04, $00, $82, $01, $06, $0A, $04, $00, $82, $01, $09, $0A + byte $04, $00, $82, $01, $0C, $0A, $04, $00, $41, $0A, $03, $0D, $04, $14, $03, $05 + byte $08, $04, $05, $14, $03, $08, $08, $04, $08, $14, $03, $0B, $08, $04, $0B, $14 + byte $03, $0E, $08, $04, $0E, $82, $1D, $03, $0A, $04, $00, $82, $1D, $06, $0A, $04 + byte $00, $82, $1D, $09, $0A, $04, $00, $82, $1D, $0C, $0A, $04, $00, $41, $1D, $03 + byte $0D, $04, $14, $24, $05, $08, $23, $05, $14, $24, $08, $08, $23, $08, $14, $24 + byte $0B, $08, $23, $0B, $14, $24, $0E, $08, $23, $0E, $25, $03, $14, $04, $26, $14 + byte $FF + +cave_G byte $07, $4B, $0A, $14 + byte $02, $07, $08, $0A, $09 + byte $0F, $14, $19, $19, $19 + byte $78, $78, $78, $78, $78 + byte $09, $0A, $0D, $00, $00 + byte $00, $10, $08, $00 + byte $64, $28, $02, $00 + byte $42, $01, $07, $0C, $02, $42, $1C, $05, $0B, $02, $7A, $13, $15, $02, $02, $14 + byte $04, $06, $14, $04, $0E, $14, $04, $16, $14, $22, $04, $14, $22, $0C, $14, $22 + byte $16, $25, $14, $03, $04, $27, $07, $FF + +cave_H byte $08, $14, $0A, $14 + byte $01, $03, $04, $05, $06 + byte $0A, $0F, $14, $14, $14 + byte $78, $6E, $64, $5A, $50 + byte $02, $0E, $09, $00, $00 + byte $00, $10, $08, $00 + byte $5A, $32, $02, $00 + byte $14, $04, $06, $14, $22, $04, $14, $22, $0C, $04, $00, $05, $25, $14, $03, $42 + byte $01, $07, $0C, $02, $42, $01, $0F, $0C, $02, $42, $1C, $05, $0B, $02, $42, $1C + byte $0D, $0B, $02, $43, $0E, $11, $08, $02, $14, $0C, $10, $00, $0E, $12, $14, $13 + byte $12, $41, $0E, $0F, $08, $02, $FF + +cave_I byte $09, $14, $05, $0A + byte $64, $89, $8C, $FB, $33 + byte $4B, $4B, $50, $55, $5A + byte $96, $96, $82, $82, $78 + byte $08, $04, $09, $00, $00 + byte $10, $14, $00, $00 + byte $F0, $78, $00, $00 + byte $82, $05, $0A, $0D, $0D, $00, $01, $0C, $0A, $82, $19, $0A, $0D, $0D, $00, $01 + byte $1F, $0A, $42, $11, $12, $09, $02, $40, $11, $13, $09, $02, $25, $07, $0C, $04 + byte $08, $0C, $FF + +cave_J byte $0A, $14, $19, $3C + byte $00, $00, $00, $00, $00 + byte $0C, $0C, $0C, $0C, $0C + byte $96, $82, $78, $6E, $64 + byte $06, $08, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $25, $0D, $03, $04, $27, $16, $54, $05, $04, $11, $03, $54, $15, $04, $11, $05 + byte $80, $05, $0B, $11, $03, $08, $C2, $01, $04, $15, $11, $00, $0D, $04, $C2, $07 + byte $06, $0D, $0D, $00, $0D, $06, $C2, $09, $08, $09, $09, $00, $0D, $08, $C2, $0B + byte $0A, $05, $05, $00, $0D, $0A, $82, $03, $06, $03, $0F, $08, $00, $04, $06, $54 + byte $04, $10, $04, $04, $FF + +cave_K byte $0B, $14, $32, $00 + byte $00, $04, $66, $97, $64 + byte $06, $06, $06, $06, $06 + byte $78, $78, $96, $96, $F0 + byte $0B, $08, $09, $00, $00 + byte $00, $10, $08, $00 + byte $64, $50, $02, $00 + byte $42, $0A, $03, $09, $04, $42, $14, $03, $09, $04, $42, $1E, $03, $09, $04, $42 + byte $09, $16, $09, $00, $42, $0C, $0F, $11, $02, $42, $05, $0B, $09, $02, $42, $0F + byte $0B, $09, $02, $42, $19, $0B, $09, $02, $42, $1C, $13, $0B, $01, $14, $04, $03 + byte $14, $0E, $03, $14, $18, $03, $14, $22, $03, $14, $04, $16, $14, $23, $15, $25 + byte $14, $14, $04, $26, $11, $FF + +cave_L byte $0C, $14, $14, $00 + byte $00, $3C, $02, $3B, $66 + byte $13, $13, $0E, $10, $15 + byte $B4, $AA, $A0, $A0, $A0 + byte $0C, $0A, $09, $00, $00 + byte $00, $10, $14, $00 + byte $3C, $32, $09, $00 + byte $42, $0A, $05, $12, $04, $42, $0E, $05, $12, $04, $42, $12, $05, $12, $04, $42 + byte $16, $05, $12, $04, $42, $02, $06, $0B, $02, $42, $02, $0A, $0B, $02, $42, $02 + byte $0E, $0F, $02, $42, $02, $12, $0B, $02, $81, $1E, $04, $04, $04, $00, $08, $20 + byte $05, $81, $1E, $09, $04, $04, $00, $08, $20, $0A, $81, $1E, $0E, $04, $04, $00 + byte $08, $20, $0F, $25, $03, $14, $04, $27, $16, $FF + +cave_M byte $0D, $8C, $05, $08 + byte $00, $01, $02, $03, $04 + byte $32, $37, $3C, $46, $50 + byte $A0, $9B, $96, $91, $8C + byte $06, $08, $0D, $00, $00 + byte $10, $00, $00, $00 + byte $28, $00, $00, $00 + byte $25, $12, $03, $04, $0A, $03, $3A, $14, $03, $42, $05, $12, $1E, $02, $70, $05 + byte $13, $1E, $02, $50, $05, $14, $1E, $02, $C1, $05, $15, $1E, $02, $FF + +cave_N byte $0E, $14, $0A, $14 + byte $00, $00, $00, $00, $00 + byte $1E, $23, $28, $2A, $2D + byte $96, $91, $8C, $87, $82 + byte $0C, $08, $09, $00, $00 + byte $10, $00, $00, $00 + byte $00, $00, $00, $00 + byte $81, $0A, $0A, $0D, $0D, $00, $70, $0B, $0B, $0C, $03, $C1, $0C, $0A, $03, $0D + byte $C1, $10, $0A, $03, $0D, $C1, $14, $0A, $03, $0D, $50, $16, $08, $0C, $02, $48 + byte $16, $07, $0C, $02, $C1, $17, $06, $03, $04, $C1, $1B, $06, $03, $04, $C1, $1F + byte $06, $03, $04, $25, $03, $03, $04, $27, $14, $FF + +cave_O byte $0F, $08, $0A, $14 + byte $01, $1D, $1E, $1F, $20 + byte $0F, $14, $14, $19, $1E + byte $78, $78, $78, $78, $8C + byte $08, $0E, $09, $00, $00 + byte $00, $10, $08, $00 + byte $64, $50, $02, $00 + byte $42, $02, $04, $0A, $03, $42, $0F, $0D, $0A, $01, $41, $0C, $0E, $03, $02, $43 + byte $0C, $0F, $03, $02, $04, $14, $16, $25, $14, $03, $FF + +cave_P byte $10, $14, $0A, $14 + byte $01, $78, $81, $7E, $7B + byte $0C, $0F, $0F, $0F, $0C + byte $96, $96, $96, $96, $96 + byte $09, $0A, $09, $00, $00 + byte $10, $00, $00, $00 + byte $32, $00, $00, $00 + byte $25, $01, $03, $04, $27, $04, $81, $08, $13, $04, $04, $00, $08, $0A, $14, $C2 + byte $07, $0A, $06, $08, $43, $07, $0A, $06, $02, $81, $10, $13, $04, $04, $00, $08 + byte $12, $14, $C2, $0F, $0A, $06, $08, $43, $0F, $0A, $06, $02, $81, $18, $13, $04 + byte $04, $00, $08, $1A, $14, $81, $20, $13, $04, $04, $00, $08, $22, $14, $FF + +inter_1 byte $11, $14, $1E, $00 + byte $0A, $0B, $0C, $0D, $0E + byte $06, $06, $06, $06, $06 + byte $0A, $0A, $0A, $0A, $0A + byte $0E, $02, $09, $00, $00 + byte $00, $14, $00, $00 + byte $FF, $09, $00, $00 + byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $00, $32, $0A, $0C, $10 + byte $0A, $04, $01, $0A, $05, $25, $03, $05, $04, $12, $0C, $FF + +inter_2 byte $12, $14, $0A, $00 + byte $0A, $0B, $0C, $0D, $0E + byte $10, $10, $10, $10, $10 + byte $0F, $0F, $0F, $0F, $0F + byte $06, $0F, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $01, $50, $01, $03, $09 + byte $03, $48, $02, $03, $08, $03, $54, $01, $05, $08, $03, $50, $01, $06, $07, $03 + byte $50, $12, $03, $09, $05, $54, $12, $05, $08, $05, $50, $12, $06, $07, $05, $25 + byte $01, $04, $04, $12, $04, $FF + +inter_3 byte $13, $04, $0A, $00 + byte $0A, $0B, $0C, $0D, $0E + byte $0E, $0E, $0E, $0E, $0E + byte $14, $14, $14, $14, $14 + byte $06, $08, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $00, $54, $01, $0C, $12 + byte $02, $88, $0F, $09, $04, $04, $08, $25, $08, $03, $04, $12, $07, $FF + +inter_4 byte $14, $03, $1E, $00 + byte $00, $00, $00, $00, $00 + byte $06, $06, $06, $06, $06 + byte $14, $14, $14, $14, $14 + byte $06, $08, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $01, $D0, $0B, $03, $03 + byte $02, $80, $0B, $07, $03, $06, $00, $43, $0B, $06, $03, $02, $43, $0B, $0A, $03 + byte $02, $50, $08, $07, $03, $03, $25, $03, $03, $04, $09, $0A, $FF + +dat + +' C64 color table approximation. Not the most accurate one, but gives the desired effect. + +ctable byte $02, $06, $4B, $BC, $2B, $9C, $EB, $7D + byte $4B, $4A, $4B, $04, $04, $9D, $0B, $04 + +pub CreateCave(raw_cave, dest) | i, j, k, cx, cy, ci, co, dir, len + +'' Create cave contents from the description array + + CaveNumber := byte[raw_cave] + + RandSeed1 := 0 + RandSeed2 := byte[raw_cave + 4 + Level] + + ' Set colors + palette.byte[1] := ctable.byte[byte[raw_cave + 20]] + palette.byte[2] := ctable.byte[byte[raw_cave + 19]] + palette.byte[3] := ctable.byte[byte[raw_cave + 21] - 8] + + ' Place random objects + repeat cy from 1 to 21 + repeat cx from 0 to 39 + co := $01 ' dirt + GetRandom + repeat ci from 0 to 3 + if RandSeed1 < byte[raw_cave + 28 + ci] + co := byte[raw_cave + 24 + ci] + byte[dest + cx + cy * 40] := co + + ' Steel bounds + repeat cx from 0 to 39 + byte[dest + cx] := $07 + byte[dest + cx + 21 * 40] := $07 + repeat cy from 0 to 21 + byte[dest + cy * 40] := $07 + byte[dest + 39 + cy * 40] := $07 + + 'Decode raw data + i := raw_cave + 32 + repeat + ci := byte[i++] + cx := byte[i++] + cy := byte[i++] - 2 + if ci == $FF + quit + case ci & $C0 + $00: + byte[dest + cx + cy * 40] := ci & $3F + if (ci & $3F) == $25 + door_x := cx + door_y := cy + $40: + len := byte[i++] + dir := byte[i++] + repeat + byte[dest + cx + cy * 40] := ci & $3F + case dir + 0: --cy + 1: --cy + ++cx + 2: ++cx + 3: ++cy + ++cx + 4: ++cy + 5: ++cy + --cx + 6: --cx + 7: --cy + --cx + while --len > 0 + $80: + len := byte[i++] - 1 'width + dir := byte[i++] - 1 'height + co := byte[i++] + repeat j from 0 to len + byte[dest + cx + j + cy * 40] := ci & $3F + byte[dest + cx + j + (cy + dir) * 40] := ci & $3F + repeat j from 1 to dir - 1 + byte[dest + cx + (cy + j) * 40] := ci & $3F + repeat k from 1 to len - 1 + byte[dest + cx + k + (cy + j) * 40] := co + byte[dest + cx + len + (cy + j) * 40] := ci & $3F + $C0: + len := byte[i++] - 1 'width + dir := byte[i++] - 1 'height + repeat j from 0 to len + byte[dest + cx + j + cy * 40] := ci & $3F + byte[dest + cx + j + (cy + dir) * 40] := ci & $3F + repeat j from 0 to dir + byte[dest + cx + (cy + j) * 40] := ci & $3F + byte[dest + cx + len + (cy + j) * 40] := ci & $3F + + DiamondsNeeded := byte[raw_cave + 9 + Level] + CaveTime := byte[raw_cave + 14 + Level] + MagicWallTime := byte[raw_cave + 1] + if MagicWallTime > CaveTime + AmoebaTime := CaveTime + else + AmoebaTime := CaveTime - MagicWallTime + DiamondValue := byte[raw_cave + 2] + ExtraValue := byte[raw_cave + 3] + DiamondCount := 0 + +pub Cover | n, cell + +'' Ramdomly cover the screen with a scrolling pattern + + n := 0 + repeat while n <> constant(40 * 22) + cell := ||long[random_ptr] // constant(40 * 22) + if byte[cave_addr + cell] <> $3C + byte[cave_addr + cell] := $3C + ++n + sn.cover_sound + waitcnt(clkfreq / 1000 + cnt) + +pub Uncover | n, cell + +'' Ramdomly uncover the screen + + n := 0 + repeat while n <> constant(40 * 22) + cell := ||long[random_ptr] // constant(40 * 22) + if byte[cave_addr + cell] == $3C + byte[cave_addr + cell] := temp_cave[cell] + ++n + sn.cover_sound + waitcnt(clkfreq / 1000 + cnt) + +dat + +reset byte $00, $01, $02, $03, $04, $05, $06, $07 + byte $08, $09, $0A, $0B, $08, $09, $0A, $0B + byte $10, $10, $12, $12, $14, $14, $16, $16 + byte $18, $19, $1A, $1B, $1C, $1D, $1E, $1F + byte $20, $21, $22, $23, $24, $25, $26, $27 + byte $28, $29, $2A, $2B, $2C, $2D, $2E, $2F + byte $30, $31, $32, $33, $30, $31, $32, $33 + byte $38, $38, $3A, $3B, $3C, $3D, $3E, $3F + +dirs long 1, 40, -1, -40 + +pub GameLoop | cx, cy, ca, cn, ob, o1, o2, ready, count, amoebas, enclosed + +'' Main game loop. Everything happens here. + + target := 0 + count := 0 'scans before rockford is born + ready := 0 + + NextLife := ((Score / 500) + 1) * 500 + MagicWallStatus := 0 'dormant + AmoebaStatus := 0 'growing slowly + + ' game loop + repeat + Alive := false + amoebas := 0 + enclosed := true + repeat cy from 1 to 21 + repeat cx from 0 to 39 + ca := cave_addr + cx + cy * 40 'address of current object + + 'large case statements execute rather slowly to the point + 'that the game becomes unplayable, so we have to split the + 'case into sections (too bad there is no indirect function + 'call in Spin) + + ob := byte[ca] + if ob < $10 + case ob + $04: 'out door + if target + byte[ca] := $05 + $08: 'firefly facing left + if CheckAround(ca) + ExplodeCenter(ca, $1B) + else + if byte[ca + 40] == $00 + byte[ca + 40] := $0F + byte[ca] := $00 + elseif byte[ca - 1] == $00 + byte[ca - 1] := $0C + byte[ca] := $00 + else + byte[ca] := $0D + $09: 'firefly facing up + if CheckAround(ca) + ExplodeCenter(ca, $1B) + else + if byte[ca - 1] == $00 + byte[ca - 1] := $0C + byte[ca] := $00 + elseif byte[ca - 40] == $00 + byte[ca - 40] := $0D + byte[ca] := $00 + else + byte[ca] := $0E + $0A: 'firefly facing right + if CheckAround(ca) + ExplodeCenter(ca, $1B) + else + if byte[ca - 40] == $00 + byte[ca - 40] := $0D + byte[ca] := $00 + elseif byte[ca + 1] == $00 + byte[ca + 1] := $0E + byte[ca] := $00 + else + byte[ca] := $0F + $0B: 'firefly facing down + if CheckAround(ca) + ExplodeCenter(ca, $1B) + else + if byte[ca + 1] == $00 + byte[ca + 1] := $0E + byte[ca] := $00 + elseif byte[ca + 40] == $00 + byte[ca + 40] := $0F + byte[ca] := $00 + else + byte[ca] := $0C + + elseif ob < $20 + case ob + $10: 'boulder + case byte[ca + 40] 'check object below + $00: + 'boulder can fall + byte[ca] := $00 + byte[ca + 40] := $13 'falling boulder, scanned + sn.boulder_sound + $02, $10, $14: 'wall, boulder or diamond + if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 + 'boulder can roll left + byte[ca] := $00 + byte[ca - 1] := $13 'falling boulder, scanned + sn.boulder_sound + elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 + 'boulder can roll right + byte[ca] := $00 + byte[ca + 1] := $13 'falling boulder, scanned + sn.boulder_sound + $12: 'falling boulder + case byte[ca + 40] 'check object below + $00: + 'boulder can continue falling + byte[ca] := $00 + byte[ca + 40] := $13 'falling boulder, scanned + $03: 'magic wall + byte[ca] := $00 + if MagicWallStatus < 2 'dormant or milling + if MagicWallStatus == 0 + MagicWallStatus := 1 + cn := st.get_time #> MagicWallTime + MagicWallTime := cn - MagicWallTime + sc.milling_on + sn.magic_wall_sound_on + if byte[ca + constant(40 * 2)] == $00 + byte[ca + constant(40 * 2)] := $17 'falling diamond, scanned + sn.diamond_sound + $02, $10, $14: 'wall, boulder or diamond + 'we hit something + sn.boulder_sound + if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 + 'boulder can roll left + byte[ca] := $00 + byte[ca - 1] := $13 'falling boulder, scanned + elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 + 'boulder can roll right + byte[ca] := $00 + byte[ca + 1] := $13 'falling boulder, scanned + else + 'boulder came to a stop + byte[ca] := $11 'stationary boulder, scanned + $38: 'rockford? + 'explode + ExplodeBelow(ca, $1B) + $08, $09, $0A, $0B: 'firefly? + ExplodeBelow(ca, $1B) + $30, $31, $32, $33: 'butterfly? + ExplodeBelow(ca, $20) + other: + 'boulder came to a stop + byte[ca] := $11 'stationary boulder, scanned + sn.boulder_sound + $14: 'diamond + case byte[ca + 40] 'check object below + $00: + 'diamond can fall + byte[ca] := $00 + byte[ca + 40] := $17 'falling diamond, scanned + sn.diamond_sound + $02, $10, $14: 'wall, boulder or diamond + if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 + 'diamond can roll left + byte[ca] := $00 + byte[ca - 1] := $17 'falling diamond, scanned + sn.diamond_sound + elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 + 'diamond can roll right + byte[ca] := $00 + byte[ca + 1] := $17 'falling diamond, scanned + sn.diamond_sound + $16: 'falling diamond + case byte[ca + 40] 'check object below + $00: + 'diamond can continue falling + byte[ca] := $00 + byte[ca + 40] := $17 'falling diamond, scanned + $03: 'magic wall + byte[ca] := $00 + if MagicWallStatus < 2 'dormant or milling + if MagicWallStatus == 0 + MagicWallStatus := 1 + cn := st.get_time #> MagicWallTime + MagicWallTime := cn - MagicWallTime + sc.milling_on + sn.magic_wall_sound_on + if byte[ca + constant(40 * 2)] == $00 + byte[ca + constant(40 * 2)] := $13 'falling boulder, scanned + sn.boulder_sound + $02, $10, $14: 'wall, boulder or diamond + 'we hit something + sn.diamond_sound + if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 + 'diamond can roll left + byte[ca] := $00 + byte[ca - 1] := $17 'falling diamond, scanned + elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 + 'diamond can roll right + byte[ca] := $00 + byte[ca + 1] := $17 'falling diamond, scanned + else + 'diamond came to a stop + byte[ca] := $15 'stationary diamond, scanned + $38: 'rockford? + 'explode + ExplodeBelow(ca, $1B) + $08, $09, $0A, $0B: 'firefly + ExplodeBelow(ca, $1B) + $30, $31, $32, $33: 'butterfly + ExplodeBelow(ca, $20) + other: + 'diamond came to a stop + byte[ca] := $15 'stationary diamond, scanned + sn.diamond_sound + $1B, $1C, $1D, $1E: 'explosion stages + byte[ca]++ + $1F: 'explosion to space, final stage + byte[ca] := $00 + + elseif ob < $30 + case ob + $20, $21, $22, $23: 'explosion stages + byte[ca]++ + $24: 'explosion to diamonds, final stage + byte[ca] := $15 + $25: 'inbox + Alive := true + if count++ == 20 + byte[ca] := $26 + sn.crack_sound + $26, $27: + Alive := true + byte[ca]++ + $28: + Alive := true + byte[ca] := $38 'rockford is born + sc.rockford_reset + st.set_time(CaveTime) + st.set_mode(st#STATUS_GAME) + ready := 1 + + elseif ob < $40 + case ob + $30: 'butterfly facing down + if CheckAround(ca) + ExplodeCenter(ca, $20) + else + if byte[ca - 1] == $00 + byte[ca - 1] := $35 + byte[ca] := $00 + elseif byte[ca + 40] == $00 + byte[ca + 40] := $34 + byte[ca] := $00 + else + byte[ca] := $37 + $31: 'butterfly facing left + if CheckAround(ca) + ExplodeCenter(ca, $20) + else + if byte[ca - 40] == $00 + byte[ca - 40] := $36 + byte[ca] := $00 + elseif byte[ca - 1] == $00 + byte[ca - 1] := $35 + byte[ca] := $00 + else + byte[ca] := $34 + $32: 'butterfly facing up + if CheckAround(ca) + ExplodeCenter(ca, $20) + else + if byte[ca + 1] == $00 + byte[ca + 1] := $37 + byte[ca] := $00 + elseif byte[ca - 40] == $00 + byte[ca - 40] := $36 + byte[ca] := $00 + else + byte[ca] := $35 + $33: 'butterfly facing right + if CheckAround(ca) + ExplodeCenter(ca, $20) + else + if byte[ca + 40] == $00 + byte[ca + 40] := $34 + byte[ca] := $00 + elseif byte[ca + 1] == $00 + byte[ca + 1] := $37 + byte[ca] := $00 + else + byte[ca] := $36 + + $38: 'rockford + Alive := true + nes := read_input + cn := 0 + if nes + if nes & GP_RIGHT + last_dir := 1 + sc.rockford_go(last_dir) + cn := ca + 1 + elseif nes & GP_LEFT + last_dir := -1 + sc.rockford_go(last_dir) + cn := ca - 1 + elseif nes & GP_UP + sc.rockford_go(last_dir) + cn := ca - 40 + elseif nes & GP_DOWN + sc.rockford_go(last_dir) + cn := ca + 40 + + if cn + if nes & GP_SELECT + o1 := $39 + o2 := $00 + else + o1 := $00 + o2 := $39 + case byte[cn] + $00, $01: 'empty or dirt + sn.moving_sound(byte[cn]) + byte[ca] := o1 + byte[cn] := o2 + $05: 'out door + sn.magic_wall_sound_off + sn.amoeba_sound_off + byte[ca] := o1 + byte[cn] := o2 + AddBonusPoints + waitcnt(clkfreq + cnt) '1 second delay + return true 'means cave succesfully completed + $10, $11: 'boulder, stationary + if (nes & GP_RIGHT) and (byte[cn + 1] == $00) and ((long[random_ptr] & $03) == 0) + 'boulder can be pushed + byte[cn + 1] := byte[cn] + byte[ca] := o1 + byte[cn] := o2 + sn.boulder_sound + elseif (nes & GP_LEFT) and (byte[cn - 1] == $00) and ((long[random_ptr] & $03) == 0) + 'boulder can be pushed + byte[cn - 1] := byte[cn] + byte[ca] := o1 + byte[cn] := o2 + sn.boulder_sound + $14, $15, $16, $17: 'diamond + byte[ca] := o1 + byte[cn] := o2 + sn.pick_sound + st.set_diamond_count(++DiamondCount) + IncrementScore(DiamondValue) + if DiamondCount == DiamondsNeeded and not target + 'flash screen when target is reached + sc.flash + sn.crack_sound + DiamondValue := ExtraValue + st.set_diamond_value(DiamondValue) + target := 1 + + else + sc.rockford_go(0) + + 'screen may need scrolling + if CaveNumber > 16 + 'do not scroll intermission caves + sx := 0 + sy := 0 + else + if cx - sx > constant(20 - 6) + sx += constant(10 - 5) + sx <#= constant(40 - 20) + elseif cx - sx < 5 + sx -= constant(10 - 5) + sx #>= 0 + if cy - sy > screen_height - 4 + sy += screen_height / 2 - 3 + sy <#= 22 - screen_height + elseif cy - sy < 3 + sy -= screen_height / 2 - 3 + sy #>= 0 + sc.scroll_to(sx * 8, sy * 16) + + $3A: 'amoeba + if ready + sn.amoeba_sound_on + if AmoebaStatus == 2 + 'turn into stone + byte[ca] := $10 'stationary boulder + elseif AmoebaStatus == 3 + 'turn into diamond + byte[ca] := $14 'stationary diamond + else + ++amoebas + if enclosed + enclosed := CheckEnclosed(ca) + cn := long[random_ptr] + if AmoebaStatus == 0 + cn &= $7F + else + cn &= $0F + if cn =< 3 + cn := ca + dirs[cn & $03] + ob := byte[cn] + if ob == $00 or ob == $01 + byte[cn] := $3A + + 'reset scanned flag + cn := ca - constant(40 + 1) + byte[cn] := reset.byte[byte[cn]] + + if MagicWallStatus == 1 + if st.get_time < MagicWallTime + MagicWallStatus := 2 'expired + sc.milling_off + sn.magic_wall_sound_off + + if AmoebaStatus == 0 + if st.get_time < AmoebaTime + AmoebaStatus := 1 'growing fast + if amoebas > 200 + AmoebaStatus := 2 'grew too big, turn into stones + elseif enclosed + AmoebaStatus := 3 'fully enclosed, turn into diamonds + if amoebas == 0 + sn.amoeba_sound_off + + if demo_ptr + nes := 0 + else + nes := read_input + if nes & GP_A + st.set_time(0) 'stop the time + sn.magic_wall_sound_off + sn.amoeba_sound_off + return false 'not completed, restart the same level + + elseif nes & GP_B + 'pause game + st.set_mode(st#STATUS_PAUSE) + repeat while nes & GP_B + nes := read_input + repeat while (nes & GP_B) == 0 + nes := read_input + if ready + st.set_mode(st#STATUS_GAME) + else + st.set_mode(st#STATUS_PRE) + repeat while nes & GP_B + nes := read_input + + elseif (nes & GP_SELECT) and (nes & GP_START) + st.set_time(0) + sn.magic_wall_sound_off + sn.amoeba_sound_off + return true '*cheat* go to the next level + + cn := st.get_time + if cn < 10 + sn.time_ending_sound(cn) + + if ready and (cn == 0) + 'out of time + sn.magic_wall_sound_off + sn.amoeba_sound_off + st.set_mode(st#STATUS_OUT_OF_TIME) + count := 60 * 60 'approx 1 minute + repeat while count > 0 + repeat while vsync == 0 + repeat while vsync <> 0 + --count + nes := read_input + if nes & GP_A + return false 'not completed, restart the same level + elseif (nes & GP_SELECT) and (nes & GP_START) + return true '*cheat* go to the next level + return false + + if Level < 2 + waitcnt(clkfreq / 50 + cnt) + +pub ExplodeBelow(cell, towhat) + if byte[cell - 1] <> $07 + byte[cell - 1] := towhat + 1 + if byte[cell] <> $07 + byte[cell] := towhat + 1 + if byte[cell + 1] <> $07 + byte[cell + 1] := towhat + if byte[cell + constant(40 - 1)] <> $07 + byte[cell + constant(40 - 1)] := towhat + if byte[cell + 40] <> $07 + byte[cell + 40] := towhat + if byte[cell + constant(40 + 1)] <> $07 + byte[cell + constant(40 + 1)] := towhat + if byte[cell + constant(40 * 2 - 1)] <> $07 + byte[cell + constant(40 * 2 - 1)] := towhat + if byte[cell + constant(40 * 2)] <> $07 + byte[cell + constant(40 * 2)] := towhat + if byte[cell + constant(40 * 2 + 1)] <> $07 + byte[cell + constant(40 * 2 + 1)] := towhat + sn.explosion_sound + +pub ExplodeCenter(cell, towhat) + if byte[cell - constant(40 + 1)] <> $07 + byte[cell - constant(40 + 1)] := towhat + 1 + if byte[cell - 40] <> $07 + byte[cell - 40] := towhat + 1 + if byte[cell - constant(40 - 1)] <> $07 + byte[cell - constant(40 - 1)] := towhat + 1 + if byte[cell - 1] <> $07 + byte[cell - 1] := towhat + 1 + if byte[cell] <> $07 + byte[cell] := towhat + 1 + if byte[cell + 1] <> $07 + byte[cell + 1] := towhat + if byte[cell + constant(40 - 1)] <> $07 + byte[cell + constant(40 - 1)] := towhat + if byte[cell + 40] <> $07 + byte[cell + 40] := towhat + if byte[cell + constant(40 + 1)] <> $07 + byte[cell + constant(40 + 1)] := towhat + sn.explosion_sound + +pub CheckAround(cell) | ob + ob := byte[cell - 40] + if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not + return true + ob := byte[cell - 1] + if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not + return true + ob := byte[cell + 1] + if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not + return true + ob := byte[cell + 40] + if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not + return true + return false + +pub CheckEnclosed(cell) | ob, i + repeat i from 0 to 3 + ob := byte[cell + dirs[i]] + if ob == $00 or ob == $01 + return false + return true + +pub IncrementScore(amount) + Score += amount + st.set_score(Score) + if Score => NextLife and Men < 9 + ++Men + sc.new_life + NextLife += 500 + +pub AddBonusPoints | i, j + + i := j := st.get_time + repeat while i > 0 + st.set_time(--i) + IncrementScore(Level + 1) + if i < 10 + sn.time_ending_sound(i) + waitcnt(clkfreq / 32 + cnt) + else + sn.bonus_point_sound(j - i) + +dat + + long 0 'align + + ' screen array +screen byte $00[40*28] + +' color index 3 1 2 0 +palette long $06_6B_04_02 + +' -x- -y- +scroll long $0000_0000 + +status long 1 'set this to 1 to show the status line at the top + + ' status line + byte $90[20] + + ' foreground color for status line characters + byte $06[20] + + ' tiles +tiles word %%0_0_0_0_0_0_0_0 ' $00 space + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_1_0_0_1_0_1 ' $01 dirt + word %%1_1_0_0_1_0_0_1 + word %%0_1_2_1_0_1_2_0 + word %%1_1_0_1_1_1_0_1 + word %%1_0_1_1_1_0_1_1 + word %%0_2_1_0_1_2_1_0 + word %%2_1_1_2_2_0_1_1 + word %%1_0_1_1_1_1_2_0 + word %%0_1_1_1_2_1_1_1 + word %%1_2_0_1_1_1_2_0 + word %%1_2_1_0_2_1_0_1 + word %%0_2_1_1_0_1_2_1 + word %%1_0_1_0_1_0_1_0 + word %%1_1_0_0_1_1_0_1 + word %%1_0_1_2_0_1_0_0 + word %%0_1_0_0_1_0_1_0 + + word %%0_3_3_3_0_3_3_3 ' $02 brick wall + word %%0_2_3_3_0_2_3_3 + word %%0_2_2_2_0_2_2_2 + word %%0_0_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%2_2_0_2_2_2_0_2 + word %%0_0_0_0_0_0_0_0 + word %%0_3_3_3_0_3_3_3 + word %%0_2_3_3_0_2_3_3 + word %%0_2_2_2_0_2_2_2 + word %%0_0_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%2_2_0_2_2_2_0_2 + word %%0_0_0_0_0_0_0_0 + + word %%0_3_3_3_0_3_3_3 ' $03 magic wall + word %%0_2_3_3_0_2_2_2 + word %%0_2_2_2_0_2_2_2 + word %%0_0_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_3 + word %%2_2_0_2_2_2_0_2 + word %%0_0_0_0_0_0_0_0 + word %%0_3_3_3_0_3_3_3 + word %%0_2_3_3_0_2_3_3 + word %%0_2_2_2_0_2_2_2 + word %%0_0_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%2_2_0_2_2_2_0_2 + word %%0_0_0_0_0_0_0_0 + + word %%2_2_2_2_2_2_2_2 ' $04 out door (invisible) + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + + word %%0_0_0_0_0_0_0_0 ' $05 out door (flashing) + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $06 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%2_2_2_2_2_2_2_2 ' $07 steel wall + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + + word %%0_0_0_0_0_0_0_0 ' $08 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $09 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0A + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0B + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0C + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0D + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0E + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0F + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_3_3_3_0_0_0 ' $10 boulder stationary + word %%0_3_2_3_1_3_0_0 + word %%3_1_3_2_3_3_3_0 + word %%2_3_1_2_1_3_3_3 + word %%2_2_2_1_2_3_3_3 + word %%2_1_2_2_2_1_2_3 + word %%2_2_1_1_2_2_3_3 + word %%2_2_2_2_2_1_2_3 + word %%2_0_2_2_2_2_2_1 + word %%2_2_0_2_2_1_2_1 + word %%2_0_2_2_2_2_2_2 + word %%2_2_0_2_2_2_2_2 + word %%2_2_2_0_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_0_1_2_0_0 + word %%0_0_0_2_2_0_0_0 + + word %%0_0_3_3_3_0_0_0 ' $11 boulder stationary, scanned this frame + word %%0_3_2_3_1_3_0_0 + word %%3_1_3_2_3_3_3_0 + word %%2_3_1_2_1_3_3_3 + word %%2_2_2_1_2_3_3_3 + word %%2_1_2_2_2_1_2_3 + word %%2_2_1_1_2_2_3_3 + word %%2_2_2_2_2_1_2_3 + word %%2_0_2_2_2_2_2_1 + word %%2_2_0_2_2_1_2_1 + word %%2_0_2_2_2_2_2_2 + word %%2_2_0_2_2_2_2_2 + word %%2_2_2_0_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_0_1_2_0_0 + word %%0_0_0_2_2_0_0_0 + + word %%0_0_3_3_3_0_0_0 ' $12 boulder falling + word %%0_3_2_3_1_3_0_0 + word %%3_1_3_2_3_3_3_0 + word %%2_3_1_2_1_3_3_3 + word %%2_2_2_1_2_3_3_3 + word %%2_1_2_2_2_1_2_3 + word %%2_2_1_1_2_2_3_3 + word %%2_2_2_2_2_1_2_3 + word %%2_0_2_2_2_2_2_1 + word %%2_2_0_2_2_1_2_1 + word %%2_0_2_2_2_2_2_2 + word %%2_2_0_2_2_2_2_2 + word %%2_2_2_0_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_0_1_2_0_0 + word %%0_0_0_2_2_0_0_0 + + word %%0_0_3_3_3_0_0_0 ' $13 boulder falling, scanned this frame + word %%0_3_2_3_1_3_0_0 + word %%3_1_3_2_3_3_3_0 + word %%2_3_1_2_1_3_3_3 + word %%2_2_2_1_2_3_3_3 + word %%2_1_2_2_2_1_2_3 + word %%2_2_1_1_2_2_3_3 + word %%2_2_2_2_2_1_2_3 + word %%2_0_2_2_2_2_2_1 + word %%2_2_0_2_2_1_2_1 + word %%2_0_2_2_2_2_2_2 + word %%2_2_0_2_2_2_2_2 + word %%2_2_2_0_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_0_1_2_0_0 + word %%0_0_0_2_2_0_0_0 + + word %%0_0_0_2_3_0_0_0 ' $14 diamond stationary + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_2_2_2_2_2_3_0 + word %%0_1_1_1_1_1_2_0 + word %%2_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%2_1_1_1_1_1_1_3 + word %%1_2_2_2_2_2_2_2 + word %%0_2_3_3_3_3_3_0 + word %%0_1_3_3_3_3_2_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 ' $15 diamond stationary, scanned + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_2_2_2_2_2_3_0 + word %%0_1_1_1_1_1_2_0 + word %%2_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%2_1_1_1_1_1_1_3 + word %%1_2_2_2_2_2_2_2 + word %%0_2_3_3_3_3_3_0 + word %%0_1_3_3_3_3_2_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 ' $16 diamond falling + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_2_2_2_2_2_3_0 + word %%0_1_1_1_1_1_2_0 + word %%2_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%2_1_1_1_1_1_1_3 + word %%1_2_2_2_2_2_2_2 + word %%0_2_3_3_3_3_3_0 + word %%0_1_3_3_3_3_2_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 ' $17 diamond falling, scanned + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_2_2_2_2_2_3_0 + word %%0_1_1_1_1_1_2_0 + word %%2_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%2_1_1_1_1_1_1_3 + word %%1_2_2_2_2_2_2_2 + word %%0_2_3_3_3_3_3_0 + word %%0_1_3_3_3_3_2_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $18 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $19 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1A + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1B explode to space frame 1 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_3_0_0_0 + word %%0_0_0_3_0_0_3_0 + word %%0_0_0_0_3_0_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_0_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1C explode to space frame 2 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_0_3_0_1_0_0 + word %%0_3_1_0_0_0_3_0 + word %%0_1_0_0_1_3_1_0 + word %%0_3_0_1_0_0_1_0 + word %%0_0_0_0_1_3_0_0 + word %%0_3_1_0_1_0_0_0 + word %%0_1_0_1_0_1_0_0 + word %%0_0_3_1_1_0_3_0 + word %%0_0_3_0_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1D explode to space frame 3 + word %%0_0_0_0_0_0_0_0 + word %%0_3_0_0_3_0_3_0 + word %%0_0_0_3_0_2_0_0 + word %%0_3_0_1_0_1_3_0 + word %%0_1_2_0_0_0_1_0 + word %%0_2_0_0_2_1_2_0 + word %%3_1_0_2_0_0_2_0 + word %%0_0_0_0_1_1_0_0 + word %%3_1_2_0_1_0_3_0 + word %%0_2_0_2_0_1_0_0 + word %%0_0_1_2_1_0_1_0 + word %%3_0_1_0_1_0_3_0 + word %%0_0_0_3_3_0_0_0 + word %%0_3_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1E explode to space frame 4, same as frame 2 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_0_3_0_1_0_0 + word %%0_3_1_0_0_0_3_0 + word %%0_1_0_0_1_3_1_0 + word %%0_3_0_1_0_0_1_0 + word %%0_0_0_0_1_3_0_0 + word %%0_3_1_0_1_0_0_0 + word %%0_1_0_1_0_1_0_0 + word %%0_0_3_1_1_0_3_0 + word %%0_0_3_0_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1F explode to space frame 5, same as frame 1 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_3_0_0_0 + word %%0_0_0_3_0_0_3_0 + word %%0_0_0_0_3_0_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_0_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $20 explode to diamond frame 1 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_3_0_0_0 + word %%0_0_0_3_0_0_3_0 + word %%0_0_0_0_3_0_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_0_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_3_0_0_0 ' $21 explode to diamond frame 2 + word %%3_0_3_0_0_0_3_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_3_0_3_0_3_0 + word %%0_3_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%3_0_0_0_0_0_0_3 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%3_0_0_0_0_0_3_0 + word %%0_0_0_0_0_0_0_0 + word %%0_3_0_0_3_0_0_3 + word %%0_0_0_3_0_0_0_0 + word %%3_0_0_0_0_0_3_0 + word %%0_0_3_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_1_1_0_0_0 ' $22 explode to diamond frame 3 + word %%0_3_0_3_0_0_0_0 + word %%0_0_1_0_0_1_0_3 + word %%0_0_3_0_2_3_0_0 + word %%0_0_0_2_0_0_1_0 + word %%0_0_0_0_0_0_3_0 + word %%1_0_2_0_0_2_0_1 + word %%3_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%3_0_2_0_0_0_0_3 + word %%0_0_0_0_0_2_2_0 + word %%0_3_0_2_0_0_3_0 + word %%0_0_1_0_1_2_0_0 + word %%0_0_3_0_0_0_0_3 + word %%0_3_0_1_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + + word %%0_0_0_1_1_0_0_0 ' $23 explode to diamond frame 4 + word %%0_0_0_3_3_0_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_3_0_2_3_0_0 + word %%0_1_0_2_0_0_1_0 + word %%0_3_0_0_3_0_3_0 + word %%1_0_2_3_1_2_0_1 + word %%3_1_0_2_2_0_2_3 + word %%1_0_0_3_0_1_1_2 + word %%3_0_2_0_2_0_0_3 + word %%0_1_1_0_0_3_2_0 + word %%0_3_0_2_2_0_3_0 + word %%0_0_1_3_0_2_0_0 + word %%0_0_3_0_1_3_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + + word %%0_0_0_1_1_0_0_0 ' $24 explode to diamond frame 5 + word %%0_0_0_3_3_0_0_0 + word %%0_0_1_2_1_1_0_0 + word %%0_0_3_2_2_3_0_0 + word %%0_1_1_3_3_2_1_0 + word %%0_3_2_3_2_2_3_0 + word %%1_2_3_1_1_3_3_1 + word %%3_3_2_3_3_2_1_3 + word %%1_2_2_3_2_3_1_2 + word %%3_2_3_1_3_1_1_3 + word %%0_1_2_3_1_3_2_0 + word %%0_3_2_1_2_1_3_0 + word %%0_0_1_3_3_2_0_0 + word %%0_0_3_2_1_3_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + + word %%2_2_2_2_2_2_2_2 ' $25 inbox, flashing + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_2_2_2_2_2_2_2 + + word %%0_0_0_0_0_0_0_0 ' $26 inbox morphing into rockford, same as explode to space frame 1 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_3_0_0_0 + word %%0_0_0_3_0_0_3_0 + word %%0_0_0_0_3_0_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_0_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $27 inbox morphing into rockford, same as explode to space frame 2 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_0_3_0_1_0_0 + word %%0_3_1_0_0_0_3_0 + word %%0_1_0_0_1_3_1_0 + word %%0_3_0_1_0_0_1_0 + word %%0_0_0_0_1_3_0_0 + word %%0_3_1_0_1_0_0_0 + word %%0_1_0_1_0_1_0_0 + word %%0_0_3_1_1_0_3_0 + word %%0_0_3_0_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $28 inbox morphing into rockford, same as explode to space frame 3 + word %%0_0_0_0_0_0_0_0 + word %%0_3_0_0_3_0_3_0 + word %%0_0_0_3_0_2_0_0 + word %%0_3_0_1_0_1_3_0 + word %%0_1_2_0_0_0_1_0 + word %%0_2_0_0_2_1_2_0 + word %%3_1_0_2_0_0_2_0 + word %%0_0_0_0_1_1_0_0 + word %%3_1_2_0_1_0_3_0 + word %%0_2_0_2_0_1_0_0 + word %%0_0_1_2_1_0_1_0 + word %%3_0_1_0_1_0_3_0 + word %%0_0_0_3_3_0_0_0 + word %%0_3_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $29 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2A + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2B + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2C + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2D + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2E + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2F + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $30 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $31 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $32 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $33 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $34 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $35 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $36 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $37 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $38 rockford + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_0_2_0 + word %%0_2_0_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_3_3_0_2_0 + word %%0_0_3_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $39 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $3A + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $3B + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%2_2_2_2_2_2_2_2 ' $3C + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + + word %%0_0_0_0_0_0_0_0 ' $3D + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $3E + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $3F + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + +' chargen + + word %%0_0_0_0_0_0_0_0 ' $80 '0' + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $81 '1' + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $82 '2' + word %%0_3_3_3_3_3_0_0 + word %%3_3_0_0_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_0_0_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $83 + word %%0_3_3_3_3_3_3_0 + word %%0_0_0_0_3_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $84 + word %%3_3_0_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_0 + word %%3_3_3_3_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_0_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $85 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%0_0_0_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $86 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $87 + word %%3_3_3_3_3_3_3_0 + word %%3_0_0_0_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $88 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $89 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%0_3_3_3_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8A ':' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8B ';' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8C '/' + word %%0_0_0_0_0_0_3_0 + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_3_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_0_0_0_0 + word %%0_3_3_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8D + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8E + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8F + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $90 space + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $91 'A' + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $92 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $93 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $94 + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_0_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_3_3_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $95 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $96 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $97 + word %%0_3_3_3_3_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_3_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $98 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $99 + word %%0_3_3_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_3_3_0_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $9A + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%0_3_3_3_3_3_3_0 + word %%0_0_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $9B + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_3_3_0_0 + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_0_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $9C + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $9D + word %%3_3_0_0_0_3_3_0 + word %%3_3_3_0_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_0_3_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $9E + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_3_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $9F + word %%0_3_3_3_3_3_0_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A1 + word %%0_0_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_3_3_0_0 + word %%0_3_3_3_3_3_3_0 + word %%0_0_3_3_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A2 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A3 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%0_3_3_3_3_3_0_0 + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A4 + word %%3_3_3_3_3_3_3_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A5 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A6 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A7 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_3_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_3_3_3_0 + word %%3_3_0_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A8 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%0_0_3_3_3_3_0_0 + word %%0_0_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A9 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%0_3_3_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AA + word %%3_3_3_3_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $AB '(' + word %%0_0_0_0_3_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AC diamond + word %%0_0_0_3_0_0_0_0 + word %%0_0_3_0_3_0_0_0 + word %%0_3_3_3_3_3_0_0 + word %%3_0_0_0_0_0_3_0 + word %%0_3_3_3_3_3_0_0 + word %%0_0_3_0_3_0_0_0 + word %%0_0_0_3_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AD ')' + word %%0_0_3_3_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AE + word %%0_0_3_0_0_3_0_0 + word %%0_0_3_3_3_3_0_0 + word %%0_3_0_3_3_0_3_0 + word %%0_3_0_3_3_0_3_0 + word %%0_0_3_3_3_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AF ',' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_0_0_0_0 + + word %%1_3_2_2_1_3_2_2 ' $B0 scrolling bgnd of the title screen + word %%1_2_2_2_1_2_2_2 + word %%0_1_2_2_0_1_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_1_3_2_2_1_3 + word %%2_2_1_2_2_2_1_2 + word %%2_2_0_1_2_2_0_1 + word %%2_2_2_2_2_2_2_2 + + word %%3_3_3_3_3_3_3_3 ' $B1 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + + word %%1_2_3_3_3_3_3_3 ' $B2 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + + word %%3_3_3_3_0_0_0_0 ' $B3 + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + + word %%3_3_3_3_3_3_3_3 ' $B4 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_0_0_0 + + word %%3_3_3_3_0_0_0_0 ' $B5 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + + word %%0_0_0_0_3_3_3_3 ' $B6 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + + word %%0_0_0_0_0_0_0_0 ' $B7 + word %%3_0_0_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + + word %%3_3_3_3_0_0_0_0 ' $B8 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_0_0_0_0_0_0_0 + + word %%1_2_3_3_0_0_0_0 ' $B9 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + + word %%0_0_0_0_1_2_3_3 ' $BA + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + + word %%0_0_0_0_1_2_3_3 ' $BB + word %%0_0_0_0_1_2_2_2 + word %%0_0_0_0_1_2_2_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_3 + + word %%3_3_3_3_3_3_3_3 ' $BC + word %%2_3_2_3_3_3_2_3 + word %%2_3_2_2_3_2_2_3 + word %%3_3_2_2_2_2_2_3 + word %%3_3_2_3_2_3_2_3 + word %%3_3_2_3_3_3_2_3 + word %%3_3_2_3_3_3_2_3 + word %%3_3_3_3_3_3_3_3 + + word %%3_3_3_3_0_0_0_0 ' $BD + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + + word %%3_3_3_3_3_3_3_3 ' $BE + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_0_0_0 + + word %%3_3_3_3_0_0_0_0 ' $BF + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + + word %%0_0_0_0_3_3_3_3 ' $C0 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + + word %%0_0_0_0_0_0_0_0 ' $C1 + word %%3_0_0_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + + word %%3_3_3_3_0_0_0_0 ' $C2 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_0_0_0_0_0_0_0 + + word %%1_2_3_3_0_0_0_0 ' $C3 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + + word %%0_0_0_0_1_2_3_3 ' $C4 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + + word %%0_0_0_0_1_2_3_3 ' $C5 + word %%0_0_0_0_1_2_2_2 + word %%0_0_0_0_1_2_2_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_3 + + word %%0_0_0_0_0_0_0_0 ' $C6 unused... padding for second chargen (see below) + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $C7 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $C8 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $C9 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CA + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CB + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CC + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CD + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CE + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CF + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + +' this is basically the same character generator, but using +' a different color (I need this for the title screen). Either +' this, or separate color attributes for each cell of the +' screen. We have still some space here, so... + + word %%0_0_0_0_0_0_0_0 ' $D0 '0' + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D1 '1' + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $D2 '2' + word %%0_2_2_2_2_2_0_0 + word %%2_2_0_0_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_0_0_0_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $D3 + word %%0_2_2_2_2_2_2_0 + word %%0_0_0_0_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D4 + word %%2_2_0_0_0_0_0_0 + word %%2_2_0_0_0_0_0_0 + word %%2_2_0_2_2_2_0_0 + word %%2_2_2_2_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_0_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D5 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_0_0 + word %%0_0_0_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D6 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D7 + word %%2_2_2_2_2_2_2_0 + word %%2_0_0_0_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D8 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D9 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DA ':' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DB ';' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DC '/' + word %%0_0_0_0_0_0_2_0 + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_0_0_0_0 + word %%0_2_2_0_0_0_0_0 + word %%2_2_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DD + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DE + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DF + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E0 space + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E1 'A' + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $E2 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E3 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E4 + word %%2_2_2_2_2_0_0_0 + word %%2_2_2_0_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_2_2_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_2_2_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E5 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $E6 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E7 + word %%0_2_2_2_2_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_2_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $E8 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $E9 + word %%0_2_2_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_2_2_0_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $EA + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $EB + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_2_2_0_0 + word %%2_2_2_2_2_0_0_0 + word %%2_2_2_2_2_0_0_0 + word %%2_2_2_0_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $EC + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $ED + word %%2_2_0_0_0_2_2_0 + word %%2_2_2_0_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_0_2_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $EE + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_2_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $EF + word %%0_2_2_2_2_2_0_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F1 + word %%0_0_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_2_2_0_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_2_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F2 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F3 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%0_2_2_2_2_2_0_0 + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F4 + word %%2_2_2_2_2_2_2_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F5 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F6 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F7 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_2_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_2_2_2_0 + word %%2_2_0_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F8 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F9 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%0_2_2_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FA + word %%2_2_2_2_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $FB '(' + word %%0_0_0_0_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FC diamond + word %%0_0_0_2_0_0_0_0 + word %%0_0_2_0_2_0_0_0 + word %%0_2_2_2_2_2_0_0 + word %%2_0_0_0_0_0_2_0 + word %%0_2_2_2_2_2_0_0 + word %%0_0_2_0_2_0_0_0 + word %%0_0_0_2_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FD ')' + word %%0_0_2_2_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FE + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_0_2_0 + word %%0_2_0_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FF ',' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_0_0_0_0 + diff --git a/source/boulder/bellatrix/bd_pal.spin b/source/boulder/bellatrix/bd_pal.spin new file mode 100644 index 0000000..beb6379 --- /dev/null +++ b/source/boulder/bellatrix/bd_pal.spin @@ -0,0 +1,3812 @@ +'Boulderdash, for Hydra or Demo Board. +'Version 0.95 +'Released to the public domain. + +' Changes: +' 2009-11-10 - Modified for the Demo Board. +' - Added 'readkey' routine to allow playing the game from the keyboard. +' - Rockford now can be moved around and the screen scrolls automatically. +' 2009-11-12 - Halved tile horizontal resolution to eliminate redundant pixel pairs +' (and BoulderDash uses 8x16 tiles anyway). This also halves tile memory +' requirements. +' - The scroller now runs in a separate cog. +' 2009-11-13 - Changed pixel clock settings in order to display 20 tiles per line, +' as in the classic C64/Atari BoulderDash I. +' - Added code to handle boulders and diamonds. Rockford cannot push yet +' boulders or pick-up diamonds. +' 2009-11-14 - Reversed pixel order in video driver in order to avoid having to define +' mirrored tiles. +' - Added more tiles, hopefully all the characters are there. +' - The scroller cog now also handles animated characters. +' - Rockford can pick-up diamonds and the screen flashes when diamond count +' reaches the target. +' - Rockford now walks facing in the right direction and gets "bored". +' 2009-11-15 - Added an optional status line. +' - Added a character font for the status line. +' - Main game loop moved to a separate routine. +' - Boulders can be pushed around. +' - New routines to cover and uncover the screen. +' - Added an infinite loop to the main routine, pressing ESC restarts the +' game. +' 2009-11-16 - Inbox now morphs into Rockford. +' - Rockford can exit through the Outbox. +' 2009-11-17 - Added hardware detection feature (Hydra, Demo Board, etc.) Video driver +' changed accordingly. Not sure if keyboard will work on Hydra. +' - Falling boulders and diamonds now can kill Rockford. +' - Added PAL timings table to video driver, but PAL mode is not working yet. +' 2009-11-18 - Synchronized scroller to vertical sync, scrolling is totally smooth now. +' - PAL mode now works. +' 2009-11-25 - Started adding support for fireflies and butterflies. Had to split the +' case statement in the main game loop into sections due to poor performance. +' - Added code to decode raw cave data of original Atari/C64 BoulderDash I. +' You can now import your favorite caves :) +' 2009-11-26 - Fireflies and butterflies now explode in contact with Rockford. +' - Time counts down, but there is no "out of time" condition yet. +' 2009-11-27 - Implemented the "pick without moving" Rockford trick (use left CTRL key). +' - Stop cave when time runs out. +' - Do not advance to next cave until current one is successfully completed. +' Game is now playable! Use LeftCtrl + LeftShift as a "cheat" to move to +' next cave without finishing the current one. The Escape key restarts the +' current cave. Sorry, no score points yet. +' 2009-11-28 - Status line now handled by a separate cog. +' - Flashing "Out of time" message when time runs out. +' - Space bar now pauses game. +' - Score points implemented. +' - No more unlimited lifes, sorry ;))) +' - New life every 500 points. +' 2009-11-29 - Using a table of codes to reset the 'scanned' flag avoids a second case +' statement and improves performance. +' - Implemented amoebas and magic wall. Now all the original caves work! +' - Added all the original BoulderDash I caves (except the intermissions) +' - Added a Level variable. After successfully finishing the last cave the +' game starts again from the first one of the next difficulty level. +' 2009-11-30 - Fixed a bug in amoeba handling that caused cave M to crash. +' 2009-12-02 - Game controller apparently does not like to be read too fast. +' - Added intermission caves. +' 2009-12-04 - Aborting the current cave will cost you a life. +' - Restart (or exit) automatically the cave if "Out of time" has been +' flashing for more than a minute without user input. +' - Throtle down Rockford a bit in levels 1 and 2 (is running too fast!) +' 2009-12-05 - Added the title screen (had a hard time scrolling the background behind +' those big letters!). +' - Starting cave and level can be selected from the title screen. +' - Run a demo if the title screen has been inactive for about a minute. +' 2009-12-06 - Fixed boulder/diamond rolling off: they must move to the side first, +' not directly diagonally. +' - Added a preliminary sound object. Nothing there yet. +' - Bonus points at the end of the cave increase with difficulty level. +' 2009-12-07 - First steps towards SID emulation via PWM. Single voice waveform generation +' already works (well, sort of). No envelope control yet. +' 2009-12-08 - SID emulator: noise waveform, amplitude control, 3 voices. Envelope +' control using a separate cog (see the ChangeLog in the SIDemu.spin file). +' 2009-12-09 - Integrated the SID emulator into the game, running out of cogs. +' - Got the main tune working. +' - Added a few other sound/noise effects the game. +' - Boulder noise interfers with diamond pick up sound. Which one has the +' preference? +' 2009-12-12 - Added the cover/uncover screen sound. +' - Added the bonus points sound. +' - Added amoeba and magic wall sound. +' +' TODO: +' - Finish it :) +' - Add broadcast TV mode with sound carrier to use the TV antenna input (like in old times :)) +' +' +' Anpassungen für den Hive +' +' 09-01-2010 - Entfernung der Hardwareerkennung +' - Anpassung Konfiguration an Hive/Bellatrix +' - Gamecontr. entfernt +' - Auskommentierung Sound +' 12-01-2010 - Scrolltext im Titelscreen +' - Optimierung Soundobjekt + +con + + _clkmode = xtal1 + pll16x + _xinfreq = 5_000_000 + + ' The supported video modes + TV_NTSC = 0 + TV_PAL = 1 + + TV_MODE = TV_PAL ' <--- Select your TV system here -- NTSC or PAL ---<<< + + ' Game controller codes + GP_RIGHT = %00000001 '(Right arrow) Move right + GP_LEFT = %00000010 '(Left arrow) Move left + GP_DOWN = %00000100 '(Down arrow) Move down + GP_UP = %00001000 '(Up arrow) Move up + GP_START = %00010000 '(Left Shift) Start game. Together with GP_SELECT: go to next cave (cheat) + GP_SELECT = %00100000 '(Left Ctrl) Pick + GP_B = %01000000 '(Space) Pause + GP_A = %10000000 '(Escape) Abort and restart current cave + +var + long nes + long last_dir + long cave_addr + long random_ptr + long screen_height + long sx, sy + long video_params[7] + long sound_pin + long Score + long NextLife + byte temp_cave[40*22] + byte HWType + byte Cave + byte Level + byte CaveNumber + byte DiamondCount + byte DiamondsNeeded + byte DiamondValue + byte ExtraValue + byte CaveTime + byte Men + byte Alive + byte MagicWallStatus + byte MagicWallTime + byte AmoebaStatus + byte AmoebaTime + byte target + byte vsync + byte door_x, door_y + +obj + tv: "Boulderdash_Tile_TV" + kb: "Keyboard" + sc: "Scroller" + st: "Status" + rr: "RealRandom" + sn: "Sounds" + +pub main | success + + video_params[0] := %0_11_101_000 ' Set Mode for VCFG + video_params[1] := 2 ' Set Pingroup used by TV driver. + video_params[2] := %0111_0000 ' Set Pinmask for VCFG pins. + video_params[3] := %0000_0111<<20 ' Set Pinmask for output pins. + + video_params[4] := TV_MODE + video_params[5] := @screen + video_params[6] := @vsync + + if video_params[4] == TV_NTSC + screen_height := 12 + else + screen_height := 14 + + rr.start 'start the real random number generator + random_ptr := rr.random_ptr + + bytefill(@screen, $00, constant(40 * 22)) 'clear screen + + tv.start(@video_params) 'start the TV driver + sc.start(@video_params, random_ptr) 'start the scroller + st.start(@video_params) 'start the status line handler + kb.start(17, 16) 'start the keyboard driver + sn.start 'start the sound engine + + cave_addr := @screen + + repeat + + repeat + success := TitleScreen + + palette.byte[1] := $04 + palette.byte[2] := $4B + palette.byte[3] := $06 + bytefill(@screen, $3C, constant(40 * 22)) 'fill the screen with the scrolling pattern + status := 0 + + Score := 0 + Men := 3 + + if success + quit + else + Demo + + repeat + + sn.music_off + + CaveNumber := byte[@@caves[Cave]] + st.player_params(1, Men, CaveNumber, Level, Score) + st.set_mode(st#STATUS_PRE) + + CreateCave(@@caves[Cave], @temp_cave) + st.cave_params(DiamondsNeeded, DiamondValue, CaveTime) + + last_dir := -1 'last rockford direction + sc.rockford_go(0) 'rockford initially stands still + sc.milling_off + + if CaveNumber > 16 + 'intermission + sx := 0 + sy := 0 + else + 'normal cave + sx := door_x - 10 + sx <#= constant(40 - 20) + sx #>= 0 + sy := door_y - screen_height / 2 + sy <#= 22 - screen_height + sy #>= 0 + sc.scroll_to(sx * 8, sy * 16) + + Uncover 'uncover screen + success := GameLoop + + if not success + if --Men == 0 + st.set_mode(st#STATUS_GAME_OVER) + waitcnt(clkfreq + cnt) + Cover + quit + + if success or CaveNumber > 16 + 'go to next cave only if current one was completed + 'but never restart intermissions + if success and CaveNumber > 16 and Men < 9 + ++Men 'the promised bonus life + if caves[++Cave] == 0 + if Level < 4 + ++Level + Cave := 0 + + st.player_params(1, Men, CaveNumber, Level, Score) + st.set_mode(st#STATUS_PRE) + Cover 'cover screen with scrolling pattern + + +pub TitleScreen | x, y, h, t, i, j, lk, ticks, count, scr + + if TV_MODE == TV_NTSC + h := 24 + t := 2 + ticks := constant(60 * 130 / 2) 'dr235 + else + h := 28 + t := 4 + ticks := constant(50 * 130 / 2) + + scr := 0 + + bytefill(@screen, $00, constant(40 * 28)) 'clear screen + palette.byte[1] := $FC + palette.byte[2] := $FB + palette.byte[3] := $06 + st.set_mode(st#STATUS_NONE) + + Cave := 0 + Level := 0 + CaveNumber := byte[@@caves[Cave]] + + repeat x from 0 to 19 + byte[@screen + x] := $B1 + byte[@screen + x + (h - 6) * 40] := $B1 + repeat y from 1 to h - 7 + byte[@screen + y * 40] := $B5 + repeat x from 1 to 18 + byte[@screen + x + y * 40] := $B0 + byte[@screen + 19 + y * 40] := $B6 + + i := 0 + repeat y from t to t + 6 + repeat x from 1 to 18 + byte[@screen + x + y * 40] := big_boulder.byte[i++] + + i := 0 + repeat y from t + 8 to t + 14 + repeat x from 3 to 15 + byte[@screen + x + y * 40] := big_dash.byte[i++] + + status := 2 + scroll := 0 + 'st.text_out(@screen + (h - 4) * 40, @str1, 20) + scr++ + repeat i from 0 to 19 + 'j := str1.byte[i] + j := scr1.byte[i + scr] + if j == $20 + byte[@screen + (h - 4) * 40 + i] := $90 + else + byte[@screen + (h - 4) * 40 + i] := j + $A0 + st.text_out(@screen + (h - 3) * 40, @str2, 20) + st.text_out(@screen + (h - 2) * 40, @str3, 20) + st.text_out(@screen + (h - 1) * 40, @str4, 20) + + screen.byte[(h - 2) * 40] := $D1 'player(s) + screen.byte[(h - 2) * 40 + 10] := $D1 'joystick(s) + screen.byte[(h - 1) * 40 + 7] := CaveNumber + $E0 + screen.byte[(h - 1) * 40 + 17] := Level + $D1 + + lk := 0 'last key + count := ticks + + sn.music_on + + repeat while count > 0 + + 'wait for vsync, count every other tick + repeat while vsync == 0 + repeat while vsync <> 0 + repeat while vsync == 0 + repeat while vsync <> 0 + --count + + 'scrolltext + scr++ + if (scr>>2) > 318 '(scr2 - scr1) + scr := 0 + repeat i from 0 to 19 + j := scr1.byte[i + (scr>>2)] + if j == $20 + byte[@screen + (h - 4) * 40 + i] := $90 + else + byte[@screen + (h - 4) * 40 + i] := j + $A0 + + ' scrolling background + x := @tiles + constant(16 * $B0) + y := word[x] + wordmove(x, x + 2, 7) + word[x + 15] := y + + repeat i from 0 to 5 + repeat y from 0 to 14 step 2 + x := @tiles + constant(16 * $B0) + y + t := @tiles + constant(16 * $BD) + y + 16 * i + j := @tiles + constant(16 * $B3) + y + 16 * i + word[j] := word[x] | word[t] + repeat y from 0 to 14 step 2 + x := @tiles + constant(16 * $B0) + y + t := @tiles + constant(16 * $C3) + y + j := @tiles + constant(16 * $B9) + y + word[j] := (word[x] & $00FF) | word[t] + repeat y from 0 to 14 step 2 + x := @tiles + constant(16 * $B0) + y + t := @tiles + constant(16 * $C4) + y + j := @tiles + constant(16 * $BA) + y + word[j] := (word[x] & $FF00) | word[t] + repeat y from 0 to 14 step 2 + x := @tiles + constant(16 * $B0) + y + t := @tiles + constant(16 * $C5) + y + j := @tiles + constant(16 * $BB) + y + word[j] := (word[x] & $FF00) | word[t] + + i := read_input + if i <> lk + count := ticks 'reset countdown + if i & GP_START + sn.music_off + return 1 + elseif i & GP_LEFT + if Cave => 5 + Cave -= 5 + CaveNumber := byte[@@caves[Cave]] + screen.byte[(h - 1) * 40 + 7] := CaveNumber + $E0 + elseif i & GP_RIGHT + if Cave =< 10 + Cave += 5 + CaveNumber := byte[@@caves[Cave]] + screen.byte[(h - 1) * 40 + 7] := CaveNumber + $E0 + elseif i & GP_UP + if Level < 4 + ++Level + screen.byte[(h - 1) * 40 + 17] := Level + $D1 + elseif i & GP_DOWN + if Level > 0 + --Level + screen.byte[(h - 1) * 40 + 17] := Level + $D1 + lk := i + + sn.music_off + return 0 + +dat + +big_boulder + byte $B2, $B1, $B7, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0 + byte $B2, $B0, $B9, $B2, $B1, $BA, $B5, $B9, $B2, $B0, $BA, $B1, $B7, $B2, $B1, $BA, $B1, $B7 + byte $B2, $B1, $B8, $B2, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9 + byte $B2, $B1, $B7, $B2, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9, $B2, $B5, $BA, $B1, $B8 + byte $B2, $B0, $B9, $B2, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $B9, $B2, $B0, $BA, $B1, $B7 + byte $B2, $B1, $B5, $B2, $B1, $BA, $B1, $B5, $B2, $B1, $BA, $B1, $B5, $B2, $B1, $BA, $B5, $B9 + byte $B2, $B1, $B8, $B2, $B1, $BA, $B1, $B5, $B2, $B1, $BA, $B1, $B8, $B2, $B1, $BA, $B5, $B9 + +big_dash + byte $BA, $B1, $B3, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0, $B0 + byte $BA, $B5, $BA, $B0, $B2, $B7, $B2, $B1, $BA, $B5, $BA, $BB, $BC + byte $BA, $B5, $BA, $BA, $B5, $B9, $B2, $B0, $BA, $B5, $BA, $B0, $B0 + byte $BA, $B5, $BA, $BA, $B1, $B5, $B2, $B1, $BA, $B1, $B1, $B0, $B0 + byte $BA, $B5, $BA, $BA, $B5, $B9, $B0, $B2, $BA, $B5, $BA, $B0, $B0 + byte $BA, $B1, $B1, $BA, $B5, $B9, $B2, $B1, $BA, $B5, $BA, $B0, $B0 + byte $BA, $B1, $B4, $BA, $B5, $B9, $B2, $B1, $BA, $B5, $BA, $B0, $B0 + +str1 byte " HIVE VERSION " +str2 byte "PRESS BUTTON TO PLAY" +str3 byte " PLAYER JOYSTICK" +str4 byte " CAVE: LEVEL: " + +scr1 byte " " + byte "THANKS :SPORK FROGS: :HPG: :AHLE2: AND THE OTHER PROPELLERHEADS FOR THE BASECODE" + byte " " + byte "THANKS PEX :MAHONEY: TUFVESSON FOR THE COOL MUSIC" + byte " " + byte "GRUSS AN ALLE HIVE-DROHNEN" + byte " " + byte "HIVE: WE ARE BORG - RESISTANCE IS FUTILE" + byte " " + byte "DROHNE235: HIVE-VERSION 2010" + byte " " +scr2 byte 0 + +pub Demo + + Score := 0 + Cave := 0 'demo happens on cave A + Level := 0 + CaveNumber := byte[@@caves[Cave]] + st.player_params(1, Men, CaveNumber, Level, Score) + st.set_mode(st#STATUS_PRE) + + CreateCave(@@caves[Cave], @temp_cave) + st.cave_params(DiamondsNeeded, DiamondValue, CaveTime) + + last_dir := -1 'last rockford direction + sc.rockford_go(0) 'rockford initially stands still + sc.milling_off + + sx := door_x - 10 + sx <#= constant(40 - 20) + sx #>= 0 + sy := door_y - screen_height / 2 + sy <#= 22 - screen_height + sy #>= 0 + sc.scroll_to(sx * 8, sy * 16) + + demo_ptr := @demo_data 'set demo data pointer + kcount := 0 + + Uncover 'uncover screen + GameLoop 'play the demo + Cover 'cover screen back + +var + + long demo_ptr + byte kcount, last_key + +dat + +' The low nibble of each byte is the direction of movement: +' $x0 = no movement +' $x1 = Right +' $x2 = Left +' $x3 = Down +' $x4 = Up +' bit 3 ($x8) set means GP_SELECT is pressed (not used here anyway) +' The high nibble is the number of scan frames to apply the movement. +' $00 means end of demo data. + +demo_data + byte $F0, $10, $14, $71, $23, $91, $40, $23 + byte $41, $34, $12, $40, $14, $B1, $13, $21 + byte $40, $63, $11, $43, $32, $40, $13, $12 + byte $41, $32, $40, $44, $52, $34, $52, $43 + byte $32, $50, $34, $A2, $14, $32, $13, $62 + byte $43, $11, $40, $33, $41, $43, $42, $24 + byte $21, $34, $A1, $A1, $13, $41, $13, $41 + byte $23, $50, $51, $44, $51, $60, $13, $00 + +pub readkey : key + + if demo_ptr + if kcount > 0 + --kcount + return last_key + else + key := byte[demo_ptr++] + if key == $00 + demo_ptr := 0 + else + kcount := key / 16 - 1 + case key & $07 + $0: last_key := 0 + $1: last_key := GP_RIGHT + $2: last_key := GP_LEFT + $3: last_key := GP_DOWN + $4: last_key := GP_UP + if key & $08 + last_key |= GP_SELECT + return last_key + + key := 0 + if kb.keystate($C0) + key |= GP_LEFT + if kb.keystate($C1) + key |= GP_RIGHT + if kb.keystate($C2) + key |= GP_UP + if kb.keystate($C3) + key |= GP_DOWN + if kb.keystate($F2) 'left control key + key |= GP_SELECT + if kb.keystate($CB) 'escape key + key |= GP_A + if kb.keystate($20) 'space key + key |= GP_B + if kb.keystate($F0) 'left shift + key |= GP_START + if kb.keystate($0D) 'or enter + key |= GP_START + +pub read_input + + return readkey + + +var + byte RandSeed1, RandSeed2 + +pub GetRandom | temp1, temp2, temp3, cy, r + +'' Generate a pseudo-random number, given a seed +'' The output matches the one used in the original BoulderDash I + + temp1 := (RandSeed1 & 1) << 7 + temp2 := (RandSeed2 & 1) << 7 + temp3 := (RandSeed2 >> 1) & $7F + + r := RandSeed2 + temp2 + if r > $FF + cy := 1 + r &= $FF + else + cy := 0 + + r += cy + $13 + if r > $FF + cy := 1 + r &= $FF + else + cy := 0 + + RandSeed2 := r + + r := RandSeed1 + cy + temp1 + if r > $FF + cy := 1 + r &= $FF + else + cy := 0 + + r += cy + temp3 + RandSeed1 := r & $FF + +dat + +caves long @cave_A, @cave_B, @cave_C, @cave_D, @inter_1 + long @cave_E, @cave_F, @cave_G, @cave_H, @inter_2 + long @cave_I, @cave_J, @cave_K, @cave_L, @inter_3 + long @cave_M, @cave_N, @cave_O, @cave_P, @inter_4 + long 0 + +cave_A byte 1 'cave number + byte 20 'magic wall/amoeba time + byte 10 'initial diamond value + byte 15 'extra diamond value + byte 10, 11, 12, 13, 14 'randomizer seed per level + byte 12, 12, 12, 12, 12 'diamonds needed per level + byte 150, 110, 70, 40, 30 'time per level + byte $08, $0B, $09, $D4, $20 'bg color 1, bg color 2, fg color + byte $00, $10, $14, $00 'random objects + byte $3C, $32, $09, $00 'probability of object + byte $42, $01, $09, $1E, $02 'raw cave data + byte $42, $09, $10, $1E, $02 + byte $25, $03, $04 + byte $04, $26, $12 + byte $FF + +cave_B byte 2 + byte 20 + byte 20, 50 + byte $03, $00, $01, $57, $58 + byte $0A, $0C, $09, $0D, $0A + byte $96, $6E, $46, $46, $46 + byte $0A, $04, $09, $00, $00 + byte $00, $10, $14, $08 + byte $3C, $32, $09, $02 + byte $42, $01, $08, $26, $02, $42, $01, $0F, $26, $02, $42, $08, $03, $14, $04, $42 + byte $10, $03, $14, $04, $42, $18, $03, $14, $04, $42, $20, $03, $14, $04, $40, $01 + byte $05, $26, $02, $40, $01, $0B, $26, $02, $40, $01, $12, $26, $02, $40, $14, $03 + byte $14, $04, $25, $12, $15, $04, $12, $16, $FF + +cave_C byte 3 + byte $00 + byte $0F, $00 + byte $00, $32, $36, $34, $37 + byte $18, $17, $18, $17, $15 + byte $96, $64, $5A, $50, $46 + byte $09, $08, $09, $04, $00 + byte $02, $10, $14, $00 + byte $64, $32, $09, $00 + byte $25, $03, $04, $04, $27, $14, $FF + +cave_D byte 4 + byte $14 + byte $05, $14 + byte $00, $6E, $70, $73, $77 + byte $24, $24, $24, $24, $24 + byte $78, $64, $50, $3C, $32 + byte $04, $08, $09, $00, $00 + byte $10, $00, $00, $00 + byte $14, $00, $00, $00 + byte $25, $01, $03, $04, $26, $16, $81, $08, $0A, $04, $04, $00, $30, $0A, $0B, $81 + byte $10, $0A, $04, $04, $00, $30, $12, $0B, $81, $18, $0A, $04, $04, $00, $30, $1A + byte $0B, $81, $20, $0A, $04, $04, $00, $30, $22, $0B, $FF + +cave_E byte $05, $14, $32, $5A + byte $00, $00, $00, $00, $00 + byte $04, $05, $06, $07, $08 + byte $96, $78, $5A, $3C, $1E + byte $09, $0A, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $25, $01, $03, $04, $27, $16, $80, $08, $0A, $03, $03, $00, $80, $10, $0A, $03 + byte $03, $00, $80, $18, $0A, $03, $03, $00, $80, $20, $0A, $03, $03, $00, $14, $09 + byte $0C, $08, $0A, $0A, $14, $11, $0C, $08, $12, $0A, $14, $19, $0C, $08, $1A, $0A + byte $14, $21, $0C, $08, $22, $0A, $80, $08, $10, $03, $03, $00, $80, $10, $10, $03 + byte $03, $00, $80, $18, $10, $03, $03, $00, $80, $20, $10, $03, $03, $00, $14, $09 + byte $12, $08, $0A, $10, $14, $11, $12, $08, $12, $10, $14, $19, $12, $08, $1A, $10 + byte $14, $21, $12, $08, $22, $10, $FF + +cave_F byte $06, $14, $28, $3C + byte $00, $14, $15, $16, $17 + byte $04, $06, $07, $08, $08 + byte $96, $78, $64, $5A, $50 + byte $0E, $0A, $09, $00, $00 + byte $10, $00, $00, $00 + byte $32, $00, $00, $00 + byte $82, $01, $03, $0A, $04, $00, $82, $01, $06, $0A, $04, $00, $82, $01, $09, $0A + byte $04, $00, $82, $01, $0C, $0A, $04, $00, $41, $0A, $03, $0D, $04, $14, $03, $05 + byte $08, $04, $05, $14, $03, $08, $08, $04, $08, $14, $03, $0B, $08, $04, $0B, $14 + byte $03, $0E, $08, $04, $0E, $82, $1D, $03, $0A, $04, $00, $82, $1D, $06, $0A, $04 + byte $00, $82, $1D, $09, $0A, $04, $00, $82, $1D, $0C, $0A, $04, $00, $41, $1D, $03 + byte $0D, $04, $14, $24, $05, $08, $23, $05, $14, $24, $08, $08, $23, $08, $14, $24 + byte $0B, $08, $23, $0B, $14, $24, $0E, $08, $23, $0E, $25, $03, $14, $04, $26, $14 + byte $FF + +cave_G byte $07, $4B, $0A, $14 + byte $02, $07, $08, $0A, $09 + byte $0F, $14, $19, $19, $19 + byte $78, $78, $78, $78, $78 + byte $09, $0A, $0D, $00, $00 + byte $00, $10, $08, $00 + byte $64, $28, $02, $00 + byte $42, $01, $07, $0C, $02, $42, $1C, $05, $0B, $02, $7A, $13, $15, $02, $02, $14 + byte $04, $06, $14, $04, $0E, $14, $04, $16, $14, $22, $04, $14, $22, $0C, $14, $22 + byte $16, $25, $14, $03, $04, $27, $07, $FF + +cave_H byte $08, $14, $0A, $14 + byte $01, $03, $04, $05, $06 + byte $0A, $0F, $14, $14, $14 + byte $78, $6E, $64, $5A, $50 + byte $02, $0E, $09, $00, $00 + byte $00, $10, $08, $00 + byte $5A, $32, $02, $00 + byte $14, $04, $06, $14, $22, $04, $14, $22, $0C, $04, $00, $05, $25, $14, $03, $42 + byte $01, $07, $0C, $02, $42, $01, $0F, $0C, $02, $42, $1C, $05, $0B, $02, $42, $1C + byte $0D, $0B, $02, $43, $0E, $11, $08, $02, $14, $0C, $10, $00, $0E, $12, $14, $13 + byte $12, $41, $0E, $0F, $08, $02, $FF + +cave_I byte $09, $14, $05, $0A + byte $64, $89, $8C, $FB, $33 + byte $4B, $4B, $50, $55, $5A + byte $96, $96, $82, $82, $78 + byte $08, $04, $09, $00, $00 + byte $10, $14, $00, $00 + byte $F0, $78, $00, $00 + byte $82, $05, $0A, $0D, $0D, $00, $01, $0C, $0A, $82, $19, $0A, $0D, $0D, $00, $01 + byte $1F, $0A, $42, $11, $12, $09, $02, $40, $11, $13, $09, $02, $25, $07, $0C, $04 + byte $08, $0C, $FF + +cave_J byte $0A, $14, $19, $3C + byte $00, $00, $00, $00, $00 + byte $0C, $0C, $0C, $0C, $0C + byte $96, $82, $78, $6E, $64 + byte $06, $08, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $25, $0D, $03, $04, $27, $16, $54, $05, $04, $11, $03, $54, $15, $04, $11, $05 + byte $80, $05, $0B, $11, $03, $08, $C2, $01, $04, $15, $11, $00, $0D, $04, $C2, $07 + byte $06, $0D, $0D, $00, $0D, $06, $C2, $09, $08, $09, $09, $00, $0D, $08, $C2, $0B + byte $0A, $05, $05, $00, $0D, $0A, $82, $03, $06, $03, $0F, $08, $00, $04, $06, $54 + byte $04, $10, $04, $04, $FF + +cave_K byte $0B, $14, $32, $00 + byte $00, $04, $66, $97, $64 + byte $06, $06, $06, $06, $06 + byte $78, $78, $96, $96, $F0 + byte $0B, $08, $09, $00, $00 + byte $00, $10, $08, $00 + byte $64, $50, $02, $00 + byte $42, $0A, $03, $09, $04, $42, $14, $03, $09, $04, $42, $1E, $03, $09, $04, $42 + byte $09, $16, $09, $00, $42, $0C, $0F, $11, $02, $42, $05, $0B, $09, $02, $42, $0F + byte $0B, $09, $02, $42, $19, $0B, $09, $02, $42, $1C, $13, $0B, $01, $14, $04, $03 + byte $14, $0E, $03, $14, $18, $03, $14, $22, $03, $14, $04, $16, $14, $23, $15, $25 + byte $14, $14, $04, $26, $11, $FF + +cave_L byte $0C, $14, $14, $00 + byte $00, $3C, $02, $3B, $66 + byte $13, $13, $0E, $10, $15 + byte $B4, $AA, $A0, $A0, $A0 + byte $0C, $0A, $09, $00, $00 + byte $00, $10, $14, $00 + byte $3C, $32, $09, $00 + byte $42, $0A, $05, $12, $04, $42, $0E, $05, $12, $04, $42, $12, $05, $12, $04, $42 + byte $16, $05, $12, $04, $42, $02, $06, $0B, $02, $42, $02, $0A, $0B, $02, $42, $02 + byte $0E, $0F, $02, $42, $02, $12, $0B, $02, $81, $1E, $04, $04, $04, $00, $08, $20 + byte $05, $81, $1E, $09, $04, $04, $00, $08, $20, $0A, $81, $1E, $0E, $04, $04, $00 + byte $08, $20, $0F, $25, $03, $14, $04, $27, $16, $FF + +cave_M byte $0D, $8C, $05, $08 + byte $00, $01, $02, $03, $04 + byte $32, $37, $3C, $46, $50 + byte $A0, $9B, $96, $91, $8C + byte $06, $08, $0D, $00, $00 + byte $10, $00, $00, $00 + byte $28, $00, $00, $00 + byte $25, $12, $03, $04, $0A, $03, $3A, $14, $03, $42, $05, $12, $1E, $02, $70, $05 + byte $13, $1E, $02, $50, $05, $14, $1E, $02, $C1, $05, $15, $1E, $02, $FF + +cave_N byte $0E, $14, $0A, $14 + byte $00, $00, $00, $00, $00 + byte $1E, $23, $28, $2A, $2D + byte $96, $91, $8C, $87, $82 + byte $0C, $08, $09, $00, $00 + byte $10, $00, $00, $00 + byte $00, $00, $00, $00 + byte $81, $0A, $0A, $0D, $0D, $00, $70, $0B, $0B, $0C, $03, $C1, $0C, $0A, $03, $0D + byte $C1, $10, $0A, $03, $0D, $C1, $14, $0A, $03, $0D, $50, $16, $08, $0C, $02, $48 + byte $16, $07, $0C, $02, $C1, $17, $06, $03, $04, $C1, $1B, $06, $03, $04, $C1, $1F + byte $06, $03, $04, $25, $03, $03, $04, $27, $14, $FF + +cave_O byte $0F, $08, $0A, $14 + byte $01, $1D, $1E, $1F, $20 + byte $0F, $14, $14, $19, $1E + byte $78, $78, $78, $78, $8C + byte $08, $0E, $09, $00, $00 + byte $00, $10, $08, $00 + byte $64, $50, $02, $00 + byte $42, $02, $04, $0A, $03, $42, $0F, $0D, $0A, $01, $41, $0C, $0E, $03, $02, $43 + byte $0C, $0F, $03, $02, $04, $14, $16, $25, $14, $03, $FF + +cave_P byte $10, $14, $0A, $14 + byte $01, $78, $81, $7E, $7B + byte $0C, $0F, $0F, $0F, $0C + byte $96, $96, $96, $96, $96 + byte $09, $0A, $09, $00, $00 + byte $10, $00, $00, $00 + byte $32, $00, $00, $00 + byte $25, $01, $03, $04, $27, $04, $81, $08, $13, $04, $04, $00, $08, $0A, $14, $C2 + byte $07, $0A, $06, $08, $43, $07, $0A, $06, $02, $81, $10, $13, $04, $04, $00, $08 + byte $12, $14, $C2, $0F, $0A, $06, $08, $43, $0F, $0A, $06, $02, $81, $18, $13, $04 + byte $04, $00, $08, $1A, $14, $81, $20, $13, $04, $04, $00, $08, $22, $14, $FF + +inter_1 byte $11, $14, $1E, $00 + byte $0A, $0B, $0C, $0D, $0E + byte $06, $06, $06, $06, $06 + byte $0A, $0A, $0A, $0A, $0A + byte $0E, $02, $09, $00, $00 + byte $00, $14, $00, $00 + byte $FF, $09, $00, $00 + byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $00, $32, $0A, $0C, $10 + byte $0A, $04, $01, $0A, $05, $25, $03, $05, $04, $12, $0C, $FF + +inter_2 byte $12, $14, $0A, $00 + byte $0A, $0B, $0C, $0D, $0E + byte $10, $10, $10, $10, $10 + byte $0F, $0F, $0F, $0F, $0F + byte $06, $0F, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $01, $50, $01, $03, $09 + byte $03, $48, $02, $03, $08, $03, $54, $01, $05, $08, $03, $50, $01, $06, $07, $03 + byte $50, $12, $03, $09, $05, $54, $12, $05, $08, $05, $50, $12, $06, $07, $05, $25 + byte $01, $04, $04, $12, $04, $FF + +inter_3 byte $13, $04, $0A, $00 + byte $0A, $0B, $0C, $0D, $0E + byte $0E, $0E, $0E, $0E, $0E + byte $14, $14, $14, $14, $14 + byte $06, $08, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $00, $54, $01, $0C, $12 + byte $02, $88, $0F, $09, $04, $04, $08, $25, $08, $03, $04, $12, $07, $FF + +inter_4 byte $14, $03, $1E, $00 + byte $00, $00, $00, $00, $00 + byte $06, $06, $06, $06, $06 + byte $14, $14, $14, $14, $14 + byte $06, $08, $09, $00, $00 + byte $00, $00, $00, $00 + byte $00, $00, $00, $00 + byte $87, $00, $02, $28, $16, $07, $87, $00, $02, $14, $0C, $01, $D0, $0B, $03, $03 + byte $02, $80, $0B, $07, $03, $06, $00, $43, $0B, $06, $03, $02, $43, $0B, $0A, $03 + byte $02, $50, $08, $07, $03, $03, $25, $03, $03, $04, $09, $0A, $FF + +dat + +' C64 color table approximation. Not the most accurate one, but gives the desired effect. + +ctable byte $02, $06, $4B, $BC, $2B, $9C, $EB, $7D + byte $4B, $4A, $4B, $04, $04, $9D, $0B, $04 + +pub CreateCave(raw_cave, dest) | i, j, k, cx, cy, ci, co, dir, len + +'' Create cave contents from the description array + + CaveNumber := byte[raw_cave] + + RandSeed1 := 0 + RandSeed2 := byte[raw_cave + 4 + Level] + + ' Set colors + palette.byte[1] := ctable.byte[byte[raw_cave + 20]] + palette.byte[2] := ctable.byte[byte[raw_cave + 19]] + palette.byte[3] := ctable.byte[byte[raw_cave + 21] - 8] + + ' Place random objects + repeat cy from 1 to 21 + repeat cx from 0 to 39 + co := $01 ' dirt + GetRandom + repeat ci from 0 to 3 + if RandSeed1 < byte[raw_cave + 28 + ci] + co := byte[raw_cave + 24 + ci] + byte[dest + cx + cy * 40] := co + + ' Steel bounds + repeat cx from 0 to 39 + byte[dest + cx] := $07 + byte[dest + cx + 21 * 40] := $07 + repeat cy from 0 to 21 + byte[dest + cy * 40] := $07 + byte[dest + 39 + cy * 40] := $07 + + 'Decode raw data + i := raw_cave + 32 + repeat + ci := byte[i++] + cx := byte[i++] + cy := byte[i++] - 2 + if ci == $FF + quit + case ci & $C0 + $00: + byte[dest + cx + cy * 40] := ci & $3F + if (ci & $3F) == $25 + door_x := cx + door_y := cy + $40: + len := byte[i++] + dir := byte[i++] + repeat + byte[dest + cx + cy * 40] := ci & $3F + case dir + 0: --cy + 1: --cy + ++cx + 2: ++cx + 3: ++cy + ++cx + 4: ++cy + 5: ++cy + --cx + 6: --cx + 7: --cy + --cx + while --len > 0 + $80: + len := byte[i++] - 1 'width + dir := byte[i++] - 1 'height + co := byte[i++] + repeat j from 0 to len + byte[dest + cx + j + cy * 40] := ci & $3F + byte[dest + cx + j + (cy + dir) * 40] := ci & $3F + repeat j from 1 to dir - 1 + byte[dest + cx + (cy + j) * 40] := ci & $3F + repeat k from 1 to len - 1 + byte[dest + cx + k + (cy + j) * 40] := co + byte[dest + cx + len + (cy + j) * 40] := ci & $3F + $C0: + len := byte[i++] - 1 'width + dir := byte[i++] - 1 'height + repeat j from 0 to len + byte[dest + cx + j + cy * 40] := ci & $3F + byte[dest + cx + j + (cy + dir) * 40] := ci & $3F + repeat j from 0 to dir + byte[dest + cx + (cy + j) * 40] := ci & $3F + byte[dest + cx + len + (cy + j) * 40] := ci & $3F + + DiamondsNeeded := byte[raw_cave + 9 + Level] + CaveTime := byte[raw_cave + 14 + Level] + MagicWallTime := byte[raw_cave + 1] + if MagicWallTime > CaveTime + AmoebaTime := CaveTime + else + AmoebaTime := CaveTime - MagicWallTime + DiamondValue := byte[raw_cave + 2] + ExtraValue := byte[raw_cave + 3] + DiamondCount := 0 + +pub Cover | n, cell + +'' Ramdomly cover the screen with a scrolling pattern + + n := 0 + repeat while n <> constant(40 * 22) + cell := ||long[random_ptr] // constant(40 * 22) + if byte[cave_addr + cell] <> $3C + byte[cave_addr + cell] := $3C + ++n + sn.cover_sound + waitcnt(clkfreq / 1000 + cnt) + +pub Uncover | n, cell + +'' Ramdomly uncover the screen + + n := 0 + repeat while n <> constant(40 * 22) + cell := ||long[random_ptr] // constant(40 * 22) + if byte[cave_addr + cell] == $3C + byte[cave_addr + cell] := temp_cave[cell] + ++n + sn.cover_sound + waitcnt(clkfreq / 1000 + cnt) + +dat + +reset byte $00, $01, $02, $03, $04, $05, $06, $07 + byte $08, $09, $0A, $0B, $08, $09, $0A, $0B + byte $10, $10, $12, $12, $14, $14, $16, $16 + byte $18, $19, $1A, $1B, $1C, $1D, $1E, $1F + byte $20, $21, $22, $23, $24, $25, $26, $27 + byte $28, $29, $2A, $2B, $2C, $2D, $2E, $2F + byte $30, $31, $32, $33, $30, $31, $32, $33 + byte $38, $38, $3A, $3B, $3C, $3D, $3E, $3F + +dirs long 1, 40, -1, -40 + +pub GameLoop | cx, cy, ca, cn, ob, o1, o2, ready, count, amoebas, enclosed + +'' Main game loop. Everything happens here. + + target := 0 + count := 0 'scans before rockford is born + ready := 0 + + NextLife := ((Score / 500) + 1) * 500 + MagicWallStatus := 0 'dormant + AmoebaStatus := 0 'growing slowly + + ' game loop + repeat + Alive := false + amoebas := 0 + enclosed := true + repeat cy from 1 to 21 + repeat cx from 0 to 39 + ca := cave_addr + cx + cy * 40 'address of current object + + 'large case statements execute rather slowly to the point + 'that the game becomes unplayable, so we have to split the + 'case into sections (too bad there is no indirect function + 'call in Spin) + + ob := byte[ca] + if ob < $10 + case ob + $04: 'out door + if target + byte[ca] := $05 + $08: 'firefly facing left + if CheckAround(ca) + ExplodeCenter(ca, $1B) + else + if byte[ca + 40] == $00 + byte[ca + 40] := $0F + byte[ca] := $00 + elseif byte[ca - 1] == $00 + byte[ca - 1] := $0C + byte[ca] := $00 + else + byte[ca] := $0D + $09: 'firefly facing up + if CheckAround(ca) + ExplodeCenter(ca, $1B) + else + if byte[ca - 1] == $00 + byte[ca - 1] := $0C + byte[ca] := $00 + elseif byte[ca - 40] == $00 + byte[ca - 40] := $0D + byte[ca] := $00 + else + byte[ca] := $0E + $0A: 'firefly facing right + if CheckAround(ca) + ExplodeCenter(ca, $1B) + else + if byte[ca - 40] == $00 + byte[ca - 40] := $0D + byte[ca] := $00 + elseif byte[ca + 1] == $00 + byte[ca + 1] := $0E + byte[ca] := $00 + else + byte[ca] := $0F + $0B: 'firefly facing down + if CheckAround(ca) + ExplodeCenter(ca, $1B) + else + if byte[ca + 1] == $00 + byte[ca + 1] := $0E + byte[ca] := $00 + elseif byte[ca + 40] == $00 + byte[ca + 40] := $0F + byte[ca] := $00 + else + byte[ca] := $0C + + elseif ob < $20 + case ob + $10: 'boulder + case byte[ca + 40] 'check object below + $00: + 'boulder can fall + byte[ca] := $00 + byte[ca + 40] := $13 'falling boulder, scanned + sn.boulder_sound + $02, $10, $14: 'wall, boulder or diamond + if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 + 'boulder can roll left + byte[ca] := $00 + byte[ca - 1] := $13 'falling boulder, scanned + sn.boulder_sound + elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 + 'boulder can roll right + byte[ca] := $00 + byte[ca + 1] := $13 'falling boulder, scanned + sn.boulder_sound + $12: 'falling boulder + case byte[ca + 40] 'check object below + $00: + 'boulder can continue falling + byte[ca] := $00 + byte[ca + 40] := $13 'falling boulder, scanned + $03: 'magic wall + byte[ca] := $00 + if MagicWallStatus < 2 'dormant or milling + if MagicWallStatus == 0 + MagicWallStatus := 1 + cn := st.get_time #> MagicWallTime + MagicWallTime := cn - MagicWallTime + sc.milling_on + sn.magic_wall_sound_on + if byte[ca + constant(40 * 2)] == $00 + byte[ca + constant(40 * 2)] := $17 'falling diamond, scanned + sn.diamond_sound + $02, $10, $14: 'wall, boulder or diamond + 'we hit something + sn.boulder_sound + if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 + 'boulder can roll left + byte[ca] := $00 + byte[ca - 1] := $13 'falling boulder, scanned + elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 + 'boulder can roll right + byte[ca] := $00 + byte[ca + 1] := $13 'falling boulder, scanned + else + 'boulder came to a stop + byte[ca] := $11 'stationary boulder, scanned + $38: 'rockford? + 'explode + ExplodeBelow(ca, $1B) + $08, $09, $0A, $0B: 'firefly? + ExplodeBelow(ca, $1B) + $30, $31, $32, $33: 'butterfly? + ExplodeBelow(ca, $20) + other: + 'boulder came to a stop + byte[ca] := $11 'stationary boulder, scanned + sn.boulder_sound + $14: 'diamond + case byte[ca + 40] 'check object below + $00: + 'diamond can fall + byte[ca] := $00 + byte[ca + 40] := $17 'falling diamond, scanned + sn.diamond_sound + $02, $10, $14: 'wall, boulder or diamond + if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 + 'diamond can roll left + byte[ca] := $00 + byte[ca - 1] := $17 'falling diamond, scanned + sn.diamond_sound + elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 + 'diamond can roll right + byte[ca] := $00 + byte[ca + 1] := $17 'falling diamond, scanned + sn.diamond_sound + $16: 'falling diamond + case byte[ca + 40] 'check object below + $00: + 'diamond can continue falling + byte[ca] := $00 + byte[ca + 40] := $17 'falling diamond, scanned + $03: 'magic wall + byte[ca] := $00 + if MagicWallStatus < 2 'dormant or milling + if MagicWallStatus == 0 + MagicWallStatus := 1 + cn := st.get_time #> MagicWallTime + MagicWallTime := cn - MagicWallTime + sc.milling_on + sn.magic_wall_sound_on + if byte[ca + constant(40 * 2)] == $00 + byte[ca + constant(40 * 2)] := $13 'falling boulder, scanned + sn.boulder_sound + $02, $10, $14: 'wall, boulder or diamond + 'we hit something + sn.diamond_sound + if byte[ca - 1] == $00 and byte[ca + constant(40 - 1)] == $00 + 'diamond can roll left + byte[ca] := $00 + byte[ca - 1] := $17 'falling diamond, scanned + elseif byte[ca + 1] == $00 and byte[ca + constant(40 + 1)] == $00 + 'diamond can roll right + byte[ca] := $00 + byte[ca + 1] := $17 'falling diamond, scanned + else + 'diamond came to a stop + byte[ca] := $15 'stationary diamond, scanned + $38: 'rockford? + 'explode + ExplodeBelow(ca, $1B) + $08, $09, $0A, $0B: 'firefly + ExplodeBelow(ca, $1B) + $30, $31, $32, $33: 'butterfly + ExplodeBelow(ca, $20) + other: + 'diamond came to a stop + byte[ca] := $15 'stationary diamond, scanned + sn.diamond_sound + $1B, $1C, $1D, $1E: 'explosion stages + byte[ca]++ + $1F: 'explosion to space, final stage + byte[ca] := $00 + + elseif ob < $30 + case ob + $20, $21, $22, $23: 'explosion stages + byte[ca]++ + $24: 'explosion to diamonds, final stage + byte[ca] := $15 + $25: 'inbox + Alive := true + if count++ == 20 + byte[ca] := $26 + sn.crack_sound + $26, $27: + Alive := true + byte[ca]++ + $28: + Alive := true + byte[ca] := $38 'rockford is born + sc.rockford_reset + st.set_time(CaveTime) + st.set_mode(st#STATUS_GAME) + ready := 1 + + elseif ob < $40 + case ob + $30: 'butterfly facing down + if CheckAround(ca) + ExplodeCenter(ca, $20) + else + if byte[ca - 1] == $00 + byte[ca - 1] := $35 + byte[ca] := $00 + elseif byte[ca + 40] == $00 + byte[ca + 40] := $34 + byte[ca] := $00 + else + byte[ca] := $37 + $31: 'butterfly facing left + if CheckAround(ca) + ExplodeCenter(ca, $20) + else + if byte[ca - 40] == $00 + byte[ca - 40] := $36 + byte[ca] := $00 + elseif byte[ca - 1] == $00 + byte[ca - 1] := $35 + byte[ca] := $00 + else + byte[ca] := $34 + $32: 'butterfly facing up + if CheckAround(ca) + ExplodeCenter(ca, $20) + else + if byte[ca + 1] == $00 + byte[ca + 1] := $37 + byte[ca] := $00 + elseif byte[ca - 40] == $00 + byte[ca - 40] := $36 + byte[ca] := $00 + else + byte[ca] := $35 + $33: 'butterfly facing right + if CheckAround(ca) + ExplodeCenter(ca, $20) + else + if byte[ca + 40] == $00 + byte[ca + 40] := $34 + byte[ca] := $00 + elseif byte[ca + 1] == $00 + byte[ca + 1] := $37 + byte[ca] := $00 + else + byte[ca] := $36 + + $38: 'rockford + Alive := true + nes := read_input + cn := 0 + if nes + if nes & GP_RIGHT + last_dir := 1 + sc.rockford_go(last_dir) + cn := ca + 1 + elseif nes & GP_LEFT + last_dir := -1 + sc.rockford_go(last_dir) + cn := ca - 1 + elseif nes & GP_UP + sc.rockford_go(last_dir) + cn := ca - 40 + elseif nes & GP_DOWN + sc.rockford_go(last_dir) + cn := ca + 40 + + if cn + if nes & GP_SELECT + o1 := $39 + o2 := $00 + else + o1 := $00 + o2 := $39 + case byte[cn] + $00, $01: 'empty or dirt + sn.moving_sound(byte[cn]) + byte[ca] := o1 + byte[cn] := o2 + $05: 'out door + sn.magic_wall_sound_off + sn.amoeba_sound_off + byte[ca] := o1 + byte[cn] := o2 + AddBonusPoints + waitcnt(clkfreq + cnt) '1 second delay + return true 'means cave succesfully completed + $10, $11: 'boulder, stationary + if (nes & GP_RIGHT) and (byte[cn + 1] == $00) and ((long[random_ptr] & $03) == 0) + 'boulder can be pushed + byte[cn + 1] := byte[cn] + byte[ca] := o1 + byte[cn] := o2 + sn.boulder_sound + elseif (nes & GP_LEFT) and (byte[cn - 1] == $00) and ((long[random_ptr] & $03) == 0) + 'boulder can be pushed + byte[cn - 1] := byte[cn] + byte[ca] := o1 + byte[cn] := o2 + sn.boulder_sound + $14, $15, $16, $17: 'diamond + byte[ca] := o1 + byte[cn] := o2 + sn.pick_sound + st.set_diamond_count(++DiamondCount) + IncrementScore(DiamondValue) + if DiamondCount == DiamondsNeeded and not target + 'flash screen when target is reached + sc.flash + sn.crack_sound + DiamondValue := ExtraValue + st.set_diamond_value(DiamondValue) + target := 1 + + else + sc.rockford_go(0) + + 'screen may need scrolling + if CaveNumber > 16 + 'do not scroll intermission caves + sx := 0 + sy := 0 + else + if cx - sx > constant(20 - 6) + sx += constant(10 - 5) + sx <#= constant(40 - 20) + elseif cx - sx < 5 + sx -= constant(10 - 5) + sx #>= 0 + if cy - sy > screen_height - 4 + sy += screen_height / 2 - 3 + sy <#= 22 - screen_height + elseif cy - sy < 3 + sy -= screen_height / 2 - 3 + sy #>= 0 + sc.scroll_to(sx * 8, sy * 16) + + $3A: 'amoeba + if ready + sn.amoeba_sound_on + if AmoebaStatus == 2 + 'turn into stone + byte[ca] := $10 'stationary boulder + elseif AmoebaStatus == 3 + 'turn into diamond + byte[ca] := $14 'stationary diamond + else + ++amoebas + if enclosed + enclosed := CheckEnclosed(ca) + cn := long[random_ptr] + if AmoebaStatus == 0 + cn &= $7F + else + cn &= $0F + if cn =< 3 + cn := ca + dirs[cn & $03] + ob := byte[cn] + if ob == $00 or ob == $01 + byte[cn] := $3A + + 'reset scanned flag + cn := ca - constant(40 + 1) + byte[cn] := reset.byte[byte[cn]] + + if MagicWallStatus == 1 + if st.get_time < MagicWallTime + MagicWallStatus := 2 'expired + sc.milling_off + sn.magic_wall_sound_off + + if AmoebaStatus == 0 + if st.get_time < AmoebaTime + AmoebaStatus := 1 'growing fast + if amoebas > 200 + AmoebaStatus := 2 'grew too big, turn into stones + elseif enclosed + AmoebaStatus := 3 'fully enclosed, turn into diamonds + if amoebas == 0 + sn.amoeba_sound_off + + if demo_ptr + nes := 0 + else + nes := read_input + if nes & GP_A + st.set_time(0) 'stop the time + sn.magic_wall_sound_off + sn.amoeba_sound_off + return false 'not completed, restart the same level + + elseif nes & GP_B + 'pause game + st.set_mode(st#STATUS_PAUSE) + repeat while nes & GP_B + nes := read_input + repeat while (nes & GP_B) == 0 + nes := read_input + if ready + st.set_mode(st#STATUS_GAME) + else + st.set_mode(st#STATUS_PRE) + repeat while nes & GP_B + nes := read_input + + elseif (nes & GP_SELECT) and (nes & GP_START) + st.set_time(0) + sn.magic_wall_sound_off + sn.amoeba_sound_off + return true '*cheat* go to the next level + + cn := st.get_time + if cn < 10 + sn.time_ending_sound(cn) + + if ready and (cn == 0) + 'out of time + sn.magic_wall_sound_off + sn.amoeba_sound_off + st.set_mode(st#STATUS_OUT_OF_TIME) + count := 60 * 60 'approx 1 minute + repeat while count > 0 + repeat while vsync == 0 + repeat while vsync <> 0 + --count + nes := read_input + if nes & GP_A + return false 'not completed, restart the same level + elseif (nes & GP_SELECT) and (nes & GP_START) + return true '*cheat* go to the next level + return false + + if Level < 2 + waitcnt(clkfreq / 50 + cnt) + +pub ExplodeBelow(cell, towhat) + if byte[cell - 1] <> $07 + byte[cell - 1] := towhat + 1 + if byte[cell] <> $07 + byte[cell] := towhat + 1 + if byte[cell + 1] <> $07 + byte[cell + 1] := towhat + if byte[cell + constant(40 - 1)] <> $07 + byte[cell + constant(40 - 1)] := towhat + if byte[cell + 40] <> $07 + byte[cell + 40] := towhat + if byte[cell + constant(40 + 1)] <> $07 + byte[cell + constant(40 + 1)] := towhat + if byte[cell + constant(40 * 2 - 1)] <> $07 + byte[cell + constant(40 * 2 - 1)] := towhat + if byte[cell + constant(40 * 2)] <> $07 + byte[cell + constant(40 * 2)] := towhat + if byte[cell + constant(40 * 2 + 1)] <> $07 + byte[cell + constant(40 * 2 + 1)] := towhat + sn.explosion_sound + +pub ExplodeCenter(cell, towhat) + if byte[cell - constant(40 + 1)] <> $07 + byte[cell - constant(40 + 1)] := towhat + 1 + if byte[cell - 40] <> $07 + byte[cell - 40] := towhat + 1 + if byte[cell - constant(40 - 1)] <> $07 + byte[cell - constant(40 - 1)] := towhat + 1 + if byte[cell - 1] <> $07 + byte[cell - 1] := towhat + 1 + if byte[cell] <> $07 + byte[cell] := towhat + 1 + if byte[cell + 1] <> $07 + byte[cell + 1] := towhat + if byte[cell + constant(40 - 1)] <> $07 + byte[cell + constant(40 - 1)] := towhat + if byte[cell + 40] <> $07 + byte[cell + 40] := towhat + if byte[cell + constant(40 + 1)] <> $07 + byte[cell + constant(40 + 1)] := towhat + sn.explosion_sound + +pub CheckAround(cell) | ob + ob := byte[cell - 40] + if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not + return true + ob := byte[cell - 1] + if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not + return true + ob := byte[cell + 1] + if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not + return true + ob := byte[cell + 40] + if ob => $38 and ob =< $3B 'rockford or ameba, scanned or not + return true + return false + +pub CheckEnclosed(cell) | ob, i + repeat i from 0 to 3 + ob := byte[cell + dirs[i]] + if ob == $00 or ob == $01 + return false + return true + +pub IncrementScore(amount) + Score += amount + st.set_score(Score) + if Score => NextLife and Men < 9 + ++Men + sc.new_life + NextLife += 500 + +pub AddBonusPoints | i, j + + i := j := st.get_time + repeat while i > 0 + st.set_time(--i) + IncrementScore(Level + 1) + if i < 10 + sn.time_ending_sound(i) + waitcnt(clkfreq / 32 + cnt) + else + sn.bonus_point_sound(j - i) + +dat + + long 0 'align + + ' screen array +screen byte $00[40*28] + +' color index 3 1 2 0 +palette long $06_6B_04_02 + +' -x- -y- +scroll long $0000_0000 + +status long 1 'set this to 1 to show the status line at the top + + ' status line + byte $90[20] + + ' foreground color for status line characters + byte $06[20] + + ' tiles +tiles word %%0_0_0_0_0_0_0_0 ' $00 space + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_1_0_0_1_0_1 ' $01 dirt + word %%1_1_0_0_1_0_0_1 + word %%0_1_2_1_0_1_2_0 + word %%1_1_0_1_1_1_0_1 + word %%1_0_1_1_1_0_1_1 + word %%0_2_1_0_1_2_1_0 + word %%2_1_1_2_2_0_1_1 + word %%1_0_1_1_1_1_2_0 + word %%0_1_1_1_2_1_1_1 + word %%1_2_0_1_1_1_2_0 + word %%1_2_1_0_2_1_0_1 + word %%0_2_1_1_0_1_2_1 + word %%1_0_1_0_1_0_1_0 + word %%1_1_0_0_1_1_0_1 + word %%1_0_1_2_0_1_0_0 + word %%0_1_0_0_1_0_1_0 + + word %%0_3_3_3_0_3_3_3 ' $02 brick wall + word %%0_2_3_3_0_2_3_3 + word %%0_2_2_2_0_2_2_2 + word %%0_0_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%2_2_0_2_2_2_0_2 + word %%0_0_0_0_0_0_0_0 + word %%0_3_3_3_0_3_3_3 + word %%0_2_3_3_0_2_3_3 + word %%0_2_2_2_0_2_2_2 + word %%0_0_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%2_2_0_2_2_2_0_2 + word %%0_0_0_0_0_0_0_0 + + word %%0_3_3_3_0_3_3_3 ' $03 magic wall + word %%0_2_3_3_0_2_2_2 + word %%0_2_2_2_0_2_2_2 + word %%0_0_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_3 + word %%2_2_0_2_2_2_0_2 + word %%0_0_0_0_0_0_0_0 + word %%0_3_3_3_0_3_3_3 + word %%0_2_3_3_0_2_3_3 + word %%0_2_2_2_0_2_2_2 + word %%0_0_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_3 + word %%3_3_0_2_3_3_0_2 + word %%2_2_0_2_2_2_0_2 + word %%0_0_0_0_0_0_0_0 + + word %%2_2_2_2_2_2_2_2 ' $04 out door (invisible) + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + + word %%0_0_0_0_0_0_0_0 ' $05 out door (flashing) + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $06 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%2_2_2_2_2_2_2_2 ' $07 steel wall + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + + word %%0_0_0_0_0_0_0_0 ' $08 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $09 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0A + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0B + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0C + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0D + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0E + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $0F + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_3_3_3_0_0_0 ' $10 boulder stationary + word %%0_3_2_3_1_3_0_0 + word %%3_1_3_2_3_3_3_0 + word %%2_3_1_2_1_3_3_3 + word %%2_2_2_1_2_3_3_3 + word %%2_1_2_2_2_1_2_3 + word %%2_2_1_1_2_2_3_3 + word %%2_2_2_2_2_1_2_3 + word %%2_0_2_2_2_2_2_1 + word %%2_2_0_2_2_1_2_1 + word %%2_0_2_2_2_2_2_2 + word %%2_2_0_2_2_2_2_2 + word %%2_2_2_0_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_0_1_2_0_0 + word %%0_0_0_2_2_0_0_0 + + word %%0_0_3_3_3_0_0_0 ' $11 boulder stationary, scanned this frame + word %%0_3_2_3_1_3_0_0 + word %%3_1_3_2_3_3_3_0 + word %%2_3_1_2_1_3_3_3 + word %%2_2_2_1_2_3_3_3 + word %%2_1_2_2_2_1_2_3 + word %%2_2_1_1_2_2_3_3 + word %%2_2_2_2_2_1_2_3 + word %%2_0_2_2_2_2_2_1 + word %%2_2_0_2_2_1_2_1 + word %%2_0_2_2_2_2_2_2 + word %%2_2_0_2_2_2_2_2 + word %%2_2_2_0_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_0_1_2_0_0 + word %%0_0_0_2_2_0_0_0 + + word %%0_0_3_3_3_0_0_0 ' $12 boulder falling + word %%0_3_2_3_1_3_0_0 + word %%3_1_3_2_3_3_3_0 + word %%2_3_1_2_1_3_3_3 + word %%2_2_2_1_2_3_3_3 + word %%2_1_2_2_2_1_2_3 + word %%2_2_1_1_2_2_3_3 + word %%2_2_2_2_2_1_2_3 + word %%2_0_2_2_2_2_2_1 + word %%2_2_0_2_2_1_2_1 + word %%2_0_2_2_2_2_2_2 + word %%2_2_0_2_2_2_2_2 + word %%2_2_2_0_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_0_1_2_0_0 + word %%0_0_0_2_2_0_0_0 + + word %%0_0_3_3_3_0_0_0 ' $13 boulder falling, scanned this frame + word %%0_3_2_3_1_3_0_0 + word %%3_1_3_2_3_3_3_0 + word %%2_3_1_2_1_3_3_3 + word %%2_2_2_1_2_3_3_3 + word %%2_1_2_2_2_1_2_3 + word %%2_2_1_1_2_2_3_3 + word %%2_2_2_2_2_1_2_3 + word %%2_0_2_2_2_2_2_1 + word %%2_2_0_2_2_1_2_1 + word %%2_0_2_2_2_2_2_2 + word %%2_2_0_2_2_2_2_2 + word %%2_2_2_0_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_0_1_2_0_0 + word %%0_0_0_2_2_0_0_0 + + word %%0_0_0_2_3_0_0_0 ' $14 diamond stationary + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_2_2_2_2_2_3_0 + word %%0_1_1_1_1_1_2_0 + word %%2_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%2_1_1_1_1_1_1_3 + word %%1_2_2_2_2_2_2_2 + word %%0_2_3_3_3_3_3_0 + word %%0_1_3_3_3_3_2_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 ' $15 diamond stationary, scanned + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_2_2_2_2_2_3_0 + word %%0_1_1_1_1_1_2_0 + word %%2_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%2_1_1_1_1_1_1_3 + word %%1_2_2_2_2_2_2_2 + word %%0_2_3_3_3_3_3_0 + word %%0_1_3_3_3_3_2_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 ' $16 diamond falling + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_2_2_2_2_2_3_0 + word %%0_1_1_1_1_1_2_0 + word %%2_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%2_1_1_1_1_1_1_3 + word %%1_2_2_2_2_2_2_2 + word %%0_2_3_3_3_3_3_0 + word %%0_1_3_3_3_3_2_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_2_3_0_0_0 ' $17 diamond falling, scanned + word %%0_0_0_1_2_0_0_0 + word %%0_0_2_3_3_3_0_0 + word %%0_0_1_3_3_2_0_0 + word %%0_2_2_2_2_2_3_0 + word %%0_1_1_1_1_1_2_0 + word %%2_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%2_1_1_1_1_1_1_3 + word %%1_2_2_2_2_2_2_2 + word %%0_2_3_3_3_3_3_0 + word %%0_1_3_3_3_3_2_0 + word %%0_0_2_1_1_3_0_0 + word %%0_0_1_1_1_2_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_1_1_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $18 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $19 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1A + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1B explode to space frame 1 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_3_0_0_0 + word %%0_0_0_3_0_0_3_0 + word %%0_0_0_0_3_0_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_0_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1C explode to space frame 2 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_0_3_0_1_0_0 + word %%0_3_1_0_0_0_3_0 + word %%0_1_0_0_1_3_1_0 + word %%0_3_0_1_0_0_1_0 + word %%0_0_0_0_1_3_0_0 + word %%0_3_1_0_1_0_0_0 + word %%0_1_0_1_0_1_0_0 + word %%0_0_3_1_1_0_3_0 + word %%0_0_3_0_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1D explode to space frame 3 + word %%0_0_0_0_0_0_0_0 + word %%0_3_0_0_3_0_3_0 + word %%0_0_0_3_0_2_0_0 + word %%0_3_0_1_0_1_3_0 + word %%0_1_2_0_0_0_1_0 + word %%0_2_0_0_2_1_2_0 + word %%3_1_0_2_0_0_2_0 + word %%0_0_0_0_1_1_0_0 + word %%3_1_2_0_1_0_3_0 + word %%0_2_0_2_0_1_0_0 + word %%0_0_1_2_1_0_1_0 + word %%3_0_1_0_1_0_3_0 + word %%0_0_0_3_3_0_0_0 + word %%0_3_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1E explode to space frame 4, same as frame 2 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_0_3_0_1_0_0 + word %%0_3_1_0_0_0_3_0 + word %%0_1_0_0_1_3_1_0 + word %%0_3_0_1_0_0_1_0 + word %%0_0_0_0_1_3_0_0 + word %%0_3_1_0_1_0_0_0 + word %%0_1_0_1_0_1_0_0 + word %%0_0_3_1_1_0_3_0 + word %%0_0_3_0_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $1F explode to space frame 5, same as frame 1 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_3_0_0_0 + word %%0_0_0_3_0_0_3_0 + word %%0_0_0_0_3_0_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_0_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $20 explode to diamond frame 1 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_3_0_0_0 + word %%0_0_0_3_0_0_3_0 + word %%0_0_0_0_3_0_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_0_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_3_0_0_0 ' $21 explode to diamond frame 2 + word %%3_0_3_0_0_0_3_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_3_0_3_0_3_0 + word %%0_3_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%3_0_0_0_0_0_0_3 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%3_0_0_0_0_0_3_0 + word %%0_0_0_0_0_0_0_0 + word %%0_3_0_0_3_0_0_3 + word %%0_0_0_3_0_0_0_0 + word %%3_0_0_0_0_0_3_0 + word %%0_0_3_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_1_1_0_0_0 ' $22 explode to diamond frame 3 + word %%0_3_0_3_0_0_0_0 + word %%0_0_1_0_0_1_0_3 + word %%0_0_3_0_2_3_0_0 + word %%0_0_0_2_0_0_1_0 + word %%0_0_0_0_0_0_3_0 + word %%1_0_2_0_0_2_0_1 + word %%3_0_0_0_0_0_0_3 + word %%1_0_0_0_0_0_0_2 + word %%3_0_2_0_0_0_0_3 + word %%0_0_0_0_0_2_2_0 + word %%0_3_0_2_0_0_3_0 + word %%0_0_1_0_1_2_0_0 + word %%0_0_3_0_0_0_0_3 + word %%0_3_0_1_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + + word %%0_0_0_1_1_0_0_0 ' $23 explode to diamond frame 4 + word %%0_0_0_3_3_0_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_3_0_2_3_0_0 + word %%0_1_0_2_0_0_1_0 + word %%0_3_0_0_3_0_3_0 + word %%1_0_2_3_1_2_0_1 + word %%3_1_0_2_2_0_2_3 + word %%1_0_0_3_0_1_1_2 + word %%3_0_2_0_2_0_0_3 + word %%0_1_1_0_0_3_2_0 + word %%0_3_0_2_2_0_3_0 + word %%0_0_1_3_0_2_0_0 + word %%0_0_3_0_1_3_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + + word %%0_0_0_1_1_0_0_0 ' $24 explode to diamond frame 5 + word %%0_0_0_3_3_0_0_0 + word %%0_0_1_2_1_1_0_0 + word %%0_0_3_2_2_3_0_0 + word %%0_1_1_3_3_2_1_0 + word %%0_3_2_3_2_2_3_0 + word %%1_2_3_1_1_3_3_1 + word %%3_3_2_3_3_2_1_3 + word %%1_2_2_3_2_3_1_2 + word %%3_2_3_1_3_1_1_3 + word %%0_1_2_3_1_3_2_0 + word %%0_3_2_1_2_1_3_0 + word %%0_0_1_3_3_2_0_0 + word %%0_0_3_2_1_3_0_0 + word %%0_0_0_1_2_0_0_0 + word %%0_0_0_3_3_0_0_0 + + word %%2_2_2_2_2_2_2_2 ' $25 inbox, flashing + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_0_0_0_0_0_0_2 + word %%2_2_2_2_2_2_2_2 + + word %%0_0_0_0_0_0_0_0 ' $26 inbox morphing into rockford, same as explode to space frame 1 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_3_0_0_0 + word %%0_0_0_3_0_0_3_0 + word %%0_0_0_0_3_0_0_0 + word %%0_0_3_0_0_0_0_0 + word %%0_3_0_0_0_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $27 inbox morphing into rockford, same as explode to space frame 2 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_3_0_0 + word %%0_0_0_3_0_1_0_0 + word %%0_3_1_0_0_0_3_0 + word %%0_1_0_0_1_3_1_0 + word %%0_3_0_1_0_0_1_0 + word %%0_0_0_0_1_3_0_0 + word %%0_3_1_0_1_0_0_0 + word %%0_1_0_1_0_1_0_0 + word %%0_0_3_1_1_0_3_0 + word %%0_0_3_0_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $28 inbox morphing into rockford, same as explode to space frame 3 + word %%0_0_0_0_0_0_0_0 + word %%0_3_0_0_3_0_3_0 + word %%0_0_0_3_0_2_0_0 + word %%0_3_0_1_0_1_3_0 + word %%0_1_2_0_0_0_1_0 + word %%0_2_0_0_2_1_2_0 + word %%3_1_0_2_0_0_2_0 + word %%0_0_0_0_1_1_0_0 + word %%3_1_2_0_1_0_3_0 + word %%0_2_0_2_0_1_0_0 + word %%0_0_1_2_1_0_1_0 + word %%3_0_1_0_1_0_3_0 + word %%0_0_0_3_3_0_0_0 + word %%0_3_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $29 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2A + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2B + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2C + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2D + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2E + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $2F + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $30 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $31 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $32 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $33 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $34 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $35 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $36 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $37 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $38 rockford + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_0_2_0 + word %%0_2_0_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_3_3_0_2_0 + word %%0_0_3_2_2_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_1_3_3_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_0_1_0_0_1_0_0 + word %%0_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $39 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $3A + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $3B + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%2_2_2_2_2_2_2_2 ' $3C + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_0_0_2_2_0_0_2 + word %%2_2_0_2_2_2_0_2 + word %%2_3_0_2_2_3_0_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_2_2_2_2_2_2 + + word %%0_0_0_0_0_0_0_0 ' $3D + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $3E + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $3F + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + +' chargen + + word %%0_0_0_0_0_0_0_0 ' $80 '0' + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $81 '1' + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $82 '2' + word %%0_3_3_3_3_3_0_0 + word %%3_3_0_0_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_0_0_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $83 + word %%0_3_3_3_3_3_3_0 + word %%0_0_0_0_3_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $84 + word %%3_3_0_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_3_0_3_3_3_0_0 + word %%3_3_3_3_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_0_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $85 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%0_0_0_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $86 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $87 + word %%3_3_3_3_3_3_3_0 + word %%3_0_0_0_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $88 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $89 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%0_3_3_3_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8A ':' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8B ';' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8C '/' + word %%0_0_0_0_0_0_3_0 + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_3_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_0_0_0_0 + word %%0_3_3_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8D + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8E + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $8F + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $90 space + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $91 'A' + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $92 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $93 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $94 + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_0_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_3_3_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $95 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $96 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $97 + word %%0_3_3_3_3_3_3_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_3_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $98 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $99 + word %%0_3_3_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_3_3_0_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $9A + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%0_3_3_3_3_3_3_0 + word %%0_0_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $9B + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_3_3_0_0 + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_0_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $9C + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $9D + word %%3_3_0_0_0_3_3_0 + word %%3_3_3_0_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_0_3_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $9E + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_3_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $9F + word %%0_3_3_3_3_3_0_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A1 + word %%0_0_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_3_3_0_0 + word %%0_3_3_3_3_3_3_0 + word %%0_0_3_3_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A2 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A3 + word %%0_3_3_3_3_3_0_0 + word %%3_3_3_0_0_0_0_0 + word %%0_3_3_3_3_3_0_0 + word %%0_0_0_0_0_3_3_0 + word %%0_0_0_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A4 + word %%3_3_3_3_3_3_3_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A5 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A6 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%0_3_3_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $A7 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_3_0_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_0_3_3_3_0 + word %%3_3_0_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A8 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%0_0_3_3_3_3_0_0 + word %%0_0_3_3_3_3_0_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + word %%3_3_3_0_0_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $A9 + word %%3_3_0_0_0_3_3_0 + word %%3_3_0_0_0_3_3_0 + word %%0_3_3_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_0_3_3_3_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AA + word %%3_3_3_3_3_3_3_0 + word %%0_0_0_3_3_3_0_0 + word %%0_0_3_3_3_0_0_0 + word %%0_3_3_3_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_0 + + word %%0_0_0_0_0_0_0_0 ' $AB '(' + word %%0_0_0_0_3_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_0_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AC diamond + word %%0_0_0_3_0_0_0_0 + word %%0_0_3_0_3_0_0_0 + word %%0_3_3_3_3_3_0_0 + word %%3_0_0_0_0_0_3_0 + word %%0_3_3_3_3_3_0_0 + word %%0_0_3_0_3_0_0_0 + word %%0_0_0_3_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AD ')' + word %%0_0_3_3_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AE + word %%0_0_3_0_0_3_0_0 + word %%0_0_3_3_3_3_0_0 + word %%0_3_0_3_3_0_3_0 + word %%0_3_0_3_3_0_3_0 + word %%0_0_3_3_3_3_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_3_3_0_0 + + word %%0_0_0_0_0_0_0_0 ' $AF ',' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_0_3_3_0_0_0 + word %%0_0_3_3_0_0_0_0 + + word %%1_3_2_2_1_3_2_2 ' $B0 scrolling bgnd of the title screen + word %%1_2_2_2_1_2_2_2 + word %%0_1_2_2_0_1_2_2 + word %%2_2_2_2_2_2_2_2 + word %%2_2_1_3_2_2_1_3 + word %%2_2_1_2_2_2_1_2 + word %%2_2_0_1_2_2_0_1 + word %%2_2_2_2_2_2_2_2 + + word %%3_3_3_3_3_3_3_3 ' $B1 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + + word %%1_2_3_3_3_3_3_3 ' $B2 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + word %%1_2_3_3_3_3_3_3 + + word %%3_3_3_3_0_0_0_0 ' $B3 + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + + word %%3_3_3_3_3_3_3_3 ' $B4 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_0_0_0 + + word %%3_3_3_3_0_0_0_0 ' $B5 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + + word %%0_0_0_0_3_3_3_3 ' $B6 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + + word %%0_0_0_0_0_0_0_0 ' $B7 + word %%3_0_0_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + + word %%3_3_3_3_0_0_0_0 ' $B8 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_0_0_0_0_0_0_0 + + word %%1_2_3_3_0_0_0_0 ' $B9 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + + word %%0_0_0_0_1_2_3_3 ' $BA + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + + word %%0_0_0_0_1_2_3_3 ' $BB + word %%0_0_0_0_1_2_2_2 + word %%0_0_0_0_1_2_2_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_3 + + word %%3_3_3_3_3_3_3_3 ' $BC + word %%2_3_2_3_3_3_2_3 + word %%2_3_2_2_3_2_2_3 + word %%3_3_2_2_2_2_2_3 + word %%3_3_2_3_2_3_2_3 + word %%3_3_2_3_3_3_2_3 + word %%3_3_2_3_3_3_2_3 + word %%3_3_3_3_3_3_3_3 + + word %%3_3_3_3_0_0_0_0 ' $BD + word %%3_3_3_3_3_0_0_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + + word %%3_3_3_3_3_3_3_3 ' $BE + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_3 + word %%3_3_3_3_3_3_3_0 + word %%3_3_3_3_3_3_0_0 + word %%3_3_3_3_3_0_0_0 + + word %%3_3_3_3_0_0_0_0 ' $BF + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + + word %%0_0_0_0_3_3_3_3 ' $C0 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + word %%0_0_0_0_3_3_3_3 + + word %%0_0_0_0_0_0_0_0 ' $C1 + word %%3_0_0_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + + word %%3_3_3_3_0_0_0_0 ' $C2 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_3_0_0_0_0 + word %%3_3_3_0_0_0_0_0 + word %%3_3_0_0_0_0_0_0 + word %%3_0_0_0_0_0_0_0 + + word %%1_2_3_3_0_0_0_0 ' $C3 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + word %%1_2_3_3_0_0_0_0 + + word %%0_0_0_0_1_2_3_3 ' $C4 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + word %%0_0_0_0_1_2_3_3 + + word %%0_0_0_0_1_2_3_3 ' $C5 + word %%0_0_0_0_1_2_2_2 + word %%0_0_0_0_1_2_2_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_2 + word %%0_0_0_0_1_2_3_3 + + word %%0_0_0_0_0_0_0_0 ' $C6 unused... padding for second chargen (see below) + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $C7 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $C8 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $C9 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CA + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CB + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CC + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CD + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CE + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $CF + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + +' this is basically the same character generator, but using +' a different color (I need this for the title screen). Either +' this, or separate color attributes for each cell of the +' screen. We have still some space here, so... + + word %%0_0_0_0_0_0_0_0 ' $D0 '0' + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D1 '1' + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $D2 '2' + word %%0_2_2_2_2_2_0_0 + word %%2_2_0_0_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_0_0_0_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $D3 + word %%0_2_2_2_2_2_2_0 + word %%0_0_0_0_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D4 + word %%2_2_0_0_0_0_0_0 + word %%2_2_0_0_0_0_0_0 + word %%2_2_0_2_2_2_0_0 + word %%2_2_2_2_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_0_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D5 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_0_0 + word %%0_0_0_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D6 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D7 + word %%2_2_2_2_2_2_2_0 + word %%2_0_0_0_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D8 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $D9 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DA ':' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DB ';' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DC '/' + word %%0_0_0_0_0_0_2_0 + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_0_0_0_0 + word %%0_2_2_0_0_0_0_0 + word %%2_2_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DD + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DE + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $DF + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E0 space + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E1 'A' + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $E2 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E3 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E4 + word %%2_2_2_2_2_0_0_0 + word %%2_2_2_0_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_2_2_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_2_2_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E5 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $E6 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $E7 + word %%0_2_2_2_2_2_2_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_2_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $E8 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $E9 + word %%0_2_2_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_2_2_0_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $EA + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $EB + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_2_2_0_0 + word %%2_2_2_2_2_0_0_0 + word %%2_2_2_2_2_0_0_0 + word %%2_2_2_0_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $EC + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $ED + word %%2_2_0_0_0_2_2_0 + word %%2_2_2_0_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_0_2_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $EE + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_2_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $EF + word %%0_2_2_2_2_2_0_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F1 + word %%0_0_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_2_2_0_0 + word %%0_2_2_2_2_2_2_0 + word %%0_0_2_2_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F2 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F3 + word %%0_2_2_2_2_2_0_0 + word %%2_2_2_0_0_0_0_0 + word %%0_2_2_2_2_2_0_0 + word %%0_0_0_0_0_2_2_0 + word %%0_0_0_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F4 + word %%2_2_2_2_2_2_2_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F5 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F6 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%0_2_2_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $F7 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_2_0_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_0_2_2_2_0 + word %%2_2_0_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F8 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + word %%2_2_2_0_0_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $F9 + word %%2_2_0_0_0_2_2_0 + word %%2_2_0_0_0_2_2_0 + word %%0_2_2_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_0_2_2_2_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FA + word %%2_2_2_2_2_2_2_0 + word %%0_0_0_2_2_2_0_0 + word %%0_0_2_2_2_0_0_0 + word %%0_2_2_2_0_0_0_0 + word %%2_2_2_0_0_0_0_0 + word %%2_2_2_2_2_2_2_0 + word %%2_2_2_2_2_2_2_0 + + word %%0_0_0_0_0_0_0_0 ' $FB '(' + word %%0_0_0_0_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_0_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FC diamond + word %%0_0_0_2_0_0_0_0 + word %%0_0_2_0_2_0_0_0 + word %%0_2_2_2_2_2_0_0 + word %%2_0_0_0_0_0_2_0 + word %%0_2_2_2_2_2_0_0 + word %%0_0_2_0_2_0_0_0 + word %%0_0_0_2_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FD ')' + word %%0_0_2_2_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_0_0_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FE + word %%0_0_2_0_0_2_0_0 + word %%0_0_2_2_2_2_0_0 + word %%0_2_0_2_2_0_2_0 + word %%0_2_0_2_2_0_2_0 + word %%0_0_2_2_2_2_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_2_2_0_0 + + word %%0_0_0_0_0_0_0_0 ' $FF ',' + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_0_0_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_0_2_2_0_0_0 + word %%0_0_2_2_0_0_0_0 + \ No newline at end of file diff --git a/source/boulder/musik/BONUS.SFX b/source/boulder/musik/BONUS.SFX new file mode 100644 index 0000000..97f538e Binary files /dev/null and b/source/boulder/musik/BONUS.SFX differ diff --git a/source/boulder/musik/BONUS.SPN b/source/boulder/musik/BONUS.SPN new file mode 100644 index 0000000..ada8775 --- /dev/null +++ b/source/boulder/musik/BONUS.SPN @@ -0,0 +1 @@ +bonus ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $03,$03,$FF,$0F,$02,$00,$05,$00,$FF,$01,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/source/boulder/musik/CRACK.SFX b/source/boulder/musik/CRACK.SFX new file mode 100644 index 0000000..f3de3e2 Binary files /dev/null and b/source/boulder/musik/CRACK.SFX differ diff --git a/source/boulder/musik/CRACK.SPN b/source/boulder/musik/CRACK.SPN new file mode 100644 index 0000000..424e89e --- /dev/null +++ b/source/boulder/musik/CRACK.SPN @@ -0,0 +1 @@ +crack ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $01,$22,$01,$0F,$11,$00,$05,$00,$55,$01,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/source/boulder/musik/ERROR.SFX b/source/boulder/musik/ERROR.SFX new file mode 100644 index 0000000..c671bc0 Binary files /dev/null and b/source/boulder/musik/ERROR.SFX differ diff --git a/source/boulder/musik/ERROR.SPN b/source/boulder/musik/ERROR.SPN new file mode 100644 index 0000000..131169e --- /dev/null +++ b/source/boulder/musik/ERROR.SPN @@ -0,0 +1 @@ +error ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $04,$01,$80,$0F,$00,$00,$00,$00,$FF,$00,$00,$80 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/source/boulder/musik/EXP.SFX b/source/boulder/musik/EXP.SFX new file mode 100644 index 0000000..feb669b Binary files /dev/null and b/source/boulder/musik/EXP.SFX differ diff --git a/source/boulder/musik/EXP.SPN b/source/boulder/musik/EXP.SPN new file mode 100644 index 0000000..bd1258f --- /dev/null +++ b/source/boulder/musik/EXP.SPN @@ -0,0 +1 @@ +exp ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $06,$04,$10,$0F,$00,$00,$00,$00,$FF,$01,$50,$11 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/source/boulder/musik/WALL.SFX b/source/boulder/musik/WALL.SFX new file mode 100644 index 0000000..dec7ab7 Binary files /dev/null and b/source/boulder/musik/WALL.SFX differ diff --git a/source/boulder/musik/WALL.SPN b/source/boulder/musik/WALL.SPN new file mode 100644 index 0000000..8465ad0 --- /dev/null +++ b/source/boulder/musik/WALL.SPN @@ -0,0 +1 @@ +wall ' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel byte $04,$FF,$FF,$0F,$01,$00,$01,$00,$FF,$06,$20,$00 byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 \ No newline at end of file diff --git a/source/boulder/musik/bd.wav b/source/boulder/musik/bd.wav new file mode 100644 index 0000000..35f20a5 Binary files /dev/null and b/source/boulder/musik/bd.wav differ diff --git a/source/boulder/regnatix/bd.spin b/source/boulder/regnatix/bd.spin new file mode 100644 index 0000000..6f1e232 --- /dev/null +++ b/source/boulder/regnatix/bd.spin @@ -0,0 +1,304 @@ +{{ --------------------------------------------------------------------------------------------------------- + +Hive-Computer-Projekt: Boulder Dash - Hive-Version + + http://hive-project.de + +Basierend auf dem Fanprojekt diverser Propellerk?pfe: + + http://forums.parallax.com/forums/default.aspx?f=33&m=263404 + +Besonderer Dank an Pex "Mahoney" Tufvesson f?r die coole Musik!: + + http://mahoney.c64.org + http://www.livet.se/visa + + +Tasten: + +ESC Stop Button A +Space Pause Button B +LShift Start +LCTRL Select +Cursor + +Anpassungen f?r den Hive + +09-01-2010 - Entfernung der Hardwareerkennung + - Anpassung Konfiguration an Hive/Bellatrix + - Gamecontr. entfernt + - Auskommentierung Sound +12-01-2010 - Soundadapter optimiert + - Scrolltext im Titelbildschirm eingef?gt +19-04-2010 - Anpassung an TriOS: Boulder l?uft jetzt auch aus dem Verzeichnis. Bedingt durch das + neue, etwas tr?gere WAV-Soundsystem, habe ich einige Effekte durch HSS/SFX ersetzt. + +Zur Hive-Version: Das Game an sich - also der urspr?ngliche Basiscode aus dem Parallax-Forum - l?uft +auf einem einzigen Propellerchip! Was war zu tun um diese Version an den Hive anzupassen: + +1. Der Code kann im wesentlichen fast ausschlie?lich auf Bellatrix laufen. Daf?r m?ssen die entsprechenden +Belegungen der IO-Pins f?r Video und Keyboard angepasst werden. +2. Da Bellatrix keinen Sound ausgeben kann, sondern diese Aufgabe im Hive Administra ?bernimmt, mu? die +Soundausgabe angepasst werden. Im Originalcode ?bernimmt das Objekt "sound.spin" diese Aufgabe - welches +wieder den SIDemu in einer getrennten Cog startet. Hier zeigt sich die St?rke der SPIN-Objekte: F?r die +Anpassung brauchte ich einfach nur ein neues Objekt gleicher Struktur definieren, ohne das Hauptprogramm +zu ?ndern. Dieses neue Soundobjekt startet ebenfalls eine Cog, welche einzig die Aufgabe hat die Kommunikation +zu Regnatix/Administra zu realisieren. +3. Regnatix-Code: Tja, die K?nigin kann bei der ganzen Sache D?umchen drehen, denn sie hat nur folgend Aufgaben +in einer einzigen Cog zu bew?ltigen: + - Bellatrix-Code laden + - SFX-Slots in Administra initialisieren + - Warten bis Bellatrix einen Ton von sich geben m?chte und ?bermittlung dieser + Tonesequenz an Administra + +Damit werden nat?rlich auf der einen Seite massig Ressourcen in Bellatrix gegen?ber dem urspr?nglichen Code frei +und es sind durch die Verwendung von HSS/SFX + Waveplayer + SDCard mehr M?glichkeiten gegeben. + +Bellatrix-Code : 20,5 KByte +Regnatix-Code : 3,2 KByte + +Bei diesen Werten ist zu beachten, dass der Regnatix das blanke IOS mit 2,6 KByte eingebunden hat - ohne Optimierung, +denn ein Gro?teil der IOS-Routinen sind in diesem Fall ungenutzt. + +Zeitaufwand : ca. 3 nette Abende ;) + +drohne235 + + --------------------------------------------------------------------------------------------------------- }} + + +OBJ + ios : "reg-ios" +' debugx : "pterm" 'debug + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +CON + +_music_on = 1 +_music_off = 2 +_moving_sound1 = 3 +_moving_sound2 = 4 +_boulder_sound = 5 +_diamond_sound = 6 +_pick_sound = 7 +_explosion_sound = 8 +_crack_sound = 9 +_magic_wall_sound_on = 10 +_magic_wall_sound_off = 11 +_amoeba_sound_on = 12 +_amoeba_sound_off = 13 +_time_ending_sound = 14 +_bonus_point_sound = 15 +_cover_sound = 16 + +VAR + +byte parastr[64] +byte fl_musicon + +PUB main | a,b,c,i,n,stradr + +'initialisierung + ios.start 'ios initialisieren +' ios.startram 'code f?r test im ram, sollte bei bin-datei auskommentiert werden + +' debugx.start(115200) + + ios.admsetsyssnd(0) 'systemsounds abschalten + ios.sddmact(ios#DM_USER) 'wieder in userverzeichnis wechseln + ios.print(string("Boulder Dash - Loading...")) + +'bellatrix-code laden + ios.parastart + parastr[0] := 0 + ios.paranext(@parastr) + + case parastr[0] + "n": + ios.belload(@beln) 'grafiktreiber ntsc laden + other: + ios.belload(@belp) 'grafiktreiber pal laden + + ios.sddmact(ios#DM_USER) '??? + +'sfx-slots setzen + ios.sfx_setslot(@fx_moving_sound1, 0) + ios.sfx_setslot(@fx_moving_sound2, 1) + ios.sfx_setslot(@fx_boulder_sound,2) + ios.sfx_setslot(@fx_diamond_sound,3) + ios.sfx_setslot(@fx_pick_sound,4) + ios.sfx_setslot(@fx_amoeba_sound,5) + ios.sfx_setslot(@fx_time_sound,6) + ios.sfx_setslot(@fx_cover_sound,7) + ios.sfx_setslot(@fx_bonus,8) + ios.sfx_setslot(@fx_crack,9) + ios.sfx_setslot(@fx_explosion,10) + ios.sfx_setslot(@fx_wall,11) + + +'soundadapter + repeat + case ios.bus_getchar2 + + _music_on: 'titelmusik + ios.admsetsound(ios#SND_HSSOFF) 'hss ausschalten + ios.admsetsound(ios#SND_WAVON) 'wav einschalten + n := ios.wav_play(@wav1) + fl_musicon := 1 + + _music_off: + if fl_musicon + ios.wav_stop + ios.admsetsound(ios#SND_WAVOFF) 'wav ausschalten + ios.admsetsound(ios#SND_HSSON) 'hss anschalten + fl_musicon := 0 + + _moving_sound1: + ios.sfx_fire(0,1) + + _moving_sound2: + ios.sfx_fire(1,1) + + _boulder_sound: + ios.sfx_fire(2,1) + waitcnt(clkfreq / 30 + cnt) + + _diamond_sound: + b? + b := b & $FF + byte[@fx_diamond_sound+2] := b + ios.sfx_setslot(@fx_diamond_sound,3) + ios.sfx_fire(3,1) + waitcnt(clkfreq / 30 + cnt) + + _pick_sound: + ios.sfx_fire(4,2) + waitcnt(clkfreq / 3 + cnt) + + _explosion_sound: 'explosion + ios.sfx_fire(10,1) + waitcnt(clkfreq * 3 + cnt) + + _crack_sound: 'eingang + ios.sfx_fire(9,1) + waitcnt(clkfreq / 3 + cnt) + + _magic_wall_sound_on: + ios.sfx_fire(11,2) + + _magic_wall_sound_off: + + _amoeba_sound_on: + ios.sfx_fire(5,2) + + _amoeba_sound_off: + + _time_ending_sound: + ios.sfx_fire(6,2) + + _bonus_point_sound: 'bonus + ios.sfx_fire(8,2) + waitcnt(clkfreq * 4 + cnt) + + _cover_sound: + b? + b := b & $FF + byte[@fx_cover_sound+2] := b + ios.sfx_setslot(@fx_cover_sound,7) + ios.sfx_fire(7,1) + waitcnt(clkfreq / 30 + cnt) + + + +DAT + +wav1 byte "bd.wav",0 ' titelmusik + +beln byte "bd_ntsc.bel",0 ' bella-code, ntsc-version +belp byte "bd_pal.bel",0 + + 'basisschwingung modulation h?llkurve + 'Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +fx_moving_sound1 byte $06, $02, $01, $08, $00, $00, $00, $00, $FF, $00, $00, $D0 +fx_moving_sound2 byte $06, $02, $01, $0F, $00, $00, $00, $00, $FF, $00, $00, $D0 +fx_boulder_sound byte $06, $01, $FF, $0F, $01, $03, $01, $00, $FF, $00, $00, $80 +fx_diamond_sound byte $01, $01, $E0, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 +fx_pick_sound byte $01, $01, $E0, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 +fx_explosion_sound byte $01, $01, $E0, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 +fx_crack_sound byte $06, $02, $10, $0F, $00, $00, $00, $00, $FF, $00, $00, $D0 +fx_magic_sound byte $01, $01, $80, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 +fx_amoeba_sound byte $01, $01, $80, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 +fx_time_sound byte $02, $05, $FF, $0F, $10, $00, $01, $00, $FF, $00, $00, $40 +fx_bonus_sound byte $01, $01, $80, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 +fx_cover_sound byte $01, $01, $80, $0F, $00, $00, $00, $00, $FF, $00, $00, $80 + +fx_bonus +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $03,$03,$FF,$0F,$02,$00,$05,$00,$FF,$01,$50,$11 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + +fx_crack +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $01,$22,$01,$0F,$11,$00,$05,$00,$55,$01,$50,$11 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + +fx_explosion +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $06,$04,$10,$0F,$00,$00,$00,$00,$FF,$01,$50,$11 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + +fx_wall +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $04,$FF,$FF,$0F,$01,$00,$01,$00,$FF,$06,$20,$00 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + + +DAT +{ + +sfx-struktur: + +wav len freq vol grundschwingung +lfo lfw fma ama modulation +att dec sus rel h?llkurve +seq (optional) + +wav wellenform + 0 sinus (0..500hz) + 1 schneller sinus (0..1khz) + 2 dreieck (0..500hz) + 3 rechteck (0..1khz) + 4 schnelles rechteck (0..4khz) + 5 impulse (0..1,333hz) + 6 rauschen +len tonl?nge $0..$fe, $ff endlos +freq frequenz $00..$ff +vol lautst?rke $00..$0f + +lfo low frequency oscillator $ff..$01 +lfw low frequency waveform + $00 sinus (0..8hz) + $01 fast sine (0..16hz) + $02 ramp up (0..8hz) + $03 ramp down (0..8hz) + $04 square (0..32hz) + $05 random + $ff sequencer data +fma frequency modulation amount + $00 no modulation + $01..$ff +ama amplitude modulation amount + $00 no modulation + $01..$ff +att attack $00..$ff +dec decay $00..$ff +sus sustain $00..$ff +rel release $00..$ff + + + +} diff --git a/source/boulder/regnatix/pterm.spin b/source/boulder/regnatix/pterm.spin new file mode 100644 index 0000000..aab7911 --- /dev/null +++ b/source/boulder/regnatix/pterm.spin @@ -0,0 +1,528 @@ +{{ +───────────────────────────────────────────────── +File: Parallax Serial Terminal.spin +Version: 1.0 +Copyright (c) 2009 Parallax, Inc. +See end of file for terms of use. + +Authors: Jeff Martin, Andy Lindsay, Chip Gracey +───────────────────────────────────────────────── +}} + +{ +HISTORY: + This object is made for direct use with the Parallax Serial Terminal; a simple serial communication program + available with the Propeller Tool installer and also separately via the Parallax website (www.parallax.com). + + This object is heavily based on FullDuplexSerialPlus (by Andy Lindsay), which is itself heavily based on + FullDuplexSerial (by Chip Gracey). + +USAGE: + • Call Start, or StartRxTx, first. + • Be sure to set the Parallax Serial Terminal software to the baudrate specified in Start, and the proper COM port. + • At 80 MHz, this object properly receives/transmits at up to 250 Kbaud, or performs transmit-only at up to 1 Mbaud. + +} + +CON +'' +'' Parallax Serial Terminal +'' Control Character Constants +''───────────────────────────────────── + CS = 16 ''CS: Clear Screen + CE = 11 ''CE: Clear to End of line + CB = 12 ''CB: Clear lines Below + + HM = 1 ''HM: HoMe cursor + PC = 2 ''PC: Position Cursor in x,y + PX = 14 ''PX: Position cursor in X + PY = 15 ''PY: Position cursor in Y + + NL = 13 ''NL: New Line + LF = 10 ''LF: Line Feed + ML = 3 ''ML: Move cursor Left + MR = 4 ''MR: Move cursor Right + MU = 5 ''MU: Move cursor Up + MD = 6 ''MD: Move cursor Down + TB = 9 ''TB: TaB + BS = 8 ''BS: BackSpace + + BP = 7 ''BP: BeeP speaker + +CON + + BUFFER_LENGTH = 64 'Recommended as 64 or higher, but can be 2, 4, 8, 16, 32, 64, 128 or 256. + BUFFER_MASK = BUFFER_LENGTH - 1 + MAXSTR_LENGTH = 49 'Maximum length of received numerical string (not including zero terminator). + +VAR + + long cog 'Cog flag/id + + long rx_head '9 contiguous longs (must keep order) + long rx_tail + long tx_head + long tx_tail + long rx_pin + long tx_pin + long rxtx_mode + long bit_ticks + long buffer_ptr + + byte rx_buffer[BUFFER_LENGTH] 'Receive and transmit buffers + byte tx_buffer[BUFFER_LENGTH] + + byte str_buffer[MAXSTR_LENGTH+1] 'String buffer for numerical strings + +PUB Start(baudrate) : okay +{{Start communication with the Parallax Serial Terminal using the Propeller's programming connection. +Waits 1 second for connection, then clears screen. + Parameters: + baudrate - bits per second. Make sure it matches the Parallax Serial Terminal's + Baud Rate field. + Returns : True (non-zero) if cog started, or False (0) if no cog is available.}} + + okay := StartRxTx(31, 30, 0, baudrate) + waitcnt(clkfreq + cnt) 'Wait 1 second for PST + Clear 'Clear display + +PUB StartRxTx(rxpin, txpin, mode, baudrate) : okay +{{Start serial communication with designated pins, mode, and baud. + Parameters: + rxpin - input pin; receives signals from external device's TX pin. + txpin - output pin; sends signals to external device's RX pin. + mode - signaling mode (4-bit pattern). + bit 0 - inverts rx. + bit 1 - inverts tx. + bit 2 - open drain/source tx. + bit 3 - ignore tx echo on rx. + baudrate - bits per second. + Returns : True (non-zero) if cog started, or False (0) if no cog is available.}} + + stop + longfill(@rx_head, 0, 4) + longmove(@rx_pin, @rxpin, 3) + bit_ticks := clkfreq / baudrate + buffer_ptr := @rx_buffer + okay := cog := cognew(@entry, @rx_head) + 1 + +PUB Stop +{{Stop serial communication; frees a cog.}} + + if cog + cogstop(cog~ - 1) + longfill(@rx_head, 0, 9) + +PUB Char(bytechr) +{{Send single-byte character. Waits for room in transmit buffer if necessary. + Parameter: + bytechr - character (ASCII byte value) to send.}} + + repeat until (tx_tail <> ((tx_head + 1) & BUFFER_MASK)) + tx_buffer[tx_head] := bytechr + tx_head := (tx_head + 1) & BUFFER_MASK + + if rxtx_mode & %1000 + CharIn + +PUB Chars(bytechr, count) +{{Send multiple copies of a single-byte character. Waits for room in transmit buffer if necessary. + Parameters: + bytechr - character (ASCII byte value) to send. + count - number of bytechrs to send.}} + + repeat count + Char(bytechr) + +PUB CharIn : bytechr +{{Receive single-byte character. Waits until character received. + Returns: $00..$FF}} + + repeat while (bytechr := RxCheck) < 0 + +PUB Str(stringptr) +{{Send zero terminated string. + Parameter: + stringptr - pointer to zero terminated string to send.}} + + repeat strsize(stringptr) + Char(byte[stringptr++]) + +PUB StrIn(stringptr) +{{Receive a string (carriage return terminated) and stores it (zero terminated) starting at stringptr. +Waits until full string received. + Parameter: + stringptr - pointer to memory in which to store received string characters. + Memory reserved must be large enough for all string characters plus a zero terminator.}} + + StrInMax(stringptr, -1) + +PUB StrInMax(stringptr, maxcount) +{{Receive a string of characters (either carriage return terminated or maxcount in length) and stores it (zero terminated) +starting at stringptr. Waits until either full string received or maxcount characters received. + Parameters: + stringptr - pointer to memory in which to store received string characters. + Memory reserved must be large enough for all string characters plus a zero terminator (maxcount + 1). + maxcount - maximum length of string to receive, or -1 for unlimited.}} + + repeat while (maxcount--) 'While maxcount not reached + if (byte[stringptr++] := CharIn) == NL 'Get chars until NL + quit + byte[stringptr+(byte[stringptr-1] == NL)]~ 'Zero terminate string; overwrite NL or append 0 char + +PUB Dec(value) | i, x +{{Send value as decimal characters. + Parameter: + value - byte, word, or long value to send as decimal characters.}} + + x := value == NEGX 'Check for max negative + if value < 0 + value := ||(value+x) 'If negative, make positive; adjust for max negative + Char("-") 'and output sign + + i := 1_000_000_000 'Initialize divisor + + repeat 10 'Loop for 10 digits + if value => i + Char(value / i + "0" + x*(i == 1)) 'If non-zero digit, output digit; adjust for max negative + value //= i 'and digit from value + result~~ 'flag non-zero found + elseif result or i == 1 + Char("0") 'If zero digit (or only digit) output it + i /= 10 'Update divisor + +PUB DecIn : value +{{Receive carriage return terminated string of characters representing a decimal value. + Returns: the corresponding decimal value.}} + + StrInMax(@str_buffer, MAXSTR_LENGTH) + value := StrToBase(@str_buffer, 10) + +PUB Bin(value, digits) +{{Send value as binary characters up to digits in length. + Parameters: + value - byte, word, or long value to send as binary characters. + digits - number of binary digits to send. Will be zero padded if necessary.}} + + value <<= 32 - digits + repeat digits + Char((value <-= 1) & 1 + "0") + +PUB BinIn : value +{{Receive carriage return terminated string of characters representing a binary value. + Returns: the corresponding binary value.}} + + StrInMax(@str_buffer, MAXSTR_LENGTH) + value := StrToBase(@str_buffer, 2) + +PUB Hex(value, digits) +{{Send value as hexadecimal characters up to digits in length. + Parameters: + value - byte, word, or long value to send as hexadecimal characters. + digits - number of hexadecimal digits to send. Will be zero padded if necessary.}} + + value <<= (8 - digits) << 2 + repeat digits + Char(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) + +PUB HexIn : value +{{Receive carriage return terminated string of characters representing a hexadecimal value. + Returns: the corresponding hexadecimal value.}} + + StrInMax(@str_buffer, MAXSTR_LENGTH) + value := StrToBase(@str_buffer, 16) + +PUB Clear +{{Clear screen and place cursor at top-left.}} + + Char(CS) + +PUB ClearEnd +{{Clear line from cursor to end of line.}} + + Char(CE) + +PUB ClearBelow +{{Clear all lines below cursor.}} + + Char(CB) + +PUB Home +{{Send cursor to home position (top-left).}} + + Char(HM) + +PUB Position(x, y) +{{Position cursor at column x, row y (from top-left).}} + + Char(PC) + Char(x) + Char(y) + +PUB PositionX(x) +{{Position cursor at column x of current row.}} + Char(PX) + Char(x) + +PUB PositionY(y) +{{Position cursor at row y of current column.}} + Char(PY) + Char(y) + +PUB NewLine +{{Send cursor to new line (carriage return plus line feed).}} + + Char(NL) + +PUB LineFeed +{{Send cursor down to next line.}} + + Char(LF) + +PUB MoveLeft(x) +{{Move cursor left x characters.}} + + repeat x + Char(ML) + +PUB MoveRight(x) +{{Move cursor right x characters.}} + + repeat x + Char(MR) + +PUB MoveUp(y) +{{Move cursor up y lines.}} + + repeat y + Char(MU) + +PUB MoveDown(y) +{{Move cursor down y lines.}} + + repeat y + Char(MD) + +PUB Tab +{{Send cursor to next tab position.}} + + Char(TB) + +PUB Backspace +{{Delete one character to left of cursor and move cursor there.}} + + Char(BS) + +PUB Beep +{{Play bell tone on PC speaker.}} + + Char(BP) + +PUB RxCount : count +{{Get count of characters in receive buffer. + Returns: number of characters waiting in receive buffer.}} + + count := rx_head - rx_tail + count -= BUFFER_LENGTH*(count < 0) + +PUB RxFlush +{{Flush receive buffer.}} + + repeat while rxcheck => 0 + +PRI RxCheck : bytechr +{Check if character received; return immediately. + Returns: -1 if no byte received, $00..$FF if character received.} + + bytechr~~ + if rx_tail <> rx_head + bytechr := rx_buffer[rx_tail] + rx_tail := (rx_tail + 1) & BUFFER_MASK + +PRI StrToBase(stringptr, base) : value | chr, index +{Converts a zero terminated string representation of a number to a value in the designated base. +Ignores all non-digit characters (except negative (-) when base is decimal (10)).} + + value := index := 0 + repeat until ((chr := byte[stringptr][index++]) == 0) + chr := -15 + --chr & %11011111 + 39*(chr > 56) 'Make "0"-"9","A"-"F","a"-"f" be 0 - 15, others out of range + if (chr > -1) and (chr < base) 'Accumulate valid values into result; ignore others + value := value * base + chr + if (base == 10) and (byte[stringptr] == "-") 'If decimal, address negative sign; ignore otherwise + value := - value + +DAT + +'*********************************** +'* Assembly language serial driver * +'*********************************** + + org +' +' +' Entry +' +entry mov t1,par 'get structure address + add t1,#4 << 2 'skip past heads and tails + + rdlong t2,t1 'get rx_pin + mov rxmask,#1 + shl rxmask,t2 + + add t1,#4 'get tx_pin + rdlong t2,t1 + mov txmask,#1 + shl txmask,t2 + + add t1,#4 'get rxtx_mode + rdlong rxtxmode,t1 + + add t1,#4 'get bit_ticks + rdlong bitticks,t1 + + add t1,#4 'get buffer_ptr + rdlong rxbuff,t1 + mov txbuff,rxbuff + add txbuff,#BUFFER_LENGTH + + test rxtxmode,#%100 wz 'init tx pin according to mode + test rxtxmode,#%010 wc + if_z_ne_c or outa,txmask + if_z or dira,txmask + + mov txcode,#transmit 'initialize ping-pong multitasking +' +' +' Receive +' +receive jmpret rxcode,txcode 'run chunk of tx code, then return + + test rxtxmode,#%001 wz 'wait for start bit on rx pin + test rxmask,ina wc + if_z_eq_c jmp #receive + + mov rxbits,#9 'ready to receive byte + mov rxcnt,bitticks + shr rxcnt,#1 + add rxcnt,cnt + +:bit add rxcnt,bitticks 'ready next bit period + +:wait jmpret rxcode,txcode 'run chunk of tx code, then return + + mov t1,rxcnt 'check if bit receive period done + sub t1,cnt + cmps t1,#0 wc + if_nc jmp #:wait + + test rxmask,ina wc 'receive bit on rx pin + rcr rxdata,#1 + djnz rxbits,#:bit + + shr rxdata,#32-9 'justify and trim received byte + and rxdata,#$FF + test rxtxmode,#%001 wz 'if rx inverted, invert byte + if_nz xor rxdata,#$FF + + rdlong t2,par 'save received byte and inc head + add t2,rxbuff + wrbyte rxdata,t2 + sub t2,rxbuff + add t2,#1 + and t2,#BUFFER_MASK + wrlong t2,par + + jmp #receive 'byte done, receive next byte +' +' +' Transmit +' +transmit jmpret txcode,rxcode 'run chunk of rx code, then return + + mov t1,par 'check for head <> tail + add t1,#2 << 2 + rdlong t2,t1 + add t1,#1 << 2 + rdlong t3,t1 + cmp t2,t3 wz + if_z jmp #transmit + + add t3,txbuff 'get byte and inc tail + rdbyte txdata,t3 + sub t3,txbuff + add t3,#1 + and t3,#BUFFER_MASK + wrlong t3,t1 + + or txdata,#$100 'ready byte to transmit + shl txdata,#2 + or txdata,#1 + mov txbits,#11 + mov txcnt,cnt + +:bit test rxtxmode,#%100 wz 'output bit on tx pin + test rxtxmode,#%010 wc 'according to mode + if_z_and_c xor txdata,#1 + shr txdata,#1 wc + if_z muxc outa,txmask + if_nz muxnc dira,txmask + add txcnt,bitticks 'ready next cnt + +:wait jmpret txcode,rxcode 'run chunk of rx code, then return + + mov t1,txcnt 'check if bit transmit period done + sub t1,cnt + cmps t1,#0 wc + if_nc jmp #:wait + + djnz txbits,#:bit 'another bit to transmit? + + jmp #transmit 'byte done, transmit next byte +' +' +' Uninitialized data +' +t1 res 1 +t2 res 1 +t3 res 1 + +rxtxmode res 1 +bitticks res 1 + +rxmask res 1 +rxbuff res 1 +rxdata res 1 +rxbits res 1 +rxcnt res 1 +rxcode res 1 + +txmask res 1 +txbuff res 1 +txdata res 1 +txbits res 1 +txcnt res 1 +txcode res 1 + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this │ +│software and associated documentation files (the "Software"), to deal in the Software │ +│without restriction, including without limitation the rights to use, copy, modify, │ +│merge, publish, distribute, sublicense, and/or sell copies of the Software, and to │ +│permit persons to whom the Software is furnished to do so, subject to the following │ +│conditions: │ │ +│ │ │ +│The above copyright notice and this permission notice shall be included in all copies │ +│or substantial portions of the Software. │ +│ │ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, │ +│INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A │ +│PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT │ +│HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION │ +│OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │ +│SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/source/shoot/bellatrix/Graphics.spin b/source/shoot/bellatrix/Graphics.spin new file mode 100644 index 0000000..58b394b --- /dev/null +++ b/source/shoot/bellatrix/Graphics.spin @@ -0,0 +1,1669 @@ +''*************************************** +''* Graphics Driver v1.0 * +''* Author: Chip Gracey * +''* Copyright (c) 2005 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +'' +'' Theory of Operation: +'' +'' A cog is launched which processes commands via the PUB routines. +'' +'' Points, lines, arcs, sprites, text, and polygons are rasterized into +'' a specified stretch of memory which serves as a generic bitmap buffer. +'' +'' The bitmap can be displayed by the TV.SRC or VGA.SRC driver. +'' +'' See GRAPHICS_DEMO.SRC for usage example. +'' + +CON + + #1, _setup, _color, _width, _plot, _line, _arc, _vec, _vecarc, _pix, _pixarc, _text, _textarc, _textmode, _fill, _loop + +VAR + + long cog + + long command + + long bitmap_base 'bitmap data + long bitmap_longs + word bases[32] + + long pixel_width 'pixel data + long slices[8] + + long text_xs, text_ys, text_sp, text_just 'text data (these 4 must be contiguous) + + +PUB start : okay + +'' Start graphics driver - starts a cog +'' returns false if no cog available + + fontptr := @font 'set font pointer (same for all instances) + + stop + okay := cog := cognew(@loop, @command) + 1 + + +PUB stop + +'' Stop graphics driver - frees a cog + + if cog + cogstop(cog~ - 1) + + command~ + + +PUB setup(x_tiles, y_tiles, x_origin, y_origin, base_ptr) | bases_ptr, slices_ptr + +'' Set bitmap parameters +'' +'' x_tiles - number of x tiles (tiles are 16x16 pixels each) +'' y_tiles - number of y tiles +'' x_origin - relative-x center pixel +'' y_origin - relative-y center pixel +'' base_ptr - base address of bitmap + + setcommand(_loop, 0) 'make sure last command finished + + repeat bases_ptr from 0 to x_tiles - 1 <# 31 'write bases + bases[bases_ptr] := base_ptr + bases_ptr * y_tiles << 6 + + y_tiles <<= 4 'adjust arguments and do setup command + y_origin := y_tiles - y_origin - 1 + bases_ptr := @bases + slices_ptr := @slices + setcommand(_setup, @x_tiles) + + bitmap_base := base_ptr 'retain high-level bitmap data + bitmap_longs := x_tiles * y_tiles + + +PUB clear + +'' Clear bitmap + + setcommand(_loop, 0) 'make sure last command finished + + longfill(bitmap_base, 0, bitmap_longs) 'clear bitmap + + +PUB copy(dest_ptr) + +'' Copy bitmap +'' use for double-buffered display (flicker-free) +'' +'' dest_ptr - base address of destination bitmap + + setcommand(_loop, 0) 'make sure last command finished + + longmove(dest_ptr, bitmap_base, bitmap_longs) 'copy bitmap + + +PUB color(c) + +'' Set pixel color to two-bit pattern +'' +'' c - color code in bits[1..0] + + setcommand(_color, @colors[c & 3]) 'set color + + +PUB width(w) | pixel_passes, r, i, p + +'' Set pixel width +'' actual width is w[3..0] + 1 +'' +'' w - 0..15 for round pixels, 16..31 for square pixels + + r := not w & $10 'determine pixel shape/width + w &= $F + pixel_width := w + pixel_passes := w >> 1 + 1 + + setcommand(_width, @w) 'do width command now to avoid updating slices when busy + + p := w ^ $F 'update slices to new shape/width + repeat i from 0 to w >> 1 + slices[i] := true >> (p << 1) << (p & $E) + if r and pixels[w] & |< i + p += 2 + if r and i == pixel_passes - 2 + p += 2 + + +PUB colorwidth(c, w) + +'' Set pixel color and width + + color(c) + width(w) + + +PUB plot(x, y) + +'' Plot point +'' +'' x,y - point + + setcommand(_plot, @x) + + +PUB line(x, y) + +'' Draw a line to point +'' +'' x,y - endpoint + + setcommand(_line, @x) + + +PUB arc(x, y, xr, yr, angle, anglestep, steps, arcmode) + +'' Draw an arc +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - initial angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' anglestep - angle step in bits[12..0] +'' steps - number of steps (0 just leaves (x,y) at initial arc position) +'' arcmode - 0: plot point(s) +'' 1: line to point(s) +'' 2: line between points +'' 3: line from point(s) to center + + setcommand(_arc, @x) + + +PUB vec(x, y, vecscale, vecangle, vecdef_ptr) + +'' Draw a vector sprite +'' +'' x,y - center of vector sprite +'' vecscale - scale of vector sprite ($100 = 1x) +'' vecangle - rotation angle of vector sprite in bits[12..0] +'' vecdef_ptr - address of vector sprite definition +'' +'' +'' Vector sprite definition: +'' +'' word $8000|$4000+angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) +'' word length 'vector length +'' ... 'more vectors +'' ... +'' word 0 'end of definition + + setcommand(_vec, @x) + + +PUB vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) + +'' Draw a vector sprite at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' vecscale - scale of vector sprite ($100 = 1x) +'' vecangle - rotation angle of vector sprite in bits[12..0] +'' vecdef_ptr - address of vector sprite definition + + setcommand(_vecarc, @x) + + +PUB pix(x, y, pixrot, pixdef_ptr) + +'' Draw a pixel sprite +'' +'' x,y - center of vector sprite +'' pixrot - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror +'' pixdef_ptr - address of pixel sprite definition +'' +'' +'' Pixel sprite definition: +'' +'' word 'word align, express dimensions and center, define pixels +'' byte xwords, ywords, xorigin, yorigin +'' word %%xxxxxxxx,%%xxxxxxxx +'' word %%xxxxxxxx,%%xxxxxxxx +'' word %%xxxxxxxx,%%xxxxxxxx +'' ... + + setcommand(_pix, @x) + + +PUB pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) + +'' Draw a pixel sprite at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' pixrot - 0: 0°, 1: 90°, 2: 180°, 3: 270°, +4: mirror +'' pixdef_ptr - address of pixel sprite definition + + setcommand(_pixarc, @x) + + +PUB text(x, y, string_ptr) | justx, justy + +'' Draw text +'' +'' x,y - text position (see textmode for sizing and justification) +'' string_ptr - address of zero-terminated string (it may be necessary to call .finish +'' immediately afterwards to prevent subsequent code from clobbering the +'' string as it is being drawn + + justify(string_ptr, @justx) 'justify string and draw text + setcommand(_text, @x) + + +PUB textarc(x, y, xr, yr, angle, string_ptr) | justx, justy + +'' Draw text at an arc position +'' +'' x,y - center of arc +'' xr,yr - radii of arc +'' angle - angle in bits[12..0] (0..$1FFF = 0°..359.956°) +'' string_ptr - address of zero-terminated string (it may be necessary to call .finish +'' immediately afterwards to prevent subsequent code from clobbering the +'' string as it is being drawn + + justify(string_ptr, @justx) 'justify string and draw text + setcommand(_textarc, @x) + + +PUB textmode(x_scale, y_scale, spacing, justification) + +'' Set text size and justification +'' +'' x_scale - x character scale, should be 1+ +'' y_scale - y character scale, should be 1+ +'' spacing - character spacing, 6 is normal +'' justification - bits[1..0]: 0..3 = left, center, right, left +'' bits[3..2]: 0..3 = bottom, center, top, bottom + + longmove(@text_xs, @x_scale, 4) 'retain high-level text data + + setcommand(_textmode, @x_scale) 'set text mode + + +PUB box(x, y, box_width, box_height) | x2, y2, pmin, pmax + +'' Draw a box with round/square corners, according to pixel width +'' +'' x,y - box left, box bottom + + if box_width > pixel_width and box_height > pixel_width + + pmax := pixel_width - (pmin := pixel_width >> 1) 'get pixel-half-min and pixel-half-max + + x += pmin 'adjust coordinates to accomodate width + y += pmin + x2 := x + box_width - 1 - pixel_width + y2 := y + box_height - 1 - pixel_width + + plot(x, y) 'plot round/square corners + plot(x, y2) + plot(x2, y) + plot(x2, y2) + + fill(x, y2 + pmax, 0, (x2 - x) << 16, 0, 0, pmax) 'fill gaps + fill(x, y, 0, (x2 - x) << 16, 0, 0, pmin) + fill(x - pmin, y2, 0, (x2 - x + pixel_width) << 16, 0, 0, y2 - y) + + +PUB quad(x1, y1, x2, y2, x3, y3, x4, y4) + +'' Draw a solid quadrilateral +'' vertices must be ordered clockwise or counter-clockwise + + tri(x1, y1, x2, y2, x3, y3) 'draw two triangle to make 4-sides polygon + tri(x3, y3, x4, y4, x1, y1) + + +PUB tri(x1, y1, x2, y2, x3, y3) | xy[2] + +'' Draw a solid triangle + +' reorder vertices by descending y + + case (y1 => y2) & %100 | (y2 => y3) & %010 | (y1 => y3) & %001 + %000: + longmove(@xy, @x1, 2) + longmove(@x1, @x3, 2) + longmove(@x3, @xy, 2) + %010: + longmove(@xy, @x1, 2) + longmove(@x1, @x2, 4) + longmove(@x3, @xy, 2) + %011: + longmove(@xy, @x1, 2) + longmove(@x1, @x2, 2) + longmove(@x2, @xy, 2) + %100: + longmove(@xy, @x3, 2) + longmove(@x2, @x1, 4) + longmove(@x1, @xy, 2) + %101: + longmove(@xy, @x2, 2) + longmove(@x2, @x3, 2) + longmove(@x3, @xy, 2) + +' draw triangle + + fill(x1, y1, (x3 - x1) << 16 / (y1 - y3 + 1), (x2 - x1) << 16 / (y1 - y2 + 1), (x3 - x2) << 16 / (y2 - y3 + 1), y1 - y2, y1 - y3) + + +PUB finish + +'' Wait for any current graphics command to finish +'' use this to insure that it is safe to manually manipulate the bitmap + + setcommand(_loop, 0) 'make sure last command finished + + +PRI fill(x, y, da, db, db2, linechange, lines_minus_1) + + setcommand(_fill, @x) + + +PRI justify(string_ptr, justptr) | x + + x := (strsize(string_ptr) - 1) * text_xs * text_sp + text_xs * 5 - 1 + long[justptr] := -lookupz(text_just >> 2 & 3: 0, x >> 1, x, 0) + long[justptr][1] := -lookupz(text_just & 3: 0, text_ys << 3, text_ys << 4, 0) + + +PRI setcommand(cmd, argptr) + + command := cmd << 16 + argptr 'write command and pointer + repeat while command 'wait for command to be cleared, signifying receipt + + +CON + + ' Vector font primitives + + xa0 = %000 << 0 'x line start / arc center + xa1 = %001 << 0 + xa2 = %010 << 0 + xa3 = %011 << 0 + xa4 = %100 << 0 + xa5 = %101 << 0 + xa6 = %110 << 0 + xa7 = %111 << 0 + + ya0 = %0000 << 3 'y line start / arc center + ya1 = %0001 << 3 + ya2 = %0010 << 3 + ya3 = %0011 << 3 + ya4 = %0100 << 3 + ya5 = %0101 << 3 + ya6 = %0110 << 3 + ya7 = %0111 << 3 + ya8 = %1000 << 3 + ya9 = %1001 << 3 + yaA = %1010 << 3 + yaB = %1011 << 3 + yaC = %1100 << 3 + yaD = %1101 << 3 + yaE = %1110 << 3 + yaF = %1111 << 3 + + xb0 = %000 << 7 'x line end + xb1 = %001 << 7 + xb2 = %010 << 7 + xb3 = %011 << 7 + xb4 = %100 << 7 + xb5 = %101 << 7 + xb6 = %110 << 7 + xb7 = %111 << 7 + + yb0 = %0000 << 10 'y line end + yb1 = %0001 << 10 + yb2 = %0010 << 10 + yb3 = %0011 << 10 + yb4 = %0100 << 10 + yb5 = %0101 << 10 + yb6 = %0110 << 10 + yb7 = %0111 << 10 + yb8 = %1000 << 10 + yb9 = %1001 << 10 + ybA = %1010 << 10 + ybB = %1011 << 10 + ybC = %1100 << 10 + ybD = %1101 << 10 + ybE = %1110 << 10 + ybF = %1111 << 10 + + ax1 = %0 << 7 'x arc radius + ax2 = %1 << 7 + + ay1 = %00 << 8 'y arc radius + ay2 = %01 << 8 + ay3 = %10 << 8 + ay4 = %11 << 8 + + a0 = %0000 << 10 'arc start/length + a1 = %0001 << 10 'bits[1..0] = start (0..3 = 0°, 90°, 180°, 270°) + a2 = %0010 << 10 'bits[3..2] = length (0..3 = 360°, 270°, 180°, 90°) + a3 = %0011 << 10 + a4 = %0100 << 10 + a5 = %0101 << 10 + a6 = %0110 << 10 + a7 = %0111 << 10 + a8 = %1000 << 10 + a9 = %1001 << 10 + aA = %1010 << 10 + aB = %1011 << 10 + aC = %1100 << 10 + aD = %1101 << 10 + aE = %1110 << 10 + aF = %1111 << 10 + + fline = %0 << 14 'line command + farc = %1 << 14 'arc command + + more = %1 << 15 'another arc/line + + +DAT + +' Color codes + +colors long %%0000000000000000 + long %%1111111111111111 + long %%2222222222222222 + long %%3333333333333333 + +' Round pixel recipes + +pixels byte %00000000,%00000000,%00000000,%00000000 '0,1,2,3 + byte %00000000,%00000000,%00000010,%00000101 '4,5,6,7 + byte %00001010,%00001010,%00011010,%00011010 '8,9,A,B + byte %00110100,%00111010,%01110100,%01110100 'C,D,E,F + +' Vector font - standard ascii characters ($21-$7E) + +font word fline + xa2 + yaC + xb2 + yb7 + more '! + word fline + xa2 + ya5 + xb2 + yb4 + + word fline + xa1 + yaD + xb1 + ybC + more '" + word fline + xa3 + yaD + xb3 + ybC + + word fline + xa1 + yaA + xb1 + yb6 + more '# + word fline + xa3 + yaA + xb3 + yb6 + more + word fline + xa0 + ya9 + xb4 + yb9 + more + word fline + xa0 + ya7 + xb4 + yb7 + + word farc + xa2 + ya9 + a9 + ax2 + ay1 + more '$ + word farc + xa2 + ya7 + aB + ax2 + ay1 + more + word fline + xa0 + ya6 + xb2 + yb6 + more + word fline + xa2 + yaA + xb4 + ybA + more + word fline + xa2 + yaA + xb2 + ybB + more + word fline + xa2 + ya6 + xb2 + yb5 + + word farc + xa1 + yaA + a0 + ax1 + ay1 + more '% + word farc + xa3 + ya6 + a0 + ax1 + ay1 + more + word fline + xa0 + ya6 + xb4 + ybA + + word farc + xa2 + yaA + a7 + ax1 + ay1 + more '& + word farc + xa2 + ya7 + a5 + ax2 + ay2 + more + word fline + xa1 + yaA + xb4 + yb5 + + word fline + xa2 + yaD + xb2 + ybC ' ' + + word farc + xa3 + ya9 + aD + ax1 + ay4 + more '( + word farc + xa3 + ya7 + aE + ax1 + ay4 + more + word fline + xa2 + ya7 + xb2 + yb9 + + word farc + xa1 + ya9 + aC + ax1 + ay4 + more ') + word farc + xa1 + ya7 + aF + ax1 + ay4 + more + word fline + xa2 + ya7 + xb2 + yb9 + + word fline + xa4 + ya6 + xb0 + ybA + more '* + word fline + xa0 + ya6 + xb4 + ybA + more + word fline + xa2 + yaB + xb2 + yb5 + + word fline + xa0 + ya8 + xb4 + yb8 + more '+ + word fline + xa2 + yaA + xb2 + yb6 + + word fline + xa2 + ya4 + xb1 + yb3 ', + + word fline + xa0 + ya8 + xb4 + yb8 '- + + word fline + xa2 + ya5 + xb2 + yb4 '. + + word fline + xa0 + ya4 + xb4 + ybC '/ + + word farc + xa2 + ya8 + a0 + ax2 + ay4 '0 + + word fline + xa0 + ya4 + xb4 + yb4 + more '1 + word fline + xa2 + ya4 + xb2 + ybC + more + word fline + xa0 + yaA + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more '2 + word farc + xa2 + yaA + aF + ax2 + ay3 + more + word farc + xa2 + ya4 + aD + ax2 + ay3 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa2 + yaA + a7 + ax2 + ay2 + more '3 + word farc + xa2 + ya6 + a6 + ax2 + ay2 + + word fline + xa2 + yaC + xb0 + yb7 + more '4 + word fline + xa0 + ya7 + xb4 + yb7 + more + word fline + xa3 + ya4 + xb3 + yb8 + + word farc + xa2 + ya6 + aB + ax2 + ay2 + more '5 + word fline + xa4 + yaC + xb0 + ybC + more + word fline + xa0 + yaC + xb0 + yb8 + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + ya4 + xb2 + yb4 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more '6 + word farc + xa2 + ya8 + aD + ax2 + ay4 + more + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa2 + yaC + xb3 + ybC + + word fline + xa0 + yaC + xb4 + ybC + more '7 + word fline + xa1 + ya4 + xb4 + ybC + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more '8 + word farc + xa2 + yaA + a0 + ax2 + ay2 + + word farc + xa2 + yaA + a0 + ax2 + ay2 + more '9 + word farc + xa2 + ya8 + aF + ax2 + ay4 + more + word fline + xa4 + ya8 + xb4 + ybA + more + word fline + xa1 + ya4 + xb2 + yb4 + + word fline + xa2 + ya6 + xb2 + yb7 + more ': + word fline + xa2 + yaA + xb2 + yb9 + + word fline + xa2 + ya4 + xb1 + yb3 + more '; + word fline + xa2 + ya8 + xb2 + yb7 + + word fline + xa0 + ya8 + xb4 + ybA + more '< + word fline + xa0 + ya8 + xb4 + yb6 + + word fline + xa0 + yaA + xb4 + ybA + more '= + word fline + xa0 + ya6 + xb4 + yb6 + + word fline + xa4 + ya8 + xb0 + ybA + more '> + word fline + xa4 + ya8 + xb0 + yb6 + + word farc + xa2 + yaB + a8 + ax2 + ay1 + more '? + word farc + xa3 + yaB + aF + ax1 + ay2 + more + word farc + xa3 + ya7 + aD + ax1 + ay2 + more + word fline + xa2 + ya5 + xb2 + yb4 + + word farc + xa2 + ya8 + a0 + ax1 + ay1 + more '@ + word farc + xa2 + ya8 + a4 + ax2 + ay3 + more + word farc + xa3 + ya8 + aF + ax1 + ay1 + more + word farc + xa2 + ya6 + aF + ax2 + ay1 + more + word fline + xa3 + ya7 + xb3 + yb9 + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'A + word fline + xa0 + ya4 + xb0 + ybA + more + word fline + xa4 + ya4 + xb4 + ybA + more + word fline + xa0 + ya8 + xb4 + yb8 + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'B + word farc + xa2 + ya6 + aB + ax2 + ay2 + more + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'C + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + + word farc + xa2 + yaA + aC + ax2 + ay2 + more 'D + word farc + xa2 + ya6 + aF + ax2 + ay2 + more + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa4 + ya6 + xb4 + ybA + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa0 + yaC + xb2 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'E + word fline + xa0 + ya4 + xb4 + yb4 + more + word fline + xa0 + ya8 + xb3 + yb8 + more + word fline + xa0 + yaC + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'F + word fline + xa0 + ya8 + xb3 + yb8 + more + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'G + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya4 + xb4 + yb7 + more + word fline + xa3 + ya7 + xb4 + yb7 + + word fline + xa0 + ya4 + xb0 + ybC + more 'H + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa0 + ya8 + xb4 + yb8 + + word fline + xa2 + ya4 + xb2 + ybC + more 'I + word fline + xa0 + ya4 + xb4 + yb4 + more + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'J + word fline + xa4 + ya6 + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'K + word fline + xa4 + yaC + xb0 + yb8 + more + word fline + xa4 + ya4 + xb0 + yb8 + + word fline + xa0 + ya4 + xb0 + ybC + more 'L + word fline + xa0 + ya4 + xb4 + yb4 + + word fline + xa0 + ya4 + xb0 + ybC + more 'M + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa2 + ya8 + xb0 + ybC + more + word fline + xa2 + ya8 + xb4 + ybC + + word fline + xa0 + ya4 + xb0 + ybC + more 'N + word fline + xa4 + ya4 + xb4 + ybC + more + word fline + xa4 + ya4 + xb0 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more '0 + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya6 + xb4 + ybA + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'P + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + + word farc + xa2 + yaA + a8 + ax2 + ay2 + more 'Q + word farc + xa2 + ya6 + aA + ax2 + ay2 + more + word fline + xa0 + ya6 + xb0 + ybA + more + word fline + xa4 + ya6 + xb4 + ybA + more + word fline + xa2 + ya6 + xb4 + yb3 + + word farc + xa2 + yaA + aB + ax2 + ay2 + more 'R + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa0 + ya8 + xb2 + yb8 + more + word fline + xa0 + yaC + xb2 + ybC + more + word fline + xa4 + ya4 + xb2 + yb8 + + word farc + xa2 + yaA + a4 + ax2 + ay2 + more 'S + word farc + xa2 + ya6 + a6 + ax2 + ay2 + + word fline + xa2 + ya4 + xb2 + ybC + more 'T + word fline + xa0 + yaC + xb4 + ybC + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'U + word fline + xa0 + ya6 + xb0 + ybC + more + word fline + xa4 + ya6 + xb4 + ybC + + word fline + xa2 + ya4 + xb0 + ybC + more 'V + word fline + xa2 + ya4 + xb4 + ybC + + word fline + xa0 + yaC + xb0 + yb4 + more 'W + word fline + xa4 + yaC + xb4 + yb4 + more + word fline + xa2 + ya8 + xb0 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb4 + + word fline + xa4 + ya4 + xb0 + ybC + more 'X + word fline + xa0 + ya4 + xb4 + ybC + + word fline + xa0 + yaC + xb2 + yb8 + more 'Y + word fline + xa4 + yaC + xb2 + yb8 + more + word fline + xa2 + ya4 + xb2 + yb8 + + word fline + xa0 + yaC + xb4 + ybC + more 'Z + word fline + xa0 + ya4 + xb4 + ybC + more + word fline + xa0 + ya4 + xb4 + yb4 + + word fline + xa2 + yaD + xb2 + yb3 + more '[ + word fline + xa2 + yaD + xb4 + ybD + more + word fline + xa2 + ya3 + xb4 + yb3 + + word fline + xa4 + ya4 + xb0 + ybC '\ + + word fline + xa2 + yaD + xb2 + yb3 + more '[ + word fline + xa2 + yaD + xb0 + ybD + more + word fline + xa2 + ya3 + xb0 + yb3 + + word fline + xa2 + yaA + xb0 + yb6 + more '^ + word fline + xa2 + yaA + xb4 + yb6 + + word fline + xa0 + ya1 + xa4 + yb1 '_ + + word fline + xa1 + ya9 + xb3 + yb7 '` + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'a + word fline + xa4 + ya4 + xb4 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'b + word fline + xa0 + ya4 + xb0 + ybC + + word farc + xa2 + ya6 + a9 + ax2 + ay2 + more 'c + word fline + xa2 + ya4 + xb4 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'd + word fline + xa4 + ya4 + xb4 + ybC + + word farc + xa2 + ya6 + a4 + ax2 + ay2 + more 'e + word fline + xa0 + ya6 + xb4 + yb6 + more + word fline + xa2 + ya4 + xb4 + yb4 + + word farc + xa4 + yaA + aD + ax2 + ay2 + more 'f + word fline + xa0 + ya8 + xb4 + yb8 + more + word fline + xa2 + ya4 + xb2 + ybA + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'g + word farc + xa2 + ya3 + aF + ax2 + ay2 + more + word fline + xa4 + ya3 + xb4 + yb8 + more + word fline + xa1 + ya1 + xb2 + yb1 + + word farc + xa2 + ya6 + a8 + ax2 + ay2 + more 'h + word fline + xa0 + ya4 + xb0 + ybC + more + word fline + xa4 + ya4 + xb4 + yb6 + + word fline + xa1 + ya4 + xb3 + yb4 + more 'i + word fline + xa2 + ya4 + xb2 + yb8 + more + word fline + xa1 + ya8 + xb2 + yb8 + more + word fline + xa2 + yaB + xb2 + ybA + + word farc + xa0 + ya3 + aF + ax2 + ay2 + more 'j + word fline + xa2 + ya3 + xb2 + yb8 + more + word fline + xa1 + ya8 + xb2 + yb8 + more + word fline + xa2 + yaB + xb2 + ybA + + word fline + xa0 + ya4 + xb0 + ybC + more 'k + word fline + xa0 + ya6 + xb2 + yb6 + more + word fline + xa2 + ya6 + xb4 + yb8 + more + word fline + xa2 + ya6 + xb4 + yb4 + + word fline + xa1 + ya4 + xb3 + yb4 + more 'l + word fline + xa2 + ya4 + xb2 + ybC + more + word fline + xa1 + yaC + xb2 + ybC + + word farc + xa1 + ya7 + a8 + ax1 + ay1 + more 'm + word farc + xa3 + ya7 + a8 + ax1 + ay1 + more + word fline + xa0 + ya4 + xb0 + yb8 + more + word fline + xa2 + ya4 + xb2 + yb7 + more + word fline + xa4 + ya4 + xb4 + yb7 + + word farc + xa2 + ya6 + a8 + ax2 + ay2 + more 'n + word fline + xa0 + ya4 + xb0 + yb8 + more + word fline + xa4 + ya4 + xb4 + yb6 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 'o + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'p + word fline + xa0 + ya1 + xb0 + yb8 + + word farc + xa2 + ya6 + a0 + ax2 + ay2 + more 'q + word fline + xa4 + ya1 + xb4 + yb8 + + word farc + xa2 + ya7 + a8 + ax2 + ay1 + more 'r + word fline + xa0 + ya4 + xb0 + yb8 + + word farc + xa2 + ya7 + a9 + ax2 + ay1 + more 's + word farc + xa2 + ya5 + aB + ax2 + ay1 + more + word fline + xa0 + ya4 + xb2 + yb4 + more + word fline + xa2 + ya8 + xb4 + yb8 + + word farc + xa4 + ya6 + aE + ax2 + ay2 + more 't + word fline + xa0 + ya8 + xb4 + yb8 + more + word fline + xa2 + ya6 + xb2 + ybA + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'u + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa4 + ya4 + xb4 + yb8 + + word fline + xa0 + ya8 + xb2 + yb4 + more 'v + word fline + xa4 + ya8 + xb2 + yb4 + + word farc + xa1 + ya5 + aA + ax1 + ay1 + more 'w + word farc + xa3 + ya5 + aA + ax1 + ay1 + more + word fline + xa0 + ya5 + xb0 + yb8 + more + word fline + xa2 + ya5 + xb2 + yb6 + more + word fline + xa4 + ya5 + xb4 + yb8 + + word fline + xa0 + ya8 + xb4 + yb4 + more 'x + word fline + xa0 + ya4 + xb4 + yb8 + + word farc + xa2 + ya6 + aA + ax2 + ay2 + more 'y + word farc + xa2 + ya3 + aF + ax2 + ay2 + more + word fline + xa4 + ya3 + xb4 + yb8 + more + word fline + xa0 + ya6 + xb0 + yb8 + more + word fline + xa1 + ya1 + xb2 + yb1 + + word fline + xa0 + ya8 + xb4 + yb8 + more 'z + word fline + xa4 + ya8 + xb0 + yb4 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa3 + yaA + aD + ax1 + ay3 + more '{ + word farc + xa1 + ya6 + aC + ax1 + ay2 + more + word farc + xa1 + yaA + aF + ax1 + ay2 + more + word farc + xa3 + ya6 + aE + ax1 + ay3 + + word fline + xa2 + ya3 + xb2 + ybD '| + + word farc + xa1 + yaA + aC + ax1 + ay3 + more '} + word farc + xa3 + ya6 + aD + ax1 + ay2 + more + word farc + xa3 + yaA + aE + ax1 + ay2 + more + word farc + xa1 + ya6 + aF + ax1 + ay3 + + word farc + xa1 + ya8 + a8 + ax1 + ay1 + more '~ + word farc + xa3 + ya8 + aA + ax1 + ay1 + +' Vector font - custom characters ($7F+) + + word fline + xa2 + ya9 + xb0 + yb4 + more 'delta + word fline + xa2 + ya9 + xb4 + yb4 + more + word fline + xa0 + ya4 + xb4 + yb4 + + word farc + xa2 + ya7 + a8 + ax2 + ay2 + more 'omega + word farc + xa1 + ya7 + aE + ax1 + ay2 + more + word farc + xa3 + ya7 + aF + ax1 + ay2 + more + word fline + xa1 + ya5 + xb1 + yb4 + more + word fline + xa3 + ya5 + xb3 + yb4 + more + word fline + xa0 + ya4 + xb1 + yb4 + more + word fline + xa4 + ya4 + xb3 + yb4 + + word farc + xa2 + ya8 + a0 + ax1 + ay1 'bullet + +CON fx = 3 'number of custom characters + +DAT + +'************************************* +'* Assembly language graphics driver * +'************************************* + + org +' +' +' Graphics driver - main loop +' +loop rdlong t1,par wz 'wait for command + if_z jmp #loop + + movd :arg,#arg0 'get 8 arguments + mov t2,t1 + mov t3,#8 +:arg rdlong arg0,t2 + add :arg,d0 + add t2,#4 + djnz t3,#:arg + + wrlong zero,par 'zero command to signify received + + call #setd 'set dx,dy from arg0,arg1 + + ror t1,#16+2 'lookup command address + add t1,#jumps + movs :table,t1 + rol t1,#2 + shl t1,#3 +:table mov t2,0 + shr t2,t1 + and t2,#$FF + jmp t2 'jump to command + + +jumps byte 0 '0 + byte setup_ '1 + byte color_ '2 + byte width_ '3 + byte plot_ '4 + byte line_ '5 + byte arc_ '6 + byte vec_ '7 + byte vecarc_ '8 + byte pix_ '9 + byte pixarc_ 'A + byte text_ 'B + byte textarc_ 'C + byte textmode_ 'D + byte fill_ 'E + byte loop 'F +' +' +' setup(x_tiles, y_tiles*16, x_origin, y_origin, base_ptr) bases_ptr, slices_ptr +' +setup_ mov xlongs,arg0 'set xlongs, ylongs + mov ylongs,arg1 + mov xorigin,arg2 'set xorigin, yorigin + mov yorigin,arg3 + mov basesptr,arg5 'set pointers + mov slicesptr,arg6 + + jmp #loop +' +' +' color(c) +' +color_ mov pcolor,arg0 'set pixel color + + jmp #loop +' +' +' width(w) pixel_passes +' +width_ mov pwidth,arg0 'set pixel width + mov passes,arg1 'set pixel passes + + jmp #loop +' +' +' plot(x, y) +' +plot_ call #plotd + + jmp #loop +' +' +' line(x, y) +' +line_ call #linepd + + jmp #loop +' +' +' arc(x, y, xr, yr, angle, anglestep, iterations, mode) +' +arc_ and arg7,#3 'limit mode + +:loop call #arca 'get arc dx,dy + + cmp arg7,#1 wz 'if not mode 1, set px,py + if_nz mov px,dx + if_nz mov py,dy + + tjz arg6,#loop 'if no points exit with new px,py + + cmp arg7,#3 wz 'if mode 3, set center + if_z call #setd + + test arg7,#1 wz 'if mode 0 or 2, plot point + if_z call #plotp + + test arg7,#1 wz 'if mode 1 or 3, plot line + if_nz call #linepd + + cmp arg7,#2 wz 'if mode 2, set mode 1 + if_z mov arg7,#1 + + add arg4,arg5 'step angle + djnz arg6,#:loop 'loop if more iterations + + jmp #loop +' +' +' vec(x, y, vecscale, vecangle, vecdef_ptr) +' vecarc(x, y, xr, yr, angle, vecscale, vecangle, vecdef_ptr) +' +' vecdef: word $8000/$4000+angle 'vector mode + 13-bit angle (mode: $4000=plot, $8000=line) +' word length 'vector length +' ... 'more vectors +' ... +' word 0 'end of definition +' +vecarc_ call #arcmod + +vec_ tjz arg2,#loop 'if scale 0, exit + +:loop rdword t7,arg4 wz 'get vector mode+angle + add arg4,#2 + + if_z jmp #loop 'if mode+angle 0, exit + + rdword t1,arg4 'get vector length + add arg4,#2 + + abs t2,arg2 wc 'add/sub vector angle to/from angle + mov t6,arg3 + sumc t6,t7 + + call #multiply 'multiply length by scale + add t1,#$80 'round up 1/2 lsb + shr t1,#8 + + mov t4,t1 'get arc dx,dy + mov t5,t1 + call #arcd + + test t7,h8000 wc 'plot pixel or draw line? + if_nc call #plotd + test t7,h8000 wc + if_c call #linepd + + jmp #:loop 'get next vector +' +' +' pix(x, y, pixrot, pixdef_ptr) +' pixarc(x, y, xr, yr, angle, pixrot, pixdef_ptr) +' +' pixdef: word +' byte xwords, ywords, xorigin, yorigin +' word %%xxxxxxxx,%%xxxxxxxx +' word %%xxxxxxxx,%%xxxxxxxx +' word %%xxxxxxxx,%%xxxxxxxx +' ... +' +pixarc_ call #arcmod + +pix_ mov t6,pcolor 'save color + + mov px,dx 'get center into px,py + mov py,dy + + mov sy,pwidth 'get actual pixel width + add sy,#1 + + rdbyte dx,arg3 'get dimensions into dx,dy + add arg3,#1 + rdbyte dy,arg3 + add arg3,#1 + + rdbyte t1,arg3 'get origin and adjust px,py + add arg3,#1 + rdbyte t2,arg3 + add arg3,#1 + neg t2,t2 + sub t2,#1 + add t2,dy + mov t3,sy +:adjust test arg2,#%001 wz + test arg2,#%110 wc + if_z sumnc px,t1 + if_nz sumc py,t1 + test arg2,#%010 wc + if_nz sumnc px,t2 + if_z sumnc py,t2 + djnz t3,#:adjust + +:yline mov sx,#0 'plot entire pix + mov t3,dx +:xword rdword t4,arg3 'read next pix word + add arg3,#2 + shl t4,#16 + mov t5,#8 +:xpixel rol t4,#2 'plot pixel within word + test t4,#1 wc 'set color + muxc pcolor,color1 + test t4,#2 wc + muxc pcolor,color2 wz '(z=1 if color=0) + if_nz call #plotp + test arg2,#%001 wz 'update px,py for next x + test arg2,#%110 wc + if_z sumc px,sy + if_nz sumnc py,sy + add sx,sy + djnz t5,#:xpixel 'another x pixel? + djnz t3,#:xword 'another x word? + if_z sumnc px,sx 'update px,py for next y + if_nz sumc py,sx + test arg2,#%010 wc + if_nz sumc px,sy + if_z sumc py,sy + djnz dy,#:yline 'another y line? + + mov pcolor,t6 'restore color + + jmp #loop +' +' +' text(x, y, @string) justx, justy +' textarc(x, y, xr, yr, angle, @string) justx, justy +' +textarc_ call #arcmod + +text_ add arg3,arg0 'add x into justx + add arg4,arg1 'add y into justy + +:chr rdbyte t1,arg2 wz 'get chr + add arg2,#1 + + if_z jmp #loop 'if 0, done + + sub t1,#$21 'if chr out of range, skip + cmp t1,#$7F-$21+fx wc + if_nc jmp #:skip + + mov arg5,fontptr 'scan font for chr definition +:scan tjz t1,#:def + rdword t2,arg5 + add arg5,#2 + test t2,h8000 wc + if_nc sub t1,#1 + jmp #:scan + +:def rdword t7,arg5 'get font definition word + add arg5,#2 + + call #fontxy 'extract initial x,y + + test t7,#$80 wc 'arc or line? + if_nc jmp #:line + + + mov t2,textsx 'arc, extract x radius + mov t3,#%0001_0001_1 + call #fontb + mov t4,t1 + + mov t2,textsy 'extract y radius + mov t3,#%0010_0011_1 + call #fontb + mov t5,t1 + + mov t2,#1 'extract starting angle + mov t3,#%0010_0011_0 + call #fontb + shl t1,#11 + + mov t6,t1 'extract angle sweep + mov t3,#%0010_0011_0 + call #fontb + neg arg6,t1 + shl arg6,#4 + add arg6,#65 + + call #arcd 'plot initial arc point + call #plotd + +:arc call #arcd 'connect subsequent arc points with lines + call #linepd + add t6,#$80 + djnz arg6,#:arc + + jmp #:more + + +:line call #plotd 'line, plot initial x,y + + call #fontxy 'extract terminal x,y + + call #linepd 'draw line + + +:more test t7,#$02 wc 'more font definition? + if_c jmp #:def + +:skip mov t1,textsp 'advance x to next chr position + mov t2,textsx + call #multiply + add arg3,t1 + + jmp #:chr 'get next chr + + +fontxy mov t2,textsx 'extract x + mov t3,#%0011_0111_0 + call #fontb + mov arg0,t1 + add arg0,arg3 + + mov t2,textsy 'extract y + mov t3,#%0100_1111_0 + call #fontb + mov arg1,t1 + add arg1,arg4 + +setd mov dx,xorigin 'set dx,dy from arg0,arg1 + add dx,arg0 + mov dy,yorigin + sub dy,arg1 +setd_ret +fontxy_ret ret + + +fontb mov t1,t7 'extract bitrange from font word + shr t3,#1 wc + and t1,t3 + if_c add t1,#1 + shr t3,#4 + shr t7,t3 + + shl t1,#32-4 'multiply t1[3..0] by t2 + mov t3,#4 +:loop shl t1,#1 wc + if_c add t1,t2 + djnz t3,#:loop + +fontb_ret ret +' +' +' textmode(x_scale, y_scale, spacing, justification) +' +textmode_ mov textsx,arg0 'set text x scale + mov textsy,arg1 'set text y scale + mov textsp,arg2 'set text spacing + + jmp #loop +' +' +' fill(x, y, da, db, db2, linechange, lines_minus_1) +' +fill_ shl dx,#16 'get left and right fractions + or dx,h8000 + mov t1,dx + + mov t2,xlongs 'get x pixels + shl t2,#4 + + add arg6,#1 'pre-increment line counter + +:yloop add dx,arg2 'adjust left and right fractions + add t1,arg3 + + cmps dx,t1 wc 'get left and right integers + if_c mov base0,dx + if_c mov base1,t1 + if_nc mov base0,t1 + if_nc mov base1,dx + sar base0,#16 + sar base1,#16 + + cmps base0,t2 wc 'left out of range? + if_c cmps hFFFFFFFF,base1 wc 'right out of range? + if_c cmp dy,ylongs wc 'y out of range? + if_nc jmp #:skip 'if any, skip + + mins base0,#0 'limit left and right + maxs base1,t2 wc + if_nc sub base1,#1 + + shl base0,#1 'make left mask + neg mask0,#1 + shl mask0,base0 + shr base0,#5 + + shl base1,#1 'make right mask + xor base1,#$1E + neg mask1,#1 + shr mask1,base1 + shr base1,#5 + + sub base1,base0 wz 'ready long count + add base1,#1 + + if_z and mask0,mask1 'if single long, merge masks + + shl base0,#1 'get long base + add base0,basesptr + rdword base0,base0 + shl dy,#2 + add base0,dy + shr dy,#2 + + mov bits0,mask0 'ready left mask +:xloop mov bits1,pcolor 'make color mask + and bits1,bits0 + rdlong pass,base0 'read-modify-write long + andn pass,bits0 + or pass,bits1 + wrlong pass,base0 + shl ylongs,#2 'advance to next long + add base0,ylongs + shr ylongs,#2 + cmp base1,#2 wz 'one more? + if_nz neg bits0,#1 'if not, ready full mask + if_z mov bits0,mask1 'if one more, ready right mask + djnz base1,#:xloop 'loop if more longs + +:skip sub arg5,#1 wc 'delta change? + if_c mov arg3,arg4 'if so, set new deltas +:same + add dy,#1 'adjust y + djnz arg6,#:yloop 'another y? + + jmp #loop +' +' +' Plot line from px,py to dx,dy +' +linepd cmps dx,px wc, wr 'get x difference + negc sx,#1 'set x direction + + cmps dy,py wc, wr 'get y difference + negc sy,#1 'set y direction + + abs dx,dx 'make differences absolute + abs dy,dy + + cmp dx,dy wc 'determine dominant axis + if_nc tjz dx,#:last 'if both differences 0, plot single pixel + if_nc mov count,dx 'set pixel count + if_c mov count,dy + mov ratio,count 'set initial ratio + shr ratio,#1 + if_c jmp #:yloop 'x or y dominant? + + +:xloop call #plotp 'dominant x line + add px,sx + sub ratio,dy wc + if_c add ratio,dx + if_c add py,sy + djnz count,#:xloop + + jmp #:last 'plot last pixel + + +:yloop call #plotp 'dominant y line + add py,sy + sub ratio,dx wc + if_c add ratio,dy + if_c add px,sx + djnz count,#:yloop + +:last call #plotp 'plot last pixel + +linepd_ret ret +' +' +' Plot pixel at px,py +' +plotd mov px,dx 'set px,py to dx,dy + mov py,dy + +plotp tjnz pwidth,#wplot 'if width > 0, do wide plot + + mov t1,px 'compute pixel mask + shl t1,#1 + mov mask0,#%11 + shl mask0,t1 + shr t1,#5 + + cmp t1,xlongs wc 'if x or y out of bounds, exit + if_c cmp py,ylongs wc + if_nc jmp #plotp_ret + + mov bits0,pcolor 'compute pixel bits + and bits0,mask0 + + shl t1,#1 'get address of pixel long + add t1,basesptr + mov t2,py + rdword t1,t1 + shl t2,#2 + add t1,t2 + + rdlong t2,t1 'write pixel + andn t2,mask0 + or t2,bits0 + wrlong t2,t1 +plotp_ret +plotd_ret ret +' +' +' Plot wide pixel +' +wplot mov t1,py 'if y out of bounds, exit + add t1,#7 + mov t2,ylongs + add t2,#7+8 + cmp t1,t2 wc + if_nc jmp #plotp_ret + + mov t1,px 'determine x long pair + sub t1,#8 + sar t1,#4 + cmp t1,xlongs wc + muxc jumps,#%01 '(use jumps[1..0] to store writes) + add t1,#1 + cmp t1,xlongs wc + muxc jumps,#%10 + + test jumps,#%11 wz 'if x out of bounds, exit + if_z jmp #plotp_ret + + shl t1,#1 'get base pair + add t1,basesptr + rdword base1,t1 + sub t1,#2 + rdword base0,t1 + + mov t1,px 'determine pair shifts + shl t1,#1 + movs :shift1,t1 + xor :shift1,#7<<1 + add t1,#9<<1 + movs :shift0,t1 + test t1,#$F<<1 wz '(account for special case) + if_z andn jumps,#%01 + + mov pass,#0 'ready to plot slices + mov slice,slicesptr + +:loop rdlong mask0,slice 'get next slice + mov mask1,mask0 + +:shift0 shl mask0,#0 'position slice +:shift1 shr mask1,#0 + + mov bits0,pcolor 'colorize slice + and bits0,mask0 + mov bits1,pcolor + and bits1,mask1 + + mov t1,py 'plot lower slice + add t1,pass + cmp t1,ylongs wc + if_c call #wslice + + mov t1,py 'plot upper slice + test pwidth,#1 wc + subx t1,pass + cmp t1,ylongs wc + if_c call #wslice + + add slice,#4 'next slice + add pass,#1 + cmp pass,passes wz + if_nz jmp #:loop + + jmp #plotp_ret +' +' +' Plot wide pixel slice +' +wslice shl t1,#2 'ready long offset + + add base0,t1 'plot left slice + test jumps,#%01 wc + if_c rdlong t2,base0 + if_c andn t2,mask0 + if_c or t2,bits0 + if_c wrlong t2,base0 + + add base1,t1 'plot right slice + test jumps,#%10 wc + if_c rdlong t2,base1 + if_c andn t2,mask1 + if_c or t2,bits1 + if_c wrlong t2,base1 + + sub base0,t1 'restore bases + sub base1,t1 + +wslice_ret ret +' +' +' Get arc point from args and then move args 5..7 to 2..4 +' +arcmod call #arca 'get arc using first 5 args + + mov arg0,dx 'set arg0,arg1 + sub arg0,xorigin + mov arg1,yorigin + sub arg1,dy + + mov arg2,arg5 'move args 5..7 to 2..4 + mov arg3,arg6 + mov arg4,arg7 + +arcmod_ret ret +' +' +' Get arc dx,dy from arg0,arg1 +' +' in: arg0,arg1 = center x,y +' arg2/t4 = x length +' arg3/t5 = y length +' arg4/t6 = 13-bit angle +' +' out: dx,dy = arc point +' +arca mov t4,arg2 'use args + mov t5,arg3 + mov t6,arg4 + +arcd call #setd 'reset dx,dy to arg0,arg1 + + mov t1,t6 'get arc dx + mov t2,t4 + call #polarx + add dx,t1 + + mov t1,t6 'get arc dy + mov t2,t5 + call #polary + sub dy,t1 +arcd_ret +arca_ret ret +' +' +' Polar to cartesian +' +' in: t1 = 13-bit angle +' t2 = 16-bit length +' +' out: t1 = x|y +' +polarx add t1,sine_90 'cosine, add 90° for sine lookup +polary test t1,sine_180 wz 'get sine quadrant 3|4 into nz + test t1,sine_90 wc 'get sine quadrant 2|4 into c + negc t1,t1 'if sine quadrant 2|4, negate table offset + or t1,sine_table 'or in sine table address >> 1 + shl t1,#1 'shift left to get final word address + rdword t1,t1 'read sine/cosine word + call #multiply 'multiply sine/cosine by length to get x|y + add t1,h8000 'add 1/2 lsb to round up x|y fraction + shr t1,#16 'justify x|y integer + negnz t1,t1 'if sine quadrant 3|4, negate x|y +polary_ret +polarx_ret ret + +sine_90 long $0800 '90° bit +sine_180 long $1000 '180° bit +sine_table long $E000 >> 1 'sine table address shifted right +' +' +' Multiply +' +' in: t1 = 16-bit multiplicand (t1[31..16] must be 0) +' t2 = 16-bit multiplier +' +' out: t1 = 32-bit product +' +multiply mov t3,#16 + shl t2,#16 + shr t1,#1 wc + +:loop if_c add t1,t2 wc + rcr t1,#1 wc + djnz t3,#:loop + +multiply_ret ret +' +' +' Defined data +' +zero long 0 'constants +d0 long $200 +h8000 long $8000 +hFFFFFFFF long $FFFFFFFF +color1 long %%1111111111111111 +color2 long %%2222222222222222 + +fontptr long 0 'font pointer (set before cognew command) + +pcolor long %%1111111111111111 'pixel color +pwidth long 0 'pixel width +passes long 1 'pixel passes +textsx long 1 'text scale x +textsy long 1 'text scale y +textsp long 6 'text spacing +' +' +' Undefined data +' +t1 res 1 'temps +t2 res 1 +t3 res 1 +t4 res 1 +t5 res 1 +t6 res 1 +t7 res 1 + +arg0 res 1 'arguments passed from high-level +arg1 res 1 +arg2 res 1 +arg3 res 1 +arg4 res 1 +arg5 res 1 +arg6 res 1 +arg7 res 1 + +basesptr res 1 'pointers +slicesptr res 1 + +xlongs res 1 'bitmap metrics +ylongs res 1 +xorigin res 1 +yorigin res 1 + +dx res 1 'line/plot coordinates +dy res 1 +px res 1 +py res 1 + +sx res 1 'line +sy res 1 +count res 1 +ratio res 1 + +pass res 1 'plot +slice res 1 +base0 res 1 +base1 res 1 +mask0 res 1 +mask1 res 1 +bits0 res 1 +bits1 res 1 + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/source/shoot/bellatrix/Mouse.spin b/source/shoot/bellatrix/Mouse.spin new file mode 100644 index 0000000..fb7f470 --- /dev/null +++ b/source/shoot/bellatrix/Mouse.spin @@ -0,0 +1,492 @@ +''*************************************** +''* PS/2 Mouse Driver v1.1 * +''* Author: Chip Gracey * +''* Copyright (c) 2006 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +' v1.0 - 01 May 2006 - original version +' v1.1 - 01 Jun 2006 - bound coordinates added to simplify upper objects + + +VAR + + long cog + + long oldx, oldy, oldz 'must be followed by parameters (10 contiguous longs) + + long par_x 'absolute x read-only (7 contiguous longs) + long par_y 'absolute y read-only + long par_z 'absolute z read-only + long par_buttons 'button states read-only + long par_present 'mouse present read-only + long par_dpin 'data pin write-only + long par_cpin 'clock pin write-only + + long bx_min, by_min, bz_min 'min/max must be contiguous + long bx_max, by_max, bz_max + long bx_div, by_div, bz_div + long bx_acc, by_acc, bz_acc + + +PUB start(dpin, cpin) : okay + +'' Start mouse driver - starts a cog +'' returns false if no cog available +'' +'' dpin = data signal on PS/2 jack +'' cpin = clock signal on PS/2 jack +'' +'' use 100-ohm resistors between pins and jack +'' use 10K-ohm resistors to pull jack-side signals to VDD +'' connect jack-power to 5V, jack-gnd to VSS + + stop + par_dpin := dpin + par_cpin := cpin + okay := cog := cognew(@entry, @par_x) + 1 + + +PUB stop + +'' Stop mouse driver - frees a cog + + if cog + cogstop(cog~ - 1) + longfill(@oldx, 0, 10) + + +PUB present : type + +'' Check if mouse present - valid ~2s after start +'' returns mouse type: +'' +'' 3 = five-button scrollwheel mouse +'' 2 = three-button scrollwheel mouse +'' 1 = two-button or three-button mouse +'' 0 = no mouse connected + + type := par_present + + +PUB button(b) : state + +'' Get the state of a particular button +'' returns t|f + + state := -(par_buttons >> b & 1) + + +PUB buttons : states + +'' Get the states of all buttons +'' returns buttons: +'' +'' bit4 = right-side button +'' bit3 = left-side button +'' bit2 = center/scrollwheel button +'' bit1 = right button +'' bit0 = left button + + states := par_buttons + + +PUB abs_x : x + +'' Get absolute-x + + x := par_x + + +PUB abs_y : y + +'' Get absolute-y + + y := par_y + + +PUB abs_z : z + +'' Get absolute-z (scrollwheel) + + z := par_z + + +PUB delta_reset + +'' Reset deltas + + oldx := par_x + oldy := par_y + oldz := par_z + + +PUB delta_x : x | newx + +'' Get delta-x + + newx := par_x + x := newx - oldx + oldx := newx + + +PUB delta_y : y | newy + +'' Get delta-y + + newy := par_y + y := newy - oldy + oldy := newy + + +PUB delta_z : z | newz + +'' Get delta-z (scrollwheel) + + newz := par_z + z := newz - oldz + oldz := newz + + +PUB bound_limits(xmin, ymin, zmin, xmax, ymax, zmax) | i + +'' Set bounding limits + + longmove(@bx_min, @xmin, 6) + + +PUB bound_scales(x_scale, y_scale, z_scale) + +'' Set bounding scales (usually +/-1's, bigger values divide) + + longmove(@bx_div, @x_scale, 3) + + +PUB bound_preset(x, y, z) | i, d + +'' Preset bound coordinates + + repeat i from 0 to 2 + d := ||bx_div[i] + bx_acc[i] := (x[i] - bx_min[i]) * d + d >> 1 + + +PUB bound_x : x + +'' Get bound-x + + x := bound(0, delta_x) + + +PUB bound_y : y + +'' Get bound-y + + y := bound(1, delta_y) + + +PUB bound_z : z + +'' Get bound-z + + z := bound(2, delta_z) + + +PRI bound(i, delta) : b | d + + d := bx_div[i] + b := bx_min[i] + (bx_acc[i] := bx_acc[i] + delta * (d < 0) | 1 #> 0 <# (bx_max[i] - bx_min[i] + 1) * ||d - 1) / ||d + + +DAT + +'*************************************** +'* Assembly language PS/2 mouse driver * +'*************************************** + + org +' +' +' Entry +' +entry mov p,par 'load input parameters: + add p,#5*4 '_dpin/_cpin + rdlong _dpin,p + add p,#4 + rdlong _cpin,p + + mov dmask,#1 'set pin masks + shl dmask,_dpin + mov cmask,#1 + shl cmask,_cpin + + test _dpin,#$20 wc 'modify port registers within code + muxc _d1,dlsb + muxc _d2,dlsb + muxc _d3,#1 + muxc _d4,#1 + test _cpin,#$20 wc + muxc _c1,dlsb + muxc _c2,dlsb + muxc _c3,#1 + + movd :par,#_x 'reset output parameters: + mov p,#5 '_x/_y/_z/_buttons/_present +:par mov 0,#0 + add :par,dlsb + djnz p,#:par +' +' +' Reset mouse +' +reset mov dira,#0 'reset directions + mov dirb,#0 + + mov stat,#1 'set reset flag +' +' +' Update parameters +' +update movd :par,#_x 'update output parameters: + mov p,par '_x/_y/_z/_buttons/_present + mov q,#5 +:par wrlong 0,p + add :par,dlsb + add p,#4 + djnz q,#:par + + test stat,#1 wc 'if reset flag, transmit reset command + if_c mov data,#$FF + if_c call #transmit +' +' +' Get data packet +' + mov stat,#0 'reset state + + call #receive 'receive first byte + + cmp data,#$AA wz 'powerup/reset? + if_z jmp #init + + mov _buttons,data 'data packet, save buttons + + call #receive 'receive second byte + + test _buttons,#$10 wc 'adjust _x + muxc data,signext + add _x,data + + call #receive 'receive third byte + + test _buttons,#$20 wc 'adjust _y + muxc data,signext + add _y,data + + and _buttons,#%111 'trim buttons + + cmp _present,#2 wc 'if not scrollwheel mouse, update parameters + if_c jmp #update + + + call #receive 'scrollwheel mouse, receive fourth byte + + cmp _present,#3 wz 'if 5-button mouse, handle two extra buttons + if_z test data,#$10 wc + if_z_and_c or _buttons,#%01000 + if_z test data,#$20 wc + if_z_and_c or _buttons,#%10000 + + shl data,#28 'adjust _z + sar data,#28 + sub _z,data + + jmp #update 'update parameters +' +' +' Initialize mouse +' +init call #receive '$AA received, receive id + + movs crate,#100 'try to enable 3-button scrollwheel type + call #checktype + movs crate,#200 'try to enable 5-button scrollwheel type + call #checktype + shr data,#1 'if neither, 3-button type + add data,#1 + mov _present,data + + movs srate,#200 'set 200 samples per second + call #setrate + + mov data,#$F4 'enable data reporting + call #transmit + + jmp #update +' +' +' Check mouse type +' +checktype movs srate,#200 'perform "knock" sequence to enable + call #setrate '..scrollwheel and extra buttons + +crate movs srate,#200/100 + call #setrate + + movs srate,#80 + call #setrate + + mov data,#$F2 'read type + call #transmit + call #receive + +checktype_ret ret +' +' +' Set sample rate +' +setrate mov data,#$F3 + call #transmit +srate mov data,#0 + call #transmit + +setrate_ret ret +' +' +' Transmit byte to mouse +' +transmit +_c1 or dira,cmask 'pull clock low + movs napshr,#13 'hold clock for ~128us (must be >100us) + call #nap +_d1 or dira,dmask 'pull data low + movs napshr,#18 'hold data for ~4us + call #nap +_c2 xor dira,cmask 'release clock + + test data,#$0FF wc 'append parity and stop bits to byte + muxnc data,#$100 + or data,dlsb + + mov p,#10 'ready 10 bits +transmit_bit call #wait_c0 'wait until clock low + shr data,#1 wc 'output data bit +_d2 muxnc dira,dmask + mov wcond,c1 'wait until clock high + call #wait + djnz p,#transmit_bit 'another bit? + + mov wcond,c0d0 'wait until clock and data low + call #wait + mov wcond,c1d1 'wait until clock and data high + call #wait + + call #receive_ack 'receive ack byte with timed wait + cmp data,#$FA wz 'if ack error, reset mouse + if_nz jmp #reset + +transmit_ret ret +' +' +' Receive byte from mouse +' +receive test _cpin,#$20 wc 'wait indefinitely for initial clock low + waitpne cmask,cmask +receive_ack + mov p,#11 'ready 11 bits +receive_bit call #wait_c0 'wait until clock low + movs napshr,#16 'pause ~16us + call #nap +_d3 test dmask,ina wc 'input data bit + rcr data,#1 + mov wcond,c1 'wait until clock high + call #wait + djnz p,#receive_bit 'another bit? + + shr data,#22 'align byte + test data,#$1FF wc 'if parity error, reset mouse + if_nc jmp #reset + and data,#$FF 'isolate byte + +receive_ack_ret +receive_ret ret +' +' +' Wait for clock/data to be in required state(s) +' +wait_c0 mov wcond,c0 '(wait until clock low) + +wait mov q,tenms 'set timeout to 10ms + +wloop movs napshr,#18 'nap ~4us + call #nap +_c3 test cmask,ina wc 'check required state(s) +_d4 test dmask,ina wz 'loop until got state(s) or timeout +wcond if_never djnz q,#wloop '(replaced with c0/c1/c0d0/c1d1) + + tjz q,#reset 'if timeout, reset mouse +wait_ret +wait_c0_ret ret + + +c0 if_c djnz q,#wloop '(if_never replacements) +c1 if_nc djnz q,#wloop +c0d0 if_c_or_nz djnz q,#wloop +c1d1 if_nc_or_z djnz q,#wloop +' +' +' Nap +' +nap rdlong t,#0 'get clkfreq +napshr shr t,#18/16/13 'shr scales time + min t,#3 'ensure waitcnt won't snag + add t,cnt 'add cnt to time + waitcnt t,#0 'wait until time elapses (nap) + +nap_ret ret +' +' +' Initialized data +' +dlsb long 1 << 9 +tenms long 10_000 / 4 +signext long $FFFFFF00 +' +' +' Uninitialized data +' +dmask res 1 +cmask res 1 +stat res 1 +data res 1 +p res 1 +q res 1 +t res 1 + +_x res 1 'write-only +_y res 1 'write-only +_z res 1 'write-only +_buttons res 1 'write-only +_present res 1 'write-only +_dpin res 1 'read-only +_cpin res 1 'read-only + + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/source/shoot/bellatrix/TV.spin b/source/shoot/bellatrix/TV.spin new file mode 100644 index 0000000..ba3e11b --- /dev/null +++ b/source/shoot/bellatrix/TV.spin @@ -0,0 +1,711 @@ +''*************************************** +''* TV Driver v1.1 * +''* Author: Chip Gracey * +''* Copyright (c) 2004 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +' v1.0 - 01 May 2006 - original version +' v1.1 - 17 May 2006 - pixel tile size can now be 16 x 32 to enable more efficient +' character displays utilizing the internal font - see 'tv_mode' + + +CON + + fntsc = 3_579_545 'NTSC color frequency + lntsc = 3640 'NTSC color cycles per line * 16 + sntsc = 624 'NTSC color cycles per sync * 16 + + fpal = 4_433_618 'PAL color frequency + lpal = 4540 'PAL color cycles per line * 16 + spal = 848 'PAL color cycles per sync * 16 + + paramcount = 14 + colortable = $180 'start of colortable inside cog + + +VAR + + long cog + + +PUB start(tvptr) : okay + +'' Start TV driver - starts a cog +'' returns false if no cog available +'' +'' tvptr = pointer to TV parameters + + stop + okay := cog := cognew(@entry, tvptr) + 1 + + +PUB stop + +'' Stop TV driver - frees a cog + + if cog + cogstop(cog~ - 1) + + +DAT + +'******************************* +'* Assembly language TV driver * +'******************************* + + org +' +' +' Entry +' +entry mov taskptr,#tasks 'reset tasks + + mov x,#10 'perform task sections initially +:init jmpret taskret,taskptr + djnz x,#:init +' +' +' Superfield +' +superfield mov taskptr,#tasks 'reset tasks + + test _mode,#%0001 wc 'if ntsc, set phaseflip + if_nc mov phaseflip,phasemask + + test _mode,#%0010 wz 'get interlace into nz +' +' +' Field +' +field mov x,vinv 'do invisible back porch lines +:black call #hsync 'do hsync + waitvid burst,sync_high2 'do black + jmpret taskret,taskptr 'call task section (z undisturbed) + djnz x,#:black 'another black line? + + wrlong visible,par 'set status to visible + + mov x,vb 'do visible back porch lines + call #blank_lines + + mov screen,_screen 'point to first tile (upper-leftmost) + mov y,_vt 'set vertical tiles +:line mov vx,_vx 'set vertical expand +:vert if_z xor interlace,#1 'interlace skip? + if_z tjz interlace,#:skip + + call #hsync 'do hsync + + mov vscl,hb 'do visible back porch pixels + xor tile,colortable + waitvid tile,#0 + + mov x,_ht 'set horizontal tiles + mov vscl,hx 'set horizontal expand + +:tile rdword tile,screen 'read tile + or tile,line 'set pointer bits into tile + rol tile,#6 'read tile pixels + rdlong pixels,tile '(2 instructions between reads) + shr tile,#10+6 'set tile colors + movs :color,tile + add screen,#2 'point to next tile + mov tile,phaseflip +:color xor tile,colortable + waitvid tile,pixels 'pass colors and pixels to video + djnz x,#:tile 'another tile? + + sub screen,hc2x 'repoint to first tile in same line + + mov vscl,hf 'do visible front porch pixels + mov tile,phaseflip + xor tile,colortable + waitvid tile,#0 + +:skip djnz vx,#:vert 'vertical expand? + ror line,linerot 'set next line + add line,lineadd wc + rol line,linerot + if_nc jmp #:line + add screen,hc2x 'point to first tile in next line + djnz y,#:line 'another tile line? + + if_z xor interlace,#1 wz 'get interlace and field1 into z + + test _mode,#%0001 wc 'do visible front porch lines + mov x,vf + if_nz_and_c add x,#1 + call #blank_lines + + if_nz wrlong invisible,par 'unless interlace and field1, set status to invisible + + if_z_eq_c call #hsync 'if required, do short line + if_z_eq_c mov vscl,hrest + if_z_eq_c waitvid burst,sync_high2 + if_z_eq_c xor phaseflip,phasemask + + call #vsync_high 'do high vsync pulses + + movs vsync1,#sync_low1 'do low vsync pulses + movs vsync2,#sync_low2 + call #vsync_low + + call #vsync_high 'do high vsync pulses + + if_nz mov vscl,hhalf 'if odd frame, do half line + if_nz waitvid burst,sync_high2 + + if_z jmp #field 'if interlace and field1, display field2 + jmp #superfield 'else, new superfield +' +' +' Blank lines +' +blank_lines call #hsync 'do hsync + + xor tile,colortable 'do background + waitvid tile,#0 + + djnz x,#blank_lines + +blank_lines_ret ret +' +' +' Horizontal sync +' +hsync test _mode,#%0001 wc 'if pal, toggle phaseflip + if_c xor phaseflip,phasemask + + mov vscl,sync_scale1 'do hsync + mov tile,phaseflip + xor tile,burst + waitvid tile,sync_normal + + mov vscl,hvis 'setup in case blank line + mov tile,phaseflip + +hsync_ret ret +' +' +' Vertical sync +' +vsync_high movs vsync1,#sync_high1 'vertical sync + movs vsync2,#sync_high2 + +vsync_low mov x,vrep + +vsyncx mov vscl,sync_scale1 +vsync1 waitvid burst,sync_high1 + + mov vscl,sync_scale2 +vsync2 waitvid burst,sync_high2 + + djnz x,#vsyncx +vsync_low_ret +vsync_high_ret ret +' +' +' Tasks - performed in sections during invisible back porch lines +' +tasks mov t1,par 'load parameters + movd :par,#_enable '(skip _status) + mov t2,#paramcount - 1 +:load add t1,#4 +:par rdlong 0,t1 + add :par,d0 + djnz t2,#:load '+119 + + mov t1,_pins 'set video pins and directions + test t1,#$08 wc + if_nc mov t2,pins0 + if_c mov t2,pins1 + test t1,#$40 wc + shr t1,#1 + shl t1,#3 + shr t2,t1 + movs vcfg,t2 + shr t1,#6 + movd vcfg,t1 + shl t1,#3 + and t2,#$FF + shl t2,t1 + if_nc mov dira,t2 + if_nc mov dirb,#0 + if_c mov dira,#0 + if_c mov dirb,t2 '+18 + + tjz _enable,#disabled '+2, disabled? + + jmpret taskptr,taskret '+1=140, break and return later + + movs :rd,#wtab 'load ntsc/pal metrics from word table + movd :wr,#hvis + mov t1,#wtabx - wtab + test _mode,#%0001 wc +:rd mov t2,0 + add :rd,#1 + if_nc shl t2,#16 + shr t2,#16 +:wr mov 0,t2 + add :wr,d0 + djnz t1,#:rd '+54 + + if_nc movs :ltab,#ltab 'load ntsc/pal metrics from long table + if_c movs :ltab,#ltab+1 + movd :ltab,#fcolor + mov t1,#(ltabx - ltab) >> 1 +:ltab mov 0,0 + add :ltab,d0s1 + djnz t1,#:ltab '+17 + + rdlong t1,#0 'get CLKFREQ + shr t1,#1 'if CLKFREQ < 16MHz, cancel _broadcast + cmp t1,m8 wc + if_c mov _broadcast,#0 + shr t1,#1 'if CLKFREQ < color frequency * 4, disable + cmp t1,fcolor wc + if_c jmp #disabled '+11 + + jmpret taskptr,taskret '+1=83, break and return later + + mov t1,fcolor 'set ctra pll to fcolor * 16 + call #divide 'if ntsc, set vco to fcolor * 32 (114.5454 MHz) + test _mode,#%0001 wc 'if pal, set vco to fcolor * 16 (70.9379 MHz) + if_c movi ctra,#%00001_111 'select fcolor * 16 output (ntsc=/2, pal=/1) + if_nc movi ctra,#%00001_110 + if_nc shl t2,#1 + mov frqa,t2 '+147 + + jmpret taskptr,taskret '+1=148, break and return later + + mov t1,_broadcast 'set ctrb pll to _broadcast + mov t2,#0 'if 0, turn off ctrb + tjz t1,#:off + min t1,m8 'limit from 8MHz to 128MHz + max t1,m128 + mov t2,#%00001_100 'adjust _broadcast to be within 4MHz-8MHz +:scale shr t1,#1 '(vco will be within 64MHz-128MHz) + cmp m8,t1 wc + if_c add t2,#%00000_001 + if_c jmp #:scale +:off movi ctrb,t2 + call #divide + mov frqb,t2 '+165 + + jmpret taskptr,taskret '+1=166, break and return later + + mov t1,#%10100_000 'set video configuration + test _pins,#$01 wc '(swap broadcast/baseband output bits?) + if_c or t1,#%01000_000 + test _mode,#%1000 wc '(strip chroma from broadcast?) + if_nc or t1,#%00010_000 + test _mode,#%0100 wc '(strip chroma from baseband?) + if_nc or t1,#%00001_000 + and _auralcog,#%111 '(set aural cog) + or t1,_auralcog + movi vcfg,t1 '+10 + + mov hx,_hx 'compute horizontal metrics + shl hx,#8 + or hx,_hx + shl hx,#4 + + mov hc2x,_ht + shl hc2x,#1 + + mov t1,_ht + mov t2,_hx + call #multiply + mov hf,hvis + sub hf,t1 + shr hf,#1 wc + mov hb,_ho + addx hb,hf + sub hf,_ho '+52 + + mov t1,_vt 'compute vertical metrics + mov t2,_vx + call #multiply + test _mode,#%10000 wc 'consider tile size + muxc linerot,#1 + mov lineadd,lineinc + if_c shr lineadd,#1 + if_c shl t1,#1 + test _mode,#%0010 wc 'consider interlace + if_c shr t1,#1 + mov vf,vvis + sub vf,t1 + shr vf,#1 wc + neg vb,_vo + addx vb,vf + add vf,_vo '+53 + + xor _mode,#%0010 '+1, flip interlace bit for display + +:colors jmpret taskptr,taskret '+1=117/160, break and return later + + mov t1,#13 'load next 13 colors into colortable +:colorloop mov t2,:colorreg '5 times = 65 (all 64 colors loaded) + shr t2,#9-2 + and t2,#$FC + add t2,_colors +:colorreg rdlong colortable,t2 + add :colorreg,d0 + andn :colorreg,d6 + djnz t1,#:colorloop '+158 + + jmp #:colors '+1, keep loading colors +' +' +' Divide t1/CLKFREQ to get frqa or frqb value into t2 +' +divide rdlong m1,#0 'get CLKFREQ + + mov m2,#32+1 +:loop cmpsub t1,m1 wc + rcl t2,#1 + shl t1,#1 + djnz m2,#:loop + +divide_ret ret '+140 +' +' +' Multiply t1 * t2 * 16 (t1, t2 = bytes) +' +multiply shl t2,#8+4-1 + + mov m1,#8 +:loop shr t1,#1 wc + if_c add t1,t2 + djnz m1,#:loop + +multiply_ret ret '+37 +' +' +' Disabled - reset status, nap ~4ms, try again +' +disabled mov ctra,#0 'reset ctra + mov ctrb,#0 'reset ctrb + mov vcfg,#0 'reset video + + wrlong outa,par 'set status to disabled + + rdlong t1,#0 'get CLKFREQ + shr t1,#8 'nap for ~4ms + min t1,#3 + add t1,cnt + waitcnt t1,#0 + + jmp #entry 'reload parameters +' +' +' Initialized data +' +m8 long 8_000_000 +m128 long 128_000_000 +d0 long 1 << 9 << 0 +d6 long 1 << 9 << 6 +d0s1 long 1 << 9 << 0 + 1 << 1 +interlace long 0 +invisible long 1 +visible long 2 +phaseflip long $00000000 +phasemask long $F0F0F0F0 +line long $00060000 +lineinc long $10000000 +linerot long 0 +pins0 long %11110000_01110000_00001111_00000111 +pins1 long %11111111_11110111_01111111_01110111 +sync_high1 long %0101010101010101010101_101010_0101 +sync_high2 long %01010101010101010101010101010101 'used for black +sync_low1 long %1010101010101010101010101010_0101 +sync_low2 long %01_101010101010101010101010101010 +' +' +' NTSC/PAL metrics tables +' ntsc pal +' ---------------------------------------------- +wtab word lntsc - sntsc, lpal - spal 'hvis + word lntsc / 2 - sntsc, lpal / 2 - spal 'hrest + word lntsc / 2, lpal / 2 'hhalf + word 243, 286 'vvis + word 10, 18 'vinv + word 6, 5 'vrep + word $02_8A, $02_AA 'burst +wtabx +ltab long fntsc 'fcolor + long fpal + long sntsc >> 4 << 12 + sntsc 'sync_scale1 + long spal >> 4 << 12 + spal + long 67 << 12 + lntsc / 2 - sntsc 'sync_scale2 + long 79 << 12 + lpal / 2 - spal + long %0101_00000000_01_10101010101010_0101 'sync_normal + long %010101_00000000_01_101010101010_0101 +ltabx +' +' +' Uninitialized data +' +taskptr res 1 'tasks +taskret res 1 +t1 res 1 +t2 res 1 +m1 res 1 +m2 res 1 + +x res 1 'display +y res 1 +hf res 1 +hb res 1 +vf res 1 +vb res 1 +hx res 1 +vx res 1 +hc2x res 1 +screen res 1 +tile res 1 +pixels res 1 +lineadd res 1 + +hvis res 1 'loaded from word table +hrest res 1 +hhalf res 1 +vvis res 1 +vinv res 1 +vrep res 1 +burst res 1 + +fcolor res 1 'loaded from long table +sync_scale1 res 1 +sync_scale2 res 1 +sync_normal res 1 +' +' +' Parameter buffer +' +_enable res 1 '0/non-0 read-only +_pins res 1 '%pppmmmm read-only +_mode res 1 '%tccip read-only +_screen res 1 '@word read-only +_colors res 1 '@long read-only +_ht res 1 '1+ read-only +_vt res 1 '1+ read-only +_hx res 1 '4+ read-only +_vx res 1 '1+ read-only +_ho res 1 '0+- read-only +_vo res 1 '0+- read-only +_broadcast res 1 '0+ read-only +_auralcog res 1 '0-7 read-only + + fit colortable 'fit underneath colortable ($180-$1BF) +'' +''___ +''VAR 'TV parameters - 14 contiguous longs +'' +'' long tv_status '0/1/2 = off/invisible/visible read-only +'' long tv_enable '0/non-0 = off/on write-only +'' long tv_pins '%pppmmmm = pin group, pin group mode write-only +'' long tv_mode '%tccip = tile,chroma,interlace,ntsc/pal write-only +'' long tv_screen 'pointer to screen (words) write-only +'' long tv_colors 'pointer to colors (longs) write-only +'' long tv_ht 'horizontal tiles write-only +'' long tv_vt 'vertical tiles write-only +'' long tv_hx 'horizontal tile expansion write-only +'' long tv_vx 'vertical tile expansion write-only +'' long tv_ho 'horizontal offset write-only +'' long tv_vo 'vertical offset write-only +'' long tv_broadcast 'broadcast frequency (Hz) write-only +'' long tv_auralcog 'aural fm cog write-only +'' +''The preceding VAR section may be copied into your code. +''After setting variables, do start(@tv_status) to start driver. +'' +''All parameters are reloaded each superframe, allowing you to make live +''changes. To minimize flicker, correlate changes with tv_status. +'' +''Experimentation may be required to optimize some parameters. +'' +''Parameter descriptions: +'' _________ +'' tv_status +'' +'' driver sets this to indicate status: +'' 0: driver disabled (tv_enable = 0 or CLKFREQ < requirement) +'' 1: currently outputting invisible sync data +'' 2: currently outputting visible screen data +'' _________ +'' tv_enable +'' +'' 0: disable (pins will be driven low, reduces power) +'' non-0: enable +'' _______ +'' tv_pins +'' +'' bits 6..4 select pin group: +'' %000: pins 7..0 +'' %001: pins 15..8 +'' %010: pins 23..16 +'' %011: pins 31..24 +'' %100: pins 39..32 +'' %101: pins 47..40 +'' %110: pins 55..48 +'' %111: pins 63..56 +'' +'' bits 3..0 select pin group mode: +'' %0000: %0000_0111 - baseband +'' %0001: %0000_0111 - broadcast +'' %0010: %0000_1111 - baseband + chroma +'' %0011: %0000_1111 - broadcast + aural +'' %0100: %0111_0000 broadcast - +'' %0101: %0111_0000 baseband - +'' %0110: %1111_0000 broadcast + aural - +'' %0111: %1111_0000 baseband + chroma - +'' %1000: %0111_0111 broadcast baseband +'' %1001: %0111_0111 baseband broadcast +'' %1010: %0111_1111 broadcast baseband + chroma +'' %1011: %0111_1111 baseband broadcast + aural +'' %1100: %1111_0111 broadcast + aural baseband +'' %1101: %1111_0111 baseband + chroma broadcast +'' %1110: %1111_1111 broadcast + aural baseband + chroma +'' %1111: %1111_1111 baseband + chroma broadcast + aural +'' ----------------------------------------------------------- +'' active pins top nibble bottom nibble +'' +'' the baseband signal nibble is arranged as: +'' bit 3: chroma signal for s-video (attach via 560-ohm resistor) +'' bits 2..0: baseband video (sum 270/560/1100-ohm resistors to form 75-ohm 1V signal) +'' +'' the broadcast signal nibble is arranged as: +'' bit 3: aural subcarrier (sum 560-ohm resistor into network below) +'' bits 2..0: visual carrier (sum 270/560/1100-ohm resistors to form 75-ohm 1V signal) +'' _______ +'' tv_mode +'' +'' bit 4 selects between 16x16 and 16x32 pixel tiles: +'' 0: 16x16 pixel tiles (tileheight = 16) +'' 1: 16x32 pixel tiles (tileheight = 32) +'' +'' bit 3 controls chroma mixing into broadcast: +'' 0: mix chroma into broadcast (color) +'' 1: strip chroma from broadcast (black/white) +'' +'' bit 2 controls chroma mixing into baseband: +'' 0: mix chroma into baseband (composite color) +'' 1: strip chroma from baseband (black/white or s-video) +'' +'' bit 1 controls interlace: +'' 0: progressive scan (243 display lines for NTSC, 286 for PAL) +'' less flicker, good for motion +'' 1: interlaced scan (486 display lines for NTSC, 572 for PAL) +'' doubles the vertical display lines, good for text +'' +'' bit 0 selects NTSC or PAL format +'' 0: NTSC +'' 3016 horizontal display ticks +'' 243 or 486 (interlaced) vertical display lines +'' CLKFREQ must be at least 14_318_180 (4 * 3_579_545 Hz)* +'' 1: PAL +'' 3692 horizontal display ticks +'' 286 or 572 (interlaced) vertical display lines +'' CLKFREQ must be at least 17_734_472 (4 * 4_433_618 Hz)* +'' +'' * driver will disable itself while CLKFREQ is below requirement +'' _________ +'' tv_screen +'' +'' pointer to words which define screen contents (left-to-right, top-to-bottom) +'' number of words must be tv_ht * tv_vt +'' each word has two bitfields: a 6-bit colorset ptr and a 10-bit pixelgroup ptr +'' bits 15..10: select the colorset* for the associated pixel tile +'' bits 9..0: select the pixelgroup** address %ppppppppppcccc00 (p=address, c=0..15) +'' +'' * colorsets are longs which each define four 8-bit colors +'' +'' ** pixelgroups are longs which define (left-to-right, top-to-bottom) the 2-bit +'' (four color) pixels that make up a 16x16 or a 32x32 pixel tile +'' _________ +'' tv_colors +'' +'' pointer to longs which define colorsets +'' number of longs must be 1..64 +'' each long has four 8-bit fields which define colors for 2-bit (four color) pixels +'' first long's bottom color is also used as the screen background color +'' 8-bit color fields are as follows: +'' bits 7..4: chroma data (0..15 = blue..green..red..)* +'' bit 3: controls chroma modulation (0=off, 1=on) +'' bits 2..0: 3-bit luminance level: +'' values 0..1: reserved for sync - don't use +'' values 2..7: valid luminance range, modulation adds/subtracts 1 (beware of 7) +'' value 0 may be modulated to produce a saturated color toggling between levels 1 and 7 +'' +'' * because of TV's limitations, it doesn't look good when chroma changes abruptly - +'' rather, use luminance - change chroma only against a black or white background for +'' best appearance +'' _____ +'' tv_ht +'' +'' horizontal number pixel tiles - must be at least 1 +'' practical limit is 40 for NTSC, 50 for PAL +'' _____ +'' tv_vt +'' +'' vertical number of pixel tiles - must be at least 1 +'' practical limit is 13 for NTSC, 15 for PAL (26/30 max for interlaced NTSC/PAL) +'' _____ +'' tv_hx +'' +'' horizontal tile expansion factor - must be at least 3 for NTSC, 4 for PAL +'' +'' make sure 16 * tv_ht * tv_hx + ||tv_ho + 32 is less than the horizontal display ticks +'' _____ +'' tv_vx +'' +'' vertical tile expansion factor - must be at least 1 +'' +'' make sure * tv_vt * tv_vx + ||tv_vo + 1 is less than the display lines +'' _____ +'' tv_ho +'' +'' horizontal offset in ticks - pos/neg value (0 for centered image) +'' shifts the display right/left +'' _____ +'' tv_vo +'' +'' vertical offset in lines - pos/neg value (0 for centered image) +'' shifts the display up/down +'' ____________ +'' tv_broadcast +'' +'' broadcast frequency expressed in Hz (ie channel 2 is 55_250_000) +'' if 0, modulator is turned off - saves power +'' +'' broadcasting requires CLKFREQ to be at least 16_000_000 +'' while CLKFREQ is below 16_000_000, modulator will be turned off +'' ___________ +'' tv_auralcog +'' +'' selects cog to supply aural fm signal - 0..7 +'' uses ctra pll output from selected cog +'' +'' in NTSC, the offset frequency must be 4.5MHz and the max bandwidth +-25KHz +'' in PAL, the offset frequency and max bandwidth vary by PAL type + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/source/shoot/bellatrix/_readme_.txt b/source/shoot/bellatrix/_readme_.txt new file mode 100644 index 0000000..3bb0f77 --- /dev/null +++ b/source/shoot/bellatrix/_readme_.txt @@ -0,0 +1,23 @@ +BST Propeller Archive +Created by Brads Spin Tool Compiler v0.15.4-pre5 - Copyright 2008,2009,2010 All rights reserved +Compiled for i386 Win32 at 14:24:31 on 2010/03/10 + +Archive Created at 15:34:27 On 01/05/10 +Included Objects : +shoot1 + | + +--tv + | + +--graphics + | + +--mouse + | + +--yma_hss_v1.2 + +, + - shoot1.spin + - TV.spin + - Graphics.spin + - Mouse.spin + - yma_hss_v1.2.spin +, diff --git a/source/shoot/bellatrix/shoot.spin b/source/shoot/bellatrix/shoot.spin new file mode 100644 index 0000000..05bfb0d --- /dev/null +++ b/source/shoot/bellatrix/shoot.spin @@ -0,0 +1,335 @@ +''*************************************** +''* Shoot Demo * +''* Author: propfan * +''* Copyright (c) 2010 propfan * +''* See end of file for terms of use. * +''*************************************** + +CON + x_tiles = 8 + y_tiles = 12 + x_pixels = x_tiles << 4 + y_pixels = y_tiles << 4 + vram_size = ( x_pixels * y_pixels ) >> 2 '2bpp + + scr_w = x_pixels >> 1 + scr_h = y_pixels >> 1 + + _clkmode = xtal1 + pll16x + _xinfreq = 5_000_000 + _stack = (vram_size + vram_size + 100) >> 2 'accomodate display memory and stack + + paramcount = 14 + display_base = $8000 - vram_size + bitmap_base = display_base - vram_size + + enemies = 5 + bullets = 5 + + +VAR + long tv_status '0/1/2 = off/visible/invisible read-only + long tv_enable '0/? = off/on write-only + long tv_pins '%ppmmm = pins write-only + long tv_mode '%ccinp = chroma,interlace,ntsc/pal,swap write-only + long tv_screen 'pointer to screen (words) write-only + long tv_colors 'pointer to colors (longs) write-only + long tv_hc 'horizontal cells write-only + long tv_vc 'vertical cells write-only + long tv_hx 'horizontal cell expansion write-only + long tv_vx 'vertical cell expansion write-only + long tv_ho 'horizontal offset write-only + long tv_vo 'vertical offset write-only + long tv_broadcast 'broadcast frequency (Hz) write-only + long tv_auralcog 'aural fm cog write-only + + word screen[x_tiles * y_tiles] + long colors[64] + + byte bx[bullets] + byte by[bullets] + byte ex[enemies] + byte ey[enemies] + byte es[enemies] + +OBJ + tv : "tv" + gr : "graphics" + mouse : "mouse" + hss : "yma_hss_hive" + +PUB main + initFunc + repeat + titleFunc + gameMain + + +PRI initFunc | i, dx, dy + longmove(@tv_status, @tvparams, paramcount) + tv_screen := @screen + tv_colors := @colors + + 'init colors + repeat i from 0 to 64 + colors[i] := $00001010 * (i<<1+4) & $F + $0D060D02 + + 'init tile screen + repeat dx from 0 to tv_hc - 1 + repeat dy from 0 to tv_vc - 1 + screen[dy * tv_hc + dx] := display_base >> 6 + dy + dx * tv_vc + ((dy & $3F) << 10) + + 'start services + tv.start(@tv_status) + gr.start + gr.setup(x_tiles, y_tiles, x_pixels >> 1, y_pixels >> 1, bitmap_base) + + mouse.start(19, 18) + hss.start + + 'wait 0.5sec. for stability of video signal + waitcnt( cnt + clkfreq >> 1 ) + + +PRI titleFunc | i,j + + hss.mus1 + + repeat while mouse.button(0) + repeat until mouse.button(0) + + 'exit? + if mouse.button(1) + hss.shoot_exit + + gr.clear + + dispBg + + 'hintergrundgrafiken im banner zeichnen + gr.colorwidth(1, 1) + repeat j from 0 to 5 + gr.vec(j*2, j*5+100-(cnt>>23), 200-j*40, cnt>>16, @vecdef3) + repeat j from 0 to 5 + gr.vec(j*2, j*5+200-(cnt>>23), 200-j*40, cnt>>16, @vecdef2) + repeat j from 0 to 5 + gr.vec(j*2, j*5+300-(cnt>>23), 200-j*40, cnt>>16, @vecdef) + + + gr.colorwidth(2, 4) + gr.textmode( 3, 3, 6, 5 ) + gr.text( 0, 20, @msg_title ) + + if ( ( cnt >> 26 ) & 1 ) + gr.colorwidth(2, 0) + gr.textmode( 1, 1, 6, 5 ) + gr.text( 0,-30, @msg_press ) + + gr.copy(display_base) + + 'wait Vsync + repeat until ( tv_status == 1 ) + + gr.textmode( 1, 1, 6, 0 ) + hss.mus_stop + + +PRI gameMain | i, j, dx, dy, pp, wt, sync, score, mousex, mousey, gameover + +' hss.hmus_load(@bgm) +' hss.hmus_play + hss.mus2 + + mousex := 0 + mousey := -60 + gameover := 0 + + repeat i from 0 to enemies - 1 + es[i] := 0 + + repeat until gameover + gr.clear + + ' music monitor + gr.colorwidth(1, 1) + repeat i from 0 to 3 +' j := hss.peek(3 + i<<3) + j := hss.peek(i) +' gr.plot( j >> 26 - 64, i<<2 + 60 ) + gr.box(i*15-30,20,10,j>>25) + + 'move ship + mousex := mousex + ( mouse.delta_x / 2 ) #> -scr_w + 5 <# scr_w - 5 + mousey := mousey + ( mouse.delta_y / 2 ) #> -scr_h + 5 <# scr_h >> 1 + gr.plot(mousex - 3, mousey - 3) + gr.line(mousex, mousey) + gr.line(mousex + 3, mousey - 3) + + 'shoot bullet + wt-- + if ( wt < 0 ) AND mouse.button(0) + wt := 2 + pp := ( pp + 1 ) // bullets + bx[pp] := mousex + ( ( cnt >> 5 ) & 1 ) + by[pp] := mousey +' hss.sfx_play(2, @SoundFX1) + hss.sfx1 + + ' enemies + gr.colorwidth(3, 1) + repeat i from 0 to enemies - 1 + ey[i]-- + if es[i] == 0 + ex[i] := (-scr_w+15) #> ( ( ( cnt >> 4 ) & 127 ) - 64 ) <# (scr_w-15) + ey[i] := scr_h + es[i] := 40 + ( ( cnt >> 5 ) & 127 ) + gr.vec(~ex[i], ~ey[i], es[i], ~ey[i]*( 100 - es[i] ), @vecdef) + if ~ey[i] < -scr_h + gameover := 1 + + ' bullets + repeat i from 0 to bullets - 1 + if ~by[i] > scr_h + next + by[i] += 12 + gr.colorwidth(1, 2) + gr.plot(~bx[i], ~by[i] - 8) + gr.line(~bx[i], ~by[i] + 8) + repeat j from 0 to enemies - 1 + dx := ||( ~bx[i] - ~ex[j] ) + dy := ||( ~by[i] - ~ey[j] ) + if ( ( dx < es[j]>>2 ) and ( dy < (es[j]>>3 #> 8) ) ) + gr.colorwidth(2,1) + gr.vec(~bx[i], ~by[i], 90, cnt, @vecdef2) + es[j] -= es[j] >> 3 + if ( es[j] > 40 ) + gr.colorwidth(2,4) + gr.vec(~ex[j], ~ey[j], es[j], ~ey[j]*( 100 - es[j] ), @vecdef) + ey[j] := ( ey[j] + 8 ) <# 127 + else + es[j] := 0 + score += 1 +' hss.sfx_stop(1) +' hss.sfx_play(1, @SoundFX2) + hss.sfx2 + by[i] := 120 + + ' show score + j := score + repeat i from 3 to 0 + msg[ i ] := ( j // 10 ) + "0" + j := j / 10 + gr.colorwidth(2, 0) + gr.text( -scr_w+5, scr_h-15, @msg ) + + 'background + dispBg + + 'copy bitmap to display + gr.copy(display_base) + + 'wait Vsync + repeat until ( tv_status == 1 ) + + hss.mus_stop + waitcnt( cnt + clkfreq ) + +PRI dispBg + gr.colorwidth(2,1) + gr.plot(-scr_w, -127) + gr.line(-scr_w, 127) + gr.plot(scr_w-1, -127) + gr.line(scr_w-1, 127) + +DAT +'bgm file "yma-mrboss.hmus" + + +msg byte "0000", 0 +msg_title byte "Shoot", 0 +msg_press byte "Press Button", 0 + +tvparams long 0 'status + long 1 'enable + long %010_0101 'pins + long %0000 'mode + long 0 'screen + long 0 'colors + long x_tiles 'hc + long y_tiles 'vc + long 10 'hx + long 1 'vx + long 0 'ho + long 0 'vo + long 0 'broadcast + long 0 'auralcog + +vecdef word $4000+$2000/3*0 'triangle + word 50 + word $8000+$2000/3*1+1 + word 50 + word $8000+$2000/3*2-1 + word 50 + word $8000+$2000/3*0 + word 50 + word 0 + +vecdef2 word $4000+$2000/12*0 'star + word 50 + word $8000+$2000/12*1 + word 20 + word $8000+$2000/12*2 + word 50 + word $8000+$2000/12*3 + word 20 + word $8000+$2000/12*4 + word 50 + word $8000+$2000/12*5 + word 20 + word $8000+$2000/12*6 + word 50 + word $8000+$2000/12*7 + word 20 + word $8000+$2000/12*8 + word 50 + word $8000+$2000/12*9 + word 20 + word $8000+$2000/12*10 + word 50 + word $8000+$2000/12*11 + word 20 + word $8000+$2000/12*0 + word 50 + word 0 + +vecdef3 word $4000+$2000/4*0 'box + word 50 + word $8000+$2000/4*1 + word 30 + word $8000+$2000/4*2 + word 50 + word $8000+$2000/4*3 + word 30 + word $8000+$2000/4*0 + word 50 + word 0 + + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/source/shoot/bellatrix/yma_hss_hive.spin b/source/shoot/bellatrix/yma_hss_hive.spin new file mode 100644 index 0000000..c4ca7c7 --- /dev/null +++ b/source/shoot/bellatrix/yma_hss_hive.spin @@ -0,0 +1,119 @@ +'' HIVE - Soundadapter zu Regnatix/Administra + + +CON + +'signaldefinitionen bellatrix + +#0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus +#8, BEL_VGABASE 'vga-signale (8pin) +#16, BEL_KEYBC,BEL_KEYBD 'keyboard-signale +#18, BEL_MOUSEC,BEL_MOUSED 'maus-signale +#20, BEL_VIDBASE 'video-signale(3pin) +#23, BEL_SELECT 'belatrix-auswahlsignal +#24, HBEAT 'front-led + BUSCLK 'bustakt + BUS_WR '/wr - schreibsignal + BUS_HS ' '/hs - quittungssignal + +VAR + +byte sndfx ' Kommando für Administra +byte fcCog ' Flag ob cCog gestartet +long cStack[32] ' Stack für cCog +long hsspeek[4] ' Registerwerte Musikplayer + +PUB start: Pass + + Pass := (fcCog := cognew(cCog, @cStack)+1) > 0 + +PUB cCog | cmd,i + + bus_init + repeat + repeat + bus_putchar(0) + repeat i from 0 to 3 + hsspeek[i] := sub_getlong ' soundregister einlesen + until sndfx > 0 'warte bis fx gesendet werden soll + bus_putchar(sndfx~) 'sndfx-Kommando senden und löschen + repeat i from 0 to 3 + hsspeek[i] := sub_getlong ' soundregister einlesen + +CON 'BUS-Routinen +' +' hbeat --------+ +' clk -------+| +' /wr ------+|| +' /hs -----+||| +------------------------- /cs +' |||| | -------- d0..d7 +DB_IN = %00001001_00000000_00000000_00000000 'maske: dbus-eingabe +DB_OUT = %00001001_00000000_00000000_11111111 'maske: dbus-ausgabe + +M1 = %00000010_00000000_00000000_00000000 +M2 = %00000010_10000000_00000000_00000000 'busclk=1? & /cs=0? + +M3 = %00000000_00000000_00000000_00000000 +M4 = %00000010_00000000_00000000_00000000 'busclk=0? + + +PUB bus_putchar(zeichen) 'BUS: Ein Byte ?ber BUS ausgeben +{{ein byte ?ber bus ausgeben Belltrix --> Regnatix}} + waitpeq(M1,M2,0) 'busclk=1? & prop2=0? + dira := db_out 'datenbus auf ausgabe stellen + outa[7..0] := zeichen 'daten ausgeben + outa[bus_hs] := 0 'daten g?ltig + waitpeq(M3,M4,0) 'busclk=0? + dira := db_in 'bus freigeben + outa[bus_hs] := 1 'daten ung?ltig + +PUB bus_getchar : zeichen 'BUS: Ein Byte ?ber BUS empfangen +{{ein byte ?ber bus empfangen Regnatix --> Bellatrix}} + waitpeq(M1,M2,0) 'busclk=1? & prop2=0? + zeichen := ina[7..0] 'daten einlesen + outa[bus_hs] := 0 'daten quittieren + outa[bus_hs] := 1 + waitpeq(M3,M4,0) 'busclk=0? + +PUB bus_init +{{initialisierung des bussystems}} + dira := db_in 'datenbus auf eingabe schalten + outa[bus_hs] := 1 'handshake inaktiv + +PUB sub_getlong:wert 'sub: long empfangen +''funktionsgruppe : sub +''funktion : subprotokoll um einen long-wert von regnatix zu empfangen +''eingabe : - +''ausgabe : 32bit-wert der empfangen wurde +''busprotokoll : [get.byte1][get.byte2][get.byte3][get.byte4] +'' : [ hsb ][ ][ ][ lsb ] + + wert := bus_getchar << 24 '32 bit empfangen hsb/lsb + wert := wert + bus_getchar << 16 + wert := wert + bus_getchar << 8 + wert := wert + bus_getchar + +CON 'Usersounds +PUB mus1 ' intro-musik + sndfx := 1 + +PUB mus2 ' ingame-musik + sndfx := 2 + +PUB sfx1 + sndfx := 3 + +PUB sfx2 + sndfx := 4 + +PUB peek(regnr): wert ' rückgabewert für musikmonitor + wert := hsspeek[regnr] + +PUB mus_stop + sndfx := 5 + +PUB shoot_exit + sndfx := 6 + waitcnt(cnt+clkfreq) + reboot + diff --git a/source/shoot/bellatrix/yma_hss_v1.2.spin b/source/shoot/bellatrix/yma_hss_v1.2.spin new file mode 100644 index 0000000..50d3d79 --- /dev/null +++ b/source/shoot/bellatrix/yma_hss_v1.2.spin @@ -0,0 +1,694 @@ +''***************************** +''* Hydra Sound System v1.2 * +''* (C)2007 Andrew Arsenault * +''***************************** +''http://www.andrewarsenault.com/hss/ +''e-mail: ym2413a@yahoo.com +'' +'' Cogs used: 2 +'' HUB-RAM: ~2.7k + +'' Please visit the website for the latest version, documentation, examples and media files. +'' Thank you! --Ym2413a + +VAR + +'Sound Engine Stack + long hsnd_stack[18] + long cog1, cog2 + +'WavSynth Parameters + long snd_regs[48] 'Regs for Sound Hardware (8x6)+5dpcm + long dpcm_regs[5] + +'DPCM Command Variables + word dpcmreg_ptr + +'Global Hmus Player Vars + word tempo + word song_pc + word song_div + word song_ptr + word chfre[4] + byte chfx[4] + byte chvol[4] + byte hmus_state + byte hmvol + byte fxphs + +'Sound FX Variables + word runlen[2] + word envamp[2] + word sfx_ptr[2] + byte envphs[2] + byte fmcnt[2], fmfreq[2] + byte loadsfx[2] + +CON + +'' Hss Master Control + +PUB start : okay + + stop + okay := cog1 := cognew(@entry, @snd_regs) + 1 + okay := cog2 := cognew(hsound, @hsnd_stack) + 1 + +PUB stop + + if cog1 + cogstop(cog1~ - 1) + if cog2 + cogstop(cog2~ - 1) + +PUB peek(addrptr) : var1 + + var1 := LONG[@snd_regs][addrptr] + +CON + +'' Hydra Music Commands + +PUB hmus_load(songptr) | z + + hmvol := 15 + song_div := 0 + song_ptr := songptr + song_pc := WORD[songptr][8] + tempo := WORD[songptr][12] + repeat z from 0 to 3 + chfx[z] := 0 + +PUB hmus_play + + hmus_state := 1 + +PUB hmus_stop | z + + hmus_state := 0 + repeat z from 0 to 3 + chvol[z] := 0 + +PUB hmus_pause + + hmus_state := 0 + +PUB hmus_tempo(var1) + + tempo := var1 + +PUB get_hmus_tempo : var1 + + var1 := tempo + +PUB hmus_vol(var1) + + hmvol := var1 <# 15 #> 0 + +PUB get_hmus_vol : var1 + + var1 := hmvol + +CON + +'' FXsynth Commands + +PUB sfx_play(chan, soundptr) + + if(chan == 1) + sfx_ptr[0] := soundptr + loadsfx[0] := 0 + if(chan == 2) + sfx_ptr[1] := soundptr + loadsfx[1] := 0 + +PUB sfx_stop(chan) + + if(chan == 1) + sfx_ptr[0] := 0 + if(chan == 2) + sfx_ptr[1] := 0 + +PUB sfx_keyoff(chan) + + if(chan == 1) + envphs[0] := 3 + if(chan == 2) + envphs[1] := 3 + +CON + +'' Hydra DPCM Commands + +PUB dpcm_play(soundptr) + + dpcmreg_ptr := soundptr + +PUB dpcm_stop + + dpcmreg_ptr := 1 + +CON +''***************************** +''* Hss Sound Engine * +''***************************** +PRI Hsound +repeat + 'Update Music Engine + UpdateMus(song_ptr, Hmus_state) 'Update Music Player + VolumeInterpol 'Delay and Interpolate Volume to Remove Pops and Clicks. + + 'Update DPCM Engine + if(dpcmreg_ptr) + DpcmUpdate 'Update the DPCM registers + + 'Update SoundFX Engine + + 'FX channel A + FXSynth(0,32) + 'FX channel B + FXSynth(1, 40) + +PRI VolumeInterpol | z, channelmul, musvar, freqval + + fxphs += 5 + +'Volume Interpolation + repeat z from 0 to 3 step 1 + channelmul := 4+(8*z) + musvar := (chvol[z]*(hmvol+1))&$F0 + snd_regs[channelmul] := (snd_regs[channelmul] & 15)+musvar + + 'Freq Interpolation + channelmul -= 1 'Jump down a REG to Freq + musvar := chfre[z]<<16 + + if(chfx[z] == 0) 'None + snd_regs[channelmul] := musvar + + elseif(chfx[z] < 3) 'Vibrato (light/hard) + if(fxphs < 128) + snd_regs[channelmul] := musvar+(chfre[z]<<(7+chfx[z])) + else + snd_regs[channelmul] := musvar-(chfre[z]<<(7+chfx[z])) + + elseif(chfx[z] == 3) 'Tremolo + if(fxphs < 128) + snd_regs[channelmul] := musvar + else + snd_regs[channelmul] := musvar<<1 + + else 'Portamento + freqval := snd_regs[channelmul]>>16 + if(freqval & $F000 == chfre[z] & $F000) + snd_regs[channelmul] := musvar + elseif(freqval < chfre[z]) + snd_regs[channelmul] := snd_regs[channelmul]+(chfx[z]<<22) + else + snd_regs[channelmul] := snd_regs[channelmul]-(chfx[z]<<22) + +PRI UpdateMus(songptr, state) | channel, channelmul, scrdat, freq, freqoct, flag + + if(state == 0) + return ''Song is not playing. + + song_div++ + + if(song_div => tempo) 'Tempo Divider + song_div := 0 + flag := 0 + + repeat 'Score Decoder and Processor + scrdat := BYTE[song_ptr][song_pc] + channel := scrdat & 3 + channelmul := channel<<3 + song_pc++ + + ''Base Commands + if(scrdat == 0) 'End Row + quit + + if(scrdat == 1) 'Repeat Song + song_pc := WORD[songptr][9] + quit + + if(scrdat == 2) 'End Song + hmus_stop + quit + + if(scrdat == 3) 'Set Flag + flag := 1 + next + + if((scrdat & $3C) == $20) 'Patch HI Note + flag := 2 + scrdat := scrdat>>3 + scrdat += 64+channel + + if(scrdat & 4) 'Change Note + freq := scrdat>>3 + freqoct := freq/12 + freq -= freqoct*12 + case flag + 1 : freqoct += 2 + 2 : freqoct += 6 + other : freqoct += 4 + flag := 0 + snd_regs[4+channelmul] := snd_regs[4+channelmul] & $FE + chfre[channel] := NoteFreqs[freq]>>(6-freqoct) + snd_regs[4+channelmul] := (snd_regs[4+channelmul] & $FE)+1 + next 'Repeat To Next Datum + + if(scrdat & 8) 'Change Evelope / Channel Effect + if(flag) + chfx[channel] := scrdat>>4 + flag := 0 + else + chvol[channel] := scrdat>>4 + next 'Repeat To Next Datum + + if(scrdat & 16) 'Change Instrument + freq := (scrdat & $E0)>>3 + freq += flag<<5 + flag := 0 + snd_regs[0+channelmul] := songptr+WORD[songptr+32][freq] + snd_regs[1+channelmul] := WORD[songptr+32][freq+1] + snd_regs[2+channelmul] := WORD[songptr+32][freq+2] + snd_regs[4+channelmul] := WORD[songptr+32][freq+3] & $0F + next 'Repeat To Next Datum + + if(scrdat & 64) 'Detune + chfre[channel] := chfre[channel]+(chfre[channel]>>8) + + + +PRI DpcmUpdate + + if(dpcmreg_ptr > 15) 'Play Sample. + dpcm_regs[2] := 65535 'End sample if one was playing + dpcm_regs[0] := dpcmreg_ptr+8 + dpcm_regs[4] := 128 + dpcm_regs[3] := LONG[dpcmreg_ptr][1] 'Get sampling rate + dpcm_regs[1] := WORD[dpcmreg_ptr][1] 'Get length + dpcm_regs[2] := 0 'Reset play counter + elseif(dpcmreg_ptr == 1) 'Stop Sample + dpcm_regs[2] := 65535 'End sample + dpcm_regs[4] := 128 + + dpcmreg_ptr := 0 + +PRI FXSynth(SoundVars, ChannelFX) | TimeCnt, SoundFX, Modwav, FMwav, AMwav + TimeCnt := Cnt + SoundFX := sfx_ptr[SoundVars] + + if(loadsfx[SoundVars] == 0) + 'Setup OSC WaveForm + case BYTE[SoundFX][0] + $00: 'Sine + snd_regs[ChannelFX] := @SineTable + snd_regs[1+ChannelFX] := 64 + $01: 'Fast Sine + snd_regs[ChannelFX] := @FastSine + snd_regs[1+ChannelFX] := 32 + $02: 'Sawtooth + snd_regs[ChannelFX] := @Sawtooth + snd_regs[1+ChannelFX] := 64 + $03: 'Square + snd_regs[ChannelFX] := @SqrTable + snd_regs[1+ChannelFX] := 32 + $04: 'Fast Square + snd_regs[ChannelFX] := @FastSqr + snd_regs[1+ChannelFX] := 8 + $05: 'Buzz + snd_regs[ChannelFX] := @NoteFreqs + snd_regs[1+ChannelFX] := 24 + $06: 'Noise + snd_regs[ChannelFX] := $F002 + snd_regs[1+ChannelFX] := 3000 + + snd_regs[2+ChannelFX] := 0 + snd_regs[4+ChannelFX] := $01 + + loadsfx[SoundVars] := 1 + runlen[SoundVars] := 0 + fmcnt[SoundVars] := 0 + fmfreq[SoundVars] := 0 + envamp[SoundVars] := 0 + envphs[SoundVars] := 0 + +''Modulation Code + fmfreq[SoundVars]++ + if(fmfreq[SoundVars] => BYTE[SoundFX][4]) + fmfreq[SoundVars] := 0 + fmcnt[SoundVars]++ + fmcnt[SoundVars] := fmcnt[SoundVars] & $3F + + case BYTE[SoundFX][5] + $00: + Modwav := BYTE[@SineTable][fmcnt[SoundVars]] + $01: + Modwav := BYTE[@FastSine][fmcnt[SoundVars] & 31] + $02: + Modwav := fmcnt[SoundVars]<<2 + $03: + Modwav := !fmcnt[SoundVars]<<2 + $04: + if(fmcnt[SoundVars] & 8) + Modwav := $ff + else + Modwav := $00 + $05: + Modwav := BYTE[$F002][fmcnt[SoundVars]] + $FF: + Modwav := BYTE[SoundFX+12][fmcnt[SoundVars] & 15] + + fmwav := Modwav/(BYTE[SoundFX][6]) 'FM amount + amwav := 256-(Modwav/(BYTE[SoundFX][7])) 'AM amount + amwav := (BYTE[SoundFX][3]*amwav)>>8 + +''Envelope Generator + if(envphs[SoundVars] == 0) 'Attack + envamp[SoundVars] += BYTE[SoundFX][8] + if(envamp[SoundVars] > 8191) + envamp[SoundVars] := 8191 + envphs[SoundVars] := 1 + if(BYTE[SoundFX][8] == $ff) + envamp[SoundVars] := 8191 + if(envphs[SoundVars] == 1) 'Decay + envamp[SoundVars] -= BYTE[SoundFX][9] + if(envamp[SoundVars] & $8000) + envphs[SoundVars] := 2 + if(envamp[SoundVars] =< (BYTE[SoundFX][10]<<5)) + envphs[SoundVars] := 2 + if(envphs[SoundVars] == 2) 'Sustain + envamp[SoundVars] := (BYTE[SoundFX][10]<<5) + if(envphs[SoundVars] == 3) 'Release + envamp[SoundVars] -= BYTE[SoundFX][11] + if(envamp[SoundVars] & $8000) + envamp[SoundVars] := 4 + + amwav := ((envamp[SoundVars]>>9)*(amwav+1))>>4 + +''Run Length and Outputing + if(SoundFX > 15) + runlen[SoundVars]++ + snd_regs[3+ChannelFX] := (BYTE[SoundFX][2]+fmwav)<<24 'Update Frequency + snd_regs[4+ChannelFX] := (amwav<<4)+(snd_regs[4+ChannelFX] & $0F) 'Update Amplitude + else + snd_regs[4+ChannelFX] := $00 'Mute + + if(BYTE[SoundFX][1] == $ff) '$ff = never stop + runlen[SoundVars] := 0 + + if(runlen[SoundVars] > (BYTE[SoundFX][1]<<5)) 'Duration KeyOff + envphs[SoundVars] := 3 + +WaitCnt(TimeCnt + 52_000) ''Delay for Synth Engine Update. + +DAT + +SineTable byte $80, $8c, $98, $a5, $b0, $bc, $c6, $d0 + byte $da, $e2, $ea, $f0, $f5, $fa, $fd, $fe + byte $ff, $fe, $fd, $fa, $f5, $f0, $ea, $e2 + byte $da, $d0, $c6, $bc, $b0, $a5, $98, $8c + byte $80, $73, $67, $5a, $4f, $43, $39, $2f + byte $25, $1d, $15, $0f, $0a, $05, $02, $01 + byte $00, $01, $02, $05, $0a, $0f, $15, $1d + byte $25, $2f, $39, $43, $4f, $5a, $67, $73 + +Sawtooth byte $ff, $fb, $f7, $f3, $ef, $eb, $e7, $e3 + byte $df, $db, $d7, $d3, $cf, $cb, $c7, $c3 + byte $bf, $bb, $b7, $b3, $af, $ab, $a7, $a3 + byte $9f, $9b, $97, $93, $8f, $8b, $87, $83 + byte $80, $7c, $78, $74, $70, $6c, $68, $64 + byte $60, $5c, $58, $54, $50, $4c, $48, $44 + byte $40, $3c, $38, $34, $30, $2c, $28, $24 + byte $20, $1c, $18, $14, $10, $0c, $08, $04 + +FastSine byte $80, $98, $b0, $c6, $da, $ea, $f5, $fd + byte $ff, $fd, $f5, $ea, $da, $c6, $b0, $98 + byte $80, $67, $4f, $39, $25, $15, $0a, $02 + byte $00, $02, $0a, $15, $25, $39, $4f, $67 + +SqrTable byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff + byte $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff + byte $00, $00, $00, $00, $00, $00, $00, $00 + byte $00, $00, $00, $00, $00, $00, $00, $00 + +FastSqr byte $ff, $ff, $ff, $ff, $00, $00, $00, $00 + +'Note LookupTable. +NoteFreqs word $85F3, $8DEA, $965B, $9F4B, $A8C4, $B2CD, $BD6F, $C8B3, $D4A2, $E147, $EEAC, $FCDE 'Top Octave Lookup + +CON +''***************************** +''* WaveTable Synth v1.2 * +''* DPCM Synth v1.1 * +''* (C)2006 Andrew Arsenault * +''***************************** +DAT + org +entry mov dira,Port_Pins 'Setup output pins + + mov ctra,Right_ctra 'Setup Right Audio Channel + mov ctrb,Left_ctra 'Setup Left Audio Channel + + mov ChlA_wave,#256 'Set channel signals. + mov ChlA_offset,#0 'Set channel's offset. + mov ChlA_counter,#0 + + mov Time,#10 + add Time,cnt 'Prepare for asm type WAITCNT loop. + +'MAIN LOOP +update waitcnt Time,Timing_delay 'Wait for CNT = D, then add S into D + + 'Transfer Sound Registers + mov addrregs,par + mov y,NumberOfChannels + + 'Fetch Channel's Registers +transferchl rdlong ChlAp_sampptr,addrregs + add addrregs,#4 + rdlong ChlAp_sampend,addrregs + add addrregs,#4 + rdlong Ch1Ap_samplpp,addrregs + add addrregs,#4 + rdlong Ch1Ap_freq,addrregs + add addrregs,#4 + rdlong ChlAp_keyon,addrregs + + 'Fetch Channel's Static Variables + add addrregs,#8 + rdlong ChlA_offset,addrregs + add addrregs,#4 + rdlong ChlA_counter,addrregs + + 'Run Synth Engine on Channel + call #wvsynth + + 'Store Channel's Static Variables (Tucked Center X move to Wave) + wrlong ChlA_counter,addrregs + sub addrregs,#4 + sub x,#256 + wrlong ChlA_offset,addrregs + sub addrregs,#4 + mov ChlA_wave,x 'Doesn't Waste anything doing this. + wrlong ChlA_wave,addrregs + add addrregs,#12 + + 'Loop Until All Channel's Are Done. + djnz y,#transferchl + + 'Run DPCM Engine + call #dpcm + + 'Mix Channels Together + mov addrregs,par + mov ChlA_wave,#0 + add addrregs,#5*4 + mov y,NumberOfChannels + +mixchls rdlong x,addrregs + add ChlA_wave,x + add addrregs,#8*4 + djnz y,#mixchls + + mov x,DPCM_wave 'Add DPCM + shl x,#2 + add ChlA_wave,x + + shl ChlA_wave,#20 'Convert 12bit singal into a 32bit one. + + 'Update output Channels then repeat again. + mov frqa,ChlA_wave + mov frqb,ChlA_wave + + jmp #update + + + + +'-------------------------Dpcm Engine-------------------------' + +dpcm mov addrregs,par + add addrregs,#192 + + rdlong DPCM_address,addrregs 'Start Address + add addrregs,#4 + rdlong DPCM_runlen,addrregs 'File Lenght + add addrregs,#4 + rdlong DPCM_offset,addrregs 'File Offset + add addrregs,#4 + rdlong DPCM_freq,addrregs 'Playback Speed + add addrregs,#4 + rdlong DPCM_wave,addrregs 'Waveform Amp + + 'Check for if keyon/length is set. + cmp DPCM_offset,DPCM_runlen wc + if_ae jmp #mute_dpcm 'End of file + + 'Freq Timer/Divider and Increase sampling offset + add DPCM_counter,DPCM_freq wc + if_nc jmp #done_dpcm + + 'Decode DPCM + add DPCM_address,DPCM_offset + rdbyte x,DPCM_address 'Fetch Datum + + mov DPCM_delta,x + shr DPCM_delta,#6 + mov y,#1 + shl y,DPCM_delta + mov DPCM_delta,y + + mov y,#1 + shl y,DPCM_phs + test x,y wc + if_c add DPCM_wave,DPCM_delta + if_nc sub DPCM_wave,DPCM_delta + + add DPCM_phs,#1 + cmp DPCM_phs,#6 wc + if_b jmp #done_dpcm + + mov DPCM_phs,#0 + add DPCM_offset,#1 + jmp #done_dpcm + +mute_dpcm mov DPCM_wave, #128 + +done_dpcm mov addrregs,par + add addrregs,#200 + wrlong DPCM_offset,addrregs 'File Offset + add addrregs,#8 + wrlong DPCM_wave,addrregs 'Wave +dpcm_ret ret + +'-----------------------Dpcm Engine End-----------------------' + + + +'-------------------------Sound Engine-------------------------' + + 'Freq Timer/Divider and Increase sampling offset +wvsynth add ChlA_counter,Ch1Ap_freq wc + if_c add ChlA_offset,#1 + + 'Reset sample position and lock at zero if Keyoff. + test ChlAp_keyon,#%0001 wc + if_nc mov ChlA_offset,#0 + + 'Reset(loop) if needed + cmp ChlA_offset,ChlAp_sampend wc + if_ae mov ChlA_offset,Ch1Ap_samplpp + + 'Check BitRate and Set Offset + mov x,ChlA_offset + test ChlAp_keyon,#%0010 wc + if_c shr x,#1 + + 'Fetch WaveTable + mov ChlA_wave,ChlAp_sampptr + add ChlA_wave,x + rdbyte ChlA_wave,ChlA_wave + + 'Check BitRate and Skip if 8bit + test ChlAp_keyon,#%0010 wc + if_nc jmp #skip_4bitsam + + 'Convert 4bit to 8bit + test ChlA_offset,#%0001 wc + if_c shr ChlA_wave,#4 + if_nc and ChlA_wave,#%00001111 + + mov x,ChlA_wave + shl ChlA_wave,#4 + add ChlA_wave,x + + 'Center Amplitude and mute if Keyoff. +skip_4bitsam test ChlAp_keyon,#%0001 wc + if_nc mov ChlA_wave,#128 + + 'Volume Multiply + mov x,#0 + test ChlAp_keyon,#%10000000 wc + if_c add x,ChlA_wave + if_nc add x,#128 + + shr ChlA_wave,#1 + test ChlAp_keyon,#%01000000 wc + if_c add x,ChlA_wave + if_nc add x,#64 + add x,#64 + + shr ChlA_wave,#1 + test ChlAp_keyon,#%00100000 wc + if_c add x,ChlA_wave + if_nc add x,#32 + add x,#96 + + shr ChlA_wave,#1 + test ChlAp_keyon,#%00010000 wc + if_c add x,ChlA_wave + if_nc add x,#16 + add x,#112 + +'Return Audio as X. +wvsynth_ret ret + +'-----------------------Sound Engine End-----------------------' + +Port_Pins long %00000000_00000000_00001100_00000000 + + '- CTR PLL -------- BPIN --- APIN +Right_ctra long %0_00110_000_00000000_000000_000_001010 +Left_ctra long %0_00110_000_00000000_000000_000_001011 + +Timing_delay long 2500 'Sampling Rate = 32,000.00hz +NumberOfChannels long 6 + +Time res 1 +addrregs res 1 +x res 1 +y res 1 + +'WaveTable Synth Accumulators +ChlA_wave res 1 +ChlA_offset res 1 +ChlA_counter res 1 +ChlAp_sampptr res 1 +ChlAp_sampend res 1 +Ch1Ap_samplpp res 1 +Ch1Ap_freq res 1 +ChlAp_keyon res 1 + +'DPCM Accumulators +DPCM_wave res 1 +DPCM_address res 1 +DPCM_offset res 1 +DPCM_counter res 1 +DPCM_freq res 1 +DPCM_runlen res 1 +DPCM_phs res 1 +DPCM_delta res 1 \ No newline at end of file diff --git a/source/shoot/musik/game.hss b/source/shoot/musik/game.hss new file mode 100644 index 0000000..6f56d22 Binary files /dev/null and b/source/shoot/musik/game.hss differ diff --git a/source/shoot/musik/menu.hss b/source/shoot/musik/menu.hss new file mode 100644 index 0000000..4c8d9d5 Binary files /dev/null and b/source/shoot/musik/menu.hss differ diff --git a/source/shoot/regnatix/shoot.spin b/source/shoot/regnatix/shoot.spin new file mode 100644 index 0000000..6d3a6ec --- /dev/null +++ b/source/shoot/regnatix/shoot.spin @@ -0,0 +1,169 @@ + +''*************************************** +''* Shoot Demo * +''* Author: propfan * +''* Copyright (c) 2010 propfan * +''* See end of file for terms of use. * +''*************************************** + +{{ Hive-Computer-Projekt: Shoot - Hive-Version + + http://hive-project.de + +Basierend auf einem Demo von propfan: + + http://propfan.wordpress.com/ + +Anpassung für den Hive: + +26-06-2010-dr235 - Anpassung und einige kleine Verbesserungen + +Der Originalcode von Propfan läuft wie die meisten Demos auf nur einem Prop +(Demoboard), aber ohne Hintergrundmusik. Ich vermute (hab es nicht überprüft), +dass auf einem Prop nicht genug Hubram frei ist, um noch die Musik zu laden. + +Auf dem Hive natürlich kein Problem: Sound wird über Regnatix angesteuert. Im +Gegensatz zu Boulder Dash, habe ich die Verbindung hier bidirektional ausgeführt: +Bei jeder Operation werden nicht nur Soundkommandos von Bellatrix zum HSS übertragen, +sondern auch Soundinfos vom HSS zu Bella. Diese Werte werden für den Sound- +monitor im Hintergrund des Gamescreens benötigt. + +Ansonsten ist das Minigame nicht sehr komplex - der Name verpflichtet ;) - aber ein +tolles Demo um mit Sound und Grafik zu experimentieren. + +Zeitaufwand der Anpassung: ca. 4 Stunden + +Viel Spaß + +drohne235 + + +}} + + +OBJ + ios : "reg-ios" +' debugx : "pterm" 'debug + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +CON + + +VAR + +byte parastr[64] + +PUB main | i + +'initialisierung + ios.start 'ios initialisieren +' ios.startram 'code für test im ram, sollte bei bin-datei auskommentiert werden + +' debugx.start(115200) + +'sfx-slots setzen + ios.sfx_setslot(@col1, 1) 'sound für explosion + ios.sfx_setslot(@phaser1, 2) 'sound für kanone + + ios.sddmact(ios#DM_USER) 'wieder in userverzeichnis wechseln + ios.print(string("Shoot - Loading...")) + +'bellatrix-code laden + ios.belload(@beln) 'bellatrix-code laden + ios.sddmact(ios#DM_USER) + +'soundadapter + + repeat + case ios.bus_getchar2 'soundkommando einlesen + + 1: ios.hss_playfile(@men) 'musik titelscreen ein + 2: ios.hss_playfile(@bgm) 'musik ingame ein + 3: ios.sfx_fire(2,1) 'explosion + 4: ios.sfx_stop(2) 'phaser + ios.sfx_fire(1,2) + 5: ios.hss_stop 'musik aus + 6: ios.hss_stop + ios.stop 'programm beenden + repeat + + repeat i from 0 to 3 'hss-register übertragen + ios.bus_putlong2(ios.hss_peek(3 + i<<3)) + +DAT + +beln byte "shoot.bel",0 ' bella-code +bgm byte "game.hss",0 ' hintergrundmusi +men byte "menu.hss",0 ' menümusi + +phaser0 +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $06,$03,$80,$0F,$08,$04,$05,$00,$FF,$40,$50,$11 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + +phaser1 +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $01,$04,$10,$0F,$00,$03,$01,$00,$FF,$01,$50,$11 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + +phaser2 +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $01,$04,$88,$0F,$00,$01,$01,$00,$FF,$01,$50,$11 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + +phaser3 +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $01,$04,$88,$0F,$00,$02,$01,$00,$FF,$01,$50,$11 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + +col1 +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $01,$04,$10,$0F,$88,$03,$01,$00,$FF,$01,$50,$11 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + +col2 +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $01,$04,$88,$0F,$00,$05,$01,$00,$FF,$01,$50,$66 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + +col3 +' Wav Len Fre Vol LFO LFW FMa AMa Att Dec Sus Rel +byte $01,$02,$55,$0F,$03,$03,$FF,$FF,$FF,$01,$50,$11 +byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01 + + + + 'Wav 'Len 'Fre 'Vol 'LFO 'LFW 'FMa 'AMa +SoundFX1 byte $06, $FF, $80, $04, $00, $00, $40, $00 + 'Att 'Dec 'Sus 'Rel + byte $F0, $80, $00, $FF + + 'Wav 'Len 'Fre 'Vol 'LFO 'LFW 'FMa 'AMa +SoundFX2 byte $05, $FF, $00, $0F, $04, $FF, $01, $05 + 'Att 'Dec 'Sus 'Rel + byte $F1, $24, $00, $FF + '16step Sequencer Table + byte $F1, $78, $3C, $00, $00, $00, $F1, $78, $3C, $00, $00, $00, $00, $00, $00, $00 + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/source/stracker/bellatrix/Corner_BottomLeft.dat b/source/stracker/bellatrix/Corner_BottomLeft.dat new file mode 100644 index 0000000..5941fa4 Binary files /dev/null and b/source/stracker/bellatrix/Corner_BottomLeft.dat differ diff --git a/source/stracker/bellatrix/Corner_topleft.dat b/source/stracker/bellatrix/Corner_topleft.dat new file mode 100644 index 0000000..0fdf59f Binary files /dev/null and b/source/stracker/bellatrix/Corner_topleft.dat differ diff --git a/source/stracker/bellatrix/Corner_topright.dat b/source/stracker/bellatrix/Corner_topright.dat new file mode 100644 index 0000000..cb56785 Binary files /dev/null and b/source/stracker/bellatrix/Corner_topright.dat differ diff --git a/source/stracker/bellatrix/HV_Break.dat b/source/stracker/bellatrix/HV_Break.dat new file mode 100644 index 0000000..ccdfe3b --- /dev/null +++ b/source/stracker/bellatrix/HV_Break.dat @@ -0,0 +1,2 @@ +______________ + diff --git a/source/stracker/bellatrix/HV_Break2.dat b/source/stracker/bellatrix/HV_Break2.dat new file mode 100644 index 0000000..53f8c70 --- /dev/null +++ b/source/stracker/bellatrix/HV_Break2.dat @@ -0,0 +1,3 @@ + + +UUUUUU \ No newline at end of file diff --git a/source/stracker/bellatrix/endcap_Med_left.dat b/source/stracker/bellatrix/endcap_Med_left.dat new file mode 100644 index 0000000..524d651 --- /dev/null +++ b/source/stracker/bellatrix/endcap_Med_left.dat @@ -0,0 +1 @@ +UUUUUUU \ No newline at end of file diff --git a/source/stracker/bellatrix/endcap_Med_right.dat b/source/stracker/bellatrix/endcap_Med_right.dat new file mode 100644 index 0000000..81b7eaa --- /dev/null +++ b/source/stracker/bellatrix/endcap_Med_right.dat @@ -0,0 +1 @@ +WUUUUWU_UU/++ \ No newline at end of file diff --git a/source/stracker/bellatrix/endcap_Small_left.dat b/source/stracker/bellatrix/endcap_Small_left.dat new file mode 100644 index 0000000..7c14573 Binary files /dev/null and b/source/stracker/bellatrix/endcap_Small_left.dat differ diff --git a/source/stracker/bellatrix/endcap_Small_right.dat b/source/stracker/bellatrix/endcap_Small_right.dat new file mode 100644 index 0000000..66db08d --- /dev/null +++ b/source/stracker/bellatrix/endcap_Small_right.dat @@ -0,0 +1,4 @@ +UU_UUW_ + + +**** \ No newline at end of file diff --git a/source/stracker/bellatrix/filled_space.dat b/source/stracker/bellatrix/filled_space.dat new file mode 100644 index 0000000..85f2b75 --- /dev/null +++ b/source/stracker/bellatrix/filled_space.dat @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/stracker/bellatrix/font_29p5.dat b/source/stracker/bellatrix/font_29p5.dat new file mode 100644 index 0000000..13c2f85 Binary files /dev/null and b/source/stracker/bellatrix/font_29p5.dat differ diff --git a/source/stracker/bellatrix/stint.spin b/source/stracker/bellatrix/stint.spin new file mode 100644 index 0000000..3a9c39c --- /dev/null +++ b/source/stracker/bellatrix/stint.spin @@ -0,0 +1,736 @@ +''LCARS tryout in XGA * +'Trying to emulate look of this page: http://www.lcarscom.net/databank.htm +'Copyright 2008 Raymond Allen + +{{ --------------------------------------------------------------------------------------------------------- + +Hive-Computer-Projekt + +Name : StarTracker +Chip : Bellatrix-Code (soundplayer) +Version : 0.1 +Dateien : stint.spin + +Beschreibung : Grafiktreiber f?r StarTracker + +Eigenschaften : + +Logbuch : + +Kommandoliste: + +0 1 Tastaturstatus abfragen +0 2 Tastaturzeichen holen +0 3 n Screensteuerzeichen +0 3 0 CLS +0 3 1 Home +0 3 2 Backspace +0 3 3 TAB +0 3 4 n SETCUR Cursorzeichen auf n setzen +0 3 5 POS1 +0 3 6 x SETX +0 3 7 y SETY +0 3 8 (x) GETX +0 3 9 (y) GETY +0 3 10 c SETCOL +0 3 11 n SLINE +0 3 13 SCREENINIT +0 3 14 CURON +0 3 15 CUROFF +0 99 Reboot und neuen Treiber laden +0 100 testfunktion + +1..255 Zeichenausgabe + + + --------------------------------------------------------------------------------------------------------- }} + + +CON + + _clkmode = xtal1 + pll16x + _xinfreq = 5_000_000 + + 'number of custom 16x16 characters + nuchars = (6*3+1*7+47+23*2+20*5) '!!!!! you must have the correct # here for alignment later + +'signaldefinitionen regnatix + +#0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus +#8, BEL_VGABASE 'vga-signale (8pin) +#16, BEL_KEYBC,BEL_KEYBD 'keyboard-signale +#18, BEL_MOUSEC,BEL_MOUSED 'maus-signale +#20, BEL_VIDBASE 'video-signale(3pin) +#23, BEL_SELECT 'belatrix-auswahlsignal +#24, HBEAT 'front-led + BUSCLK 'bustakt + BUS_WR '/wr - schreibsignal + BUS_HS ' '/hs - quittungssignal + +COLS = 64 +ROWS = 48 +TILES = cols * rows + +TAB1 = 16 +TAB2 = 32 +TAB3 = 48 +SPACETILE = $8000 + $20 << 6 + +VGA_BASPORT = 8 'vga startport +VGA_RESX = COLS * 16 'vga anzahl pixel x +VGA_RESY = ROWS * 16 'vga anzahl pixel y +KEYB_DPORT = BEL_KEYBD 'tastatur datenport +KEYB_CPORT = BEL_KEYBC 'tastatur taktport +MOUSE_DPORT = BEL_MOUSED +MOUSE_CPORT = BEL_MOUSEC +CURSORCHAR = $0E 'cursorzeichen + +DB_WAIT = %00000001_00000000_00000000_00000000 'dira-wert f?r wait-status am bus +CNT_HBEAT = 5_000_0000 'blinkgeschw. front-led + +' hbeat --------+ +' clk -------+| +' /wr ------+|| +' /hs -----+||| +------------------------- /cs +' |||| | -------- d0..d7 +DB_IN = %00001001_00000000_00000000_00000000 'maske: dbus-eingabe +DB_OUT = %00001001_00000000_00000000_11111111 'maske: dbus-ausgabe + +M1 = %00000010_00000000_00000000_00000000 +M2 = %00000010_10000000_00000000_00000000 'busclk=1? & /cs=0? + +M3 = %00000000_00000000_00000000_00000000 +M4 = %00000010_00000000_00000000_00000000 'busclk=0? + +VAR + + 'variables for display + long col, row, color, flag + long array[tiles/2] + long stackhb[9] 'stack f?r hbeat-cog + byte cursor 'cursorzeichen + byte curstat 'cursorstatus 1 = ein + byte sline 'startzeile des scrollfensters + byte eline 'endzeile des scrollfensters + + 'for custom characters + word user_charbase + + 'for drawing buttons + word ptr + byte boxcolor + byte sBuffer[32] 'stingpuffer + + +OBJ + + vga : "bel-vga" + keyb : "bel-keyb" + + +PUB main | zeichen +{{interpreter f?r hostdialog}} + + init_subsysteme 'bus/vga/keyboard/maus initialisieren + repeat + zeichen := bus_getchar '1. zeichen empfangen + if zeichen > 0 + print_char(zeichen) + else + zeichen := bus_getchar '2. zeichen kommando empfange + case zeichen + 1: bus_putchar(keyb.gotkey) '1: Tastaturstatus senden + 2: bus_putchar(keyb.key) '2: Tastaturzeichen senden + 3: zeichen := bus_getchar '3: Sonderzeichen von $100 bis $1FF ausgeben + print_ctrl(zeichen) + 6: pchar(bus_getchar) '6: zeichen ohne steuerzeichen augeben + + 10: cmd_bitmap1 + 11: cmd_fillbox + 12: cmd_drawtxt + 13: cmd_printchan + 99: reboot '99: bellatrix neu starten + 100: gfx1 + +PUB gfx1 + +PUB cmd_bitmap1 | nBitmap,pBitmap,xPos,yPos,xSize,ySize,clr +'Bitmap1Bit(@endcap_med_left,1,1,1,2,1) +'Bitmap1Bit(pBitmap, xPos, yPos, xSize, ySize, clr) + nBitmap := bus_getchar + xPos := bus_getchar + yPos := bus_getchar + xSize := bus_getchar + ySize := bus_getchar + clr := bus_getchar + case nBitmap + 0: pBitmap := @title + 1: pBitmap := @footer + 2: pBitmap := @button1 + 3: pBitmap := @button2 + 4: pBitmap := @button3 + 5: pBitmap := @button4 + 6: pBitmap := @button5 + 7: pBitmap := @button6 + 8: pBitmap := @button7 + 9: pBitmap := @button8 + 10: pBitmap := @button9 + 11: pBitmap := @corner_topleft + 12: pBitmap := @corner_topright + 13: pBitmap := @corner_bottomLeft + 14: pBitmap := @endcap_med_left + 15: pBitmap := @endcap_med_right + 16: pBitmap := @endcap_small_left + 17: pBitmap := @endcap_small_right + Bitmap1Bit(pBitmap, xPos, yPos, xSize, ySize, clr) + + +PUB cmd_fillbox | left,top,width,height,clr,bBottomBreak,bRightBreak,bTrimRight +'FillBlock(3,1,35,2,3,false,false,false) +'FillBlock(left,top,width,height,clr,bBottomBreak,bRightBreak,bTrimRight) + left := bus_getchar + top := bus_getchar + width := bus_getchar + height := bus_getchar + clr := bus_getchar + bBottomBreak := bus_getchar + bRightBreak := bus_getchar + bTrimRight := bus_getchar + FillBlock(left,top,width,height,clr,bBottomBreak,bRightBreak,bTrimRight) + +PUB cmd_drawtxt | nButton,pButton,nLen,c,i +'DrawText(@button,@string,bInvert) + nButton := bus_getchar + nLen := bus_getchar + repeat i from 0 to nLen - 1 + c := bus_getchar + sBuffer[i] := c + sBuffer[i+1] := 0 + case nButton + 0: pButton := @title + 1: pButton := @footer + 2: pButton := @button1 + 3: pButton := @button2 + 4: pButton := @button3 + 5: pButton := @button4 + 6: pButton := @button5 + 7: pButton := @button6 + 8: pButton := @button7 + 9: pButton := @button8 + 10: pButton := @button9 + DrawText(pButton, @sBuffer,false) + +PRI cmd_printchan | x,y,note,okt,vol,fx,ins + x := bus_getchar + y := bus_getchar + note := bus_getchar + okt := bus_getchar + vol := bus_getchar + fx := bus_getchar + ins := bus_getchar + + 'cursor setzen + col := x + row := y * 2 + sline + + 'note ausgeben + color := 5 + case note + 0: printq_str(string("▶ ")) + 1: printq_str(string("C ")) + 2: printq_str(string("C• ")) + 3: printq_str(string("D ")) + 4: printq_str(string("D• ")) + 5: printq_str(string("E ")) + 6: printq_str(string("F ")) + 7: printq_str(string("F• ")) + 8: printq_str(string("G ")) + 9: printq_str(string("G• ")) + 10: printq_str(string("A ")) + 11: printq_str(string("A• ")) + 12: printq_str(string("H ")) + + '-------------------------------------------------- oktave + color := 0 + if okt + printhex(okt,1) + else + print_char("-") + print_char(" ") + + '-------------------------------------------------- volume + color := 1 + if vol + printhex(vol,1) + else + print_char("-") + print_char(" ") + + '-------------------------------------------------- effekt + color := 2 + if fx + printhex(fx,1) + else + print_char("-") + print_char(" ") + + '-------------------------------------------------- instrument + color := 3 + if ins + printhex(ins,1) + else + print_char("-") + print_char(" ") + +PUB init_subsysteme +{{initialisierung des belatrix-chips}} + cognew(led_hbeat, @stackhb) 'heartbeat aktivieren + bus_init 'bussignale initialisieren + + '64 byte align the user characters + user_charbase := @uchar & $FFC0 'destination + 'user_charbase_offset := user_charbase-@uchar + longmove(user_charbase,@uchar,16*nuchars) + + keyb.start(keyb_dport, keyb_cport) 'tastaturport starten + vga.start(vga_basport, @array, @vgacolors, 0,0,0) 'vga-treiber starten + + print_char($100) 'bildschirm l?schen + cursor := CURSORCHAR 'cursorzeichen setzen + curstat := 1 'cursor anschalten + sline := 2 + eline := rows + +PUB bus_init +{{initialisierung des bussystems}} + dira := db_in 'datenbus auf eingabe schalten + outa[bus_hs] := 1 'handshake inaktiv + +PUB bus_putchar(zeichen) 'chip: ein byte an regnatix senden +''funktionsgruppe : chip +''funktion : ein byte an regnatix senden +''eingabe : byte +''ausgabe : - + + waitpeq(M1,M2,0) 'busclk=1? & prop2=0? + dira := db_out 'datenbus auf ausgabe stellen + outa[7..0] := zeichen 'daten ausgeben + outa[bus_hs] := 0 'daten gültig + waitpeq(M3,M4,0) 'busclk=0? + dira := db_in 'bus freigeben + outa[bus_hs] := 1 'daten ungültig + +PUB bus_getchar : zeichen 'chip: ein byte von regnatix empfangen +''funktionsgruppe : chip +''funktion : ein byte von regnatix empfangen +''eingabe : - +''ausgabe : byte + + waitpeq(M1,M2,0) 'busclk=1? & prop2=0? + zeichen := ina[7..0] 'daten einlesen + outa[bus_hs] := 0 'daten quittieren + waitpeq(M3,M4,0) 'busclk=0? + outa[bus_hs] := 1 + + +PUB led_hbeat +{{led_hbeat - herzschlag f?r front-led}} + dira := db_in + repeat + !outa[hbeat] + waitcnt(cnt_hbeat + cnt) + +PUB print_str(strptr) +{{zeichenkette auf bildschirm ausgeben}} + repeat while byte[strptr] + print_char(byte[strptr++]) + +PUB printq_str(strptr) +{{zeichenkette auf bildschirm ausgeben}} + repeat while byte[strptr] + pchar(byte[strptr++]) + +PUB printhex(value, digits) 'screen: hexadezimalen zahlenwert auf bildschirm ausgeben +{{hex(value,digits) - screen: hexadezimale bildschirmausgabe eines zahlenwertes}} + value <<= (8 - digits) << 2 + repeat digits + print_char(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) + +PUB print_char(c) | code,n +{{zeichen auf bildschirm ausgeben}} + + case c + $01: 'clear screen? + if curstat == 1 + schar($20) + n := sline * cols * 2 + wordfill(@array + n, spacetile, tiles - n) + row := sline + col := 0 + if curstat == 1 + schar(cursor) + $02: 'home? + row := sline + col := 0 + $03: 'pos1 + if curstat == 1 + schar($20) + col := 0 + if curstat == 1 + schar(cursor) + $04: 'curon + curstat := 1 + schar(cursor) + $05: 'curoff + if curstat == 1 + schar($20) + curstat := 0 + $06: 'scrollup + scrollup + $07: 'scrolldown + $08: 'backspace? + if col + if curstat == 1 + schar($20) + col-- + if curstat == 1 + schar(cursor) + $09: 'tab + if col < TAB1 + if curstat == 1 + schar($20) + col := TAB1 + if curstat == 1 + schar(cursor) + return + if col < TAB2 + if curstat == 1 + schar($20) + col := TAB2 + if curstat == 1 + schar(cursor) + return + if col < TAB3 + if curstat == 1 + schar($20) + col := TAB3 + if curstat == 1 + schar(cursor) + return + $0A: 'LF ausblenden + return + $0D: 'return? + if curstat == 1 + schar($20) + newline + if curstat == 1 + schar(cursor) + $0E..$FF: + pchar(c) + if curstat == 1 + schar(cursor) + +PUB print_ctrl(c) | code,n,m 'screen: steuerzeichen ausgeben + + case c + $01: 'setcur + code := bus_getchar + cursor := code + if curstat == 1 + schar(code) + $02: 'setx + if curstat == 1 + schar($20) + col := bus_getchar + if curstat == 1 + schar(cursor) + $03: 'sety + if curstat == 1 + schar($20) + row := bus_getchar * 2 + sline '2 tiles pro zeichen! + if curstat == 1 + schar(cursor) + $04: 'getx + bus_putchar(col) + $05: 'gety + bus_putchar(row / 2) + $06: 'setcolor + color := bus_getchar + $07: 'sline + sline := bus_getchar * 2 + $08: 'eline + eline := bus_getchar * 2 + $09: 'screeninit + wordfill(@array, spacetile, tiles) + row := 0 + col := 0 + sline := 0 + +PRI schar(c)| i,k +'schreibt zeichen an aktuelle position ohne cursorposition zu ver?ndern + k := color << 1 + c & 1 + i := $8000 + (c & $FE) << 6 + k + array.word[row * cols + col] := i 'oberes tile setzen + array.word[(row + 1) * cols + col] := i | $40 'unteres tile setzen + +PRI pchar(c) +'schreibt zeichen an aktuelle position z?hlt position weiter + schar(c) + if ++col == cols + newline + +PUB newline | i + + col := 0 + if (row += 2) == rows + row -= 2 + 'scroll lines + repeat i from sline to rows-3 + + wordmove(@array.word[i*cols], @array.word[(i+2)*cols], cols) 'wordmove(dest,src,cnt) + 'clear new line + wordfill(@array.word[(rows-2)*cols], spacetile, cols<<1) + +PUB scrollup | i 'scrollt den screen nach oben + 'scroll lines + repeat i from sline to rows-3 + wordmove(@array.word[i*cols], @array.word[(i+2)*cols], cols) 'wordmove(dest,src,cnt) + 'clear new line + wordfill(@array.word[(rows-2)*cols], spacetile, cols<<1) + +PRI DrawText(pBmp,str,bInvert)|x1,x2,i,j,b,k,c,s +'draw prop font into bitmap + k:=0 'current column + repeat s from 0 to strsize(str)-1 + c:=byte[str][s] + if (c=>32) and (c=<(95+2)) 'note: char 96=dot, 97=degree + x1:=word[@FontTable][c-32] + x2:=word[@FontTable][c-32+1] + repeat i from x1 to x2-1 + DrawFontColumn(i,j,pBmp,k,b) + 'repeat j from 0 to 31 + ' b:=getFontPixel(i,j) + ' setFontPixel(pBmp,k,j,b) + k++ + +PRI DrawFontColumn(x,y,pdest,k,b)|dtile,stile,doffset,soffset,psrc,d,pixel,j + stile:=x/16 + soffset:=(x//16)*2 + psrc:=@font+4*16*stile+user_charbase-@uchar + dtile:=k/16 + doffset:=(k//16)*2 + pdest+=4*16*dtile+user_charbase-@uchar + repeat j from 0 to 31 + y:=j + if y=>16 + y-=16 + if j==16 + soffset++ + doffset++ + pixel:=long[psrc][y//16] + pixel>>=soffset + pixel&=$1 + 'draw + if pixel + long[pdest][y//16]|=|16 + offset++ + y-=16 + p:=@font+4*16*tile + d:=long[p+user_charbase-@uchar][y//16] + d>>=offset + return (d&$1)>0 + +PRI setFontPixel(p,x,y,b)|tile,offset,d +'set (b=true) or clear (b=false) pixel in bmp @p at coordinates (x,y) + tile:=x/16 + offset:=(x//16)*2 + if y=>16 + offset++ + y-=16 + p+=4*16*tile+user_charbase-@uchar + 'd:=long[p][y//16] + if b + long[p][y//16]|=|>6 + c & $FE + +PRI uPrintBottom(c,ncol,nrow)|i,k + 'print bottom part of a character + k := color << 1 + c & 1 + i := user_charbase + (c & $FE) << 6 + k + array.word[nrow * cols + ncol] := i+$40'user_charbase + (c<<6) + color+$40'(color << 1 + c & 1) << 10 + user_charbase>>6 + c & $FE +1 + +PRI Bitmap2Bit(pBitmap, xPos, yPos, xSize, ySize, clr)|c,i,j,BmpAddress + row:=yPos + col:=xPos + c:=0 + BmpAddress:=pBitmap+user_charbase-@uchar + repeat j from 0 to (ySize-1) + repeat i from 0 to (xSize-1) + array.word[row * cols + col] := BmpAddress + (c<<6) + clr + 'Print2Bit(c,clr,pBitmap) + c++ + col++ + row++ + col:=xPos + + +PRI Bitmap1Bit(pBitmap, xPos, yPos, xSize, ySize, clr)|c,i,j,BmpAddress + row:=yPos + col:=xPos + c:=0 + BmpAddress:=pBitmap+user_charbase-@uchar + repeat j from 0 to (ySize-1) step 2 + repeat i from 0 to (xSize-1) + array.word[row * cols + col] := (clr<<1+1) + BmpAddress +c<<6 + if ySize<>1 + array.word[(row+1) * cols + col] := (clr<<1) + BmpAddress +c<<6 + c++ + col++ + row+=2 + col:=xPos + + +PRI Bitmap1BitTile(pBitmap,x,y,clr,bLower)|BmpAddress +'print just the upper or lower tile of a 2-tile bitmap + BmpAddress:=pBitmap+user_charbase-@uchar + clr:=clr<<1+1 + if bLower + clr-=1 + + array.word[y * cols + x] := clr + BmpAddress + + +DAT + vgacolors long + +'0..1: text color 0: + long $90009000 'orange on black + long $90900000 +'2..3: text color 1: + long $5c005c00 'blue on black + long $5c5c0000 +'4..5: text color 2: + long $94009400 'light red on black + long $94940000 +'6..7: text color 3: + long $98009800 'purple on black + long $98980000 +'8..9: text color 4: + long $f800f800 'yellow on black + long $f8f80000 +'10..11: text color 5: + long $84008400 'dark red on black + long $84840000 + + +'12: graphics 2: 'card edge colors + long $100000FC ''green,black,black,white +'13: graphics 3: 'red face card colors + long $F0C000FC ' yellow,red,black,white +'14: graphics 4: 'black face card colors + long $F000C0FC ''yellow,black,red,white +'15: graphics 5: button colors + long $FC54A8A8 'lt grey, dk.gray, gray, gray + + +FontTable word + word 8, 16,21,32,60,72,92,107,114,121,129,138,150,156,164,170,184,195,203,214,225,239,250,261,273,284,295,300,306,316,333,343,354,378,392 'to B + word 403,414,425,435,445,456,467,472,483,496,506,523,537,548,559,570,582,593,605,616,630,649,663,676,686,695,706,720,733,743,751 'note last two chars are dot and degree + +padding LONG 7[16] 'alignment padding for the following user defined characters + +uchar long + +corner_topleft long + file "corner_topleft.dat" '6x2 + +corner_topright long + file "corner_topright.dat" '6x2 + +corner_bottomLeft long + file "corner_bottomLeft.dat" '6x2 + +hv_break long + file "hv_break.dat" '1x2 + +hv_break2 long + file "hv_break2.dat" '1x2 + +endcap_med_left long + file "endcap_med_left.dat" '1x2 + +endcap_med_right long + file "endcap_med_right.dat" '1x2 + +endcap_small_left long + file "endcap_small_left.dat" '1x2 + +endcap_small_right long + file "endcap_small_right.dat" '1x2 + +filled_space long + file "filled_space.dat" '1x2 + +font long + file "font_29p5.dat" '47x2 + +title long 0[16*23] 'space for title 23x2 +footer long 0[16*23] 'space for footer 23x2 + +button1 long 0[16*20] 'space for button text 10x2 +button2 long 0[16*20] 'space for button text +button3 long 0[16*20] 'space for button text +button4 long 0[16*20] 'space for button text +button5 long 0[16*20] 'space for button text +button6 long 0[16*20] 'space for button text 10x2 +button7 long 0[16*20] 'space for button text +button8 long 0[16*20] 'space for button text +button9 long 0[16*20] 'space for button text diff --git a/source/stracker/bellatrix/stkeyb.spin b/source/stracker/bellatrix/stkeyb.spin new file mode 100644 index 0000000..49aadfb --- /dev/null +++ b/source/stracker/bellatrix/stkeyb.spin @@ -0,0 +1,738 @@ +''*************************************** +''* PS/2 Keyboard Driver v1.0.1 * +''* Author: Chip Gracey * +''* Copyright (c) 2004 Parallax, Inc. * +''* See end of file for terms of use. * +''*************************************** + +{-----------------REVISION HISTORY----------------- + v1.0.1 - Updated 6/15/2006 to work with Propeller Tool 0.96} + +VAR + + long cog + + long par_tail 'key buffer tail read/write (19 contiguous longs) + long par_head 'key buffer head read-only + long par_present 'keyboard present read-only + long par_states[8] 'key states (256 bits) read-only + long par_keys[8] 'key buffer (16 words) read-only (also used to pass initial parameters) + + +PUB start(dpin, cpin) : okay + +'' Start keyboard driver - starts a cog +'' returns false if no cog available +'' +'' dpin = data signal on PS/2 jack +'' cpin = clock signal on PS/2 jack +'' +'' use 100-ohm resistors between pins and jack +'' use 10K-ohm resistors to pull jack-side signals to VDD +'' connect jack-power to 5V, jack-gnd to VSS +'' +'' all lock-keys will be enabled, NumLock will be initially 'on', +'' and auto-repeat will be set to 15cps with a delay of .5s + + okay := startx(dpin, cpin, %0_000_000, %01_01000) + + +PUB startx(dpin, cpin, locks, auto) : okay + +'' Like start, but allows you to specify lock settings and auto-repeat +'' +'' locks = lock setup +'' bit 6 disallows shift-alphas (case set soley by CapsLock) +'' bits 5..3 disallow toggle of NumLock/CapsLock/ScrollLock state +'' bits 2..0 specify initial state of NumLock/CapsLock/ScrollLock +'' (eg. %0_001_100 = disallow ScrollLock, NumLock initially 'on') +'' +'' auto = auto-repeat setup +'' bits 6..5 specify delay (0=.25s, 1=.5s, 2=.75s, 3=1s) +'' bits 4..0 specify repeat rate (0=30cps..31=2cps) +'' (eg %01_00000 = .5s delay, 30cps repeat) + + stop + longmove(@par_keys, @dpin, 4) + okay := cog := cognew(@entry, @par_tail) + 1 + + +PUB stop + +'' Stop keyboard driver - frees a cog + + if cog + cogstop(cog~ - 1) + longfill(@par_tail, 0, 19) + + +PUB present : truefalse + +'' Check if keyboard present - valid ~2s after start +'' returns t|f + + truefalse := -par_present + + +PUB key : keycode + +'' Get key (never waits) +'' returns key (0 if buffer empty) + + if par_tail <> par_head + keycode := par_keys.word[par_tail] + par_tail := ++par_tail & $F + + +PUB getkey : keycode + +'' Get next key (may wait for keypress) +'' returns key + + repeat until (keycode := key) + + +PUB newkey : keycode + +'' Clear buffer and get new key (always waits for keypress) +'' returns key + + par_tail := par_head + keycode := getkey + + +PUB gotkey : truefalse + +'' Check if any key in buffer +'' returns t|f + + truefalse := par_tail <> par_head + + +PUB clearkeys + +'' Clear key buffer + + par_tail := par_head + + +PUB keystate(k) : state + +'' Get the state of a particular key +'' returns t|f + + state := -(par_states[k >> 5] >> k & 1) + + +DAT + +'****************************************** +'* Assembly language PS/2 keyboard driver * +'****************************************** + + org +' +' +' Entry +' +entry movd :par,#_dpin 'load input parameters _dpin/_cpin/_locks/_auto + mov x,par + add x,#11*4 + mov y,#4 +:par rdlong 0,x + add :par,dlsb + add x,#4 + djnz y,#:par + + mov dmask,#1 'set pin masks + shl dmask,_dpin + mov cmask,#1 + shl cmask,_cpin + + test _dpin,#$20 wc 'modify port registers within code + muxc _d1,dlsb + muxc _d2,dlsb + muxc _d3,#1 + muxc _d4,#1 + test _cpin,#$20 wc + muxc _c1,dlsb + muxc _c2,dlsb + muxc _c3,#1 + + mov _head,#0 'reset output parameter _head +' +' +' Reset keyboard +' +reset mov dira,#0 'reset directions + mov dirb,#0 + + movd :par,#_present 'reset output parameters _present/_states[8] + mov x,#1+8 +:par mov 0,#0 + add :par,dlsb + djnz x,#:par + + mov stat,#8 'set reset flag +' +' +' Update parameters +' +update movd :par,#_head 'update output parameters _head/_present/_states[8] + mov x,par + add x,#1*4 + mov y,#1+1+8 +:par wrlong 0,x + add :par,dlsb + add x,#4 + djnz y,#:par + + test stat,#8 wc 'if reset flag, transmit reset command + if_c mov data,#$FF + if_c call #transmit +' +' +' Get scancode +' +newcode mov stat,#0 'reset state + +:same call #receive 'receive byte from keyboard + + cmp data,#$83+1 wc 'scancode? + + if_nc cmp data,#$AA wz 'powerup/reset? + if_nc_and_z jmp #configure + + if_nc cmp data,#$E0 wz 'extended? + if_nc_and_z or stat,#1 + if_nc_and_z jmp #:same + + if_nc cmp data,#$F0 wz 'released? + if_nc_and_z or stat,#2 + if_nc_and_z jmp #:same + + if_nc jmp #newcode 'unknown, ignore +' +' +' Translate scancode and enter into buffer +' + test stat,#1 wc 'lookup code with extended flag + rcl data,#1 + call #look + + cmp data,#0 wz 'if unknown, ignore + if_z jmp #newcode + + mov t,_states+6 'remember lock keys in _states + + mov x,data 'set/clear key bit in _states + shr x,#5 + add x,#_states + movd :reg,x + mov y,#1 + shl y,data + test stat,#2 wc +:reg muxnc 0,y + + if_nc cmpsub data,#$F0 wc 'if released or shift/ctrl/alt/win, done + if_c jmp #update + + mov y,_states+7 'get shift/ctrl/alt/win bit pairs + shr y,#16 + + cmpsub data,#$E0 wc 'translate keypad, considering numlock + if_c test _locks,#%100 wz + if_c_and_z add data,#@keypad1-@table + if_c_and_nz add data,#@keypad2-@table + if_c call #look + if_c jmp #:flags + + cmpsub data,#$DD wc 'handle scrlock/capslock/numlock + if_c mov x,#%001_000 + if_c shl x,data + if_c andn x,_locks + if_c shr x,#3 + if_c shr t,#29 'ignore auto-repeat + if_c andn x,t wz + if_c xor _locks,x + if_c add data,#$DD + if_c_and_nz or stat,#4 'if change, set configure flag to update leds + + test y,#%11 wz 'get shift into nz + + if_nz cmp data,#$60+1 wc 'check shift1 + if_nz_and_c cmpsub data,#$5B wc + if_nz_and_c add data,#@shift1-@table + if_nz_and_c call #look + if_nz_and_c andn y,#%11 + + if_nz cmp data,#$3D+1 wc 'check shift2 + if_nz_and_c cmpsub data,#$27 wc + if_nz_and_c add data,#@shift2-@table + if_nz_and_c call #look + if_nz_and_c andn y,#%11 + + test _locks,#%010 wc 'check shift-alpha, considering capslock + muxnc :shift,#$20 + test _locks,#$40 wc + if_nz_and_nc xor :shift,#$20 + cmp data,#"z"+1 wc + if_c cmpsub data,#"a" wc +:shift if_c add data,#"A" + if_c andn y,#%11 + +:flags ror data,#8 'add shift/ctrl/alt/win flags + mov x,#4 '+$100 if shift +:loop test y,#%11 wz '+$200 if ctrl + shr y,#2 '+$400 if alt + if_nz or data,#1 '+$800 if win + ror data,#1 + djnz x,#:loop + rol data,#12 + + rdlong x,par 'if room in buffer and key valid, enter + sub x,#1 + and x,#$F + cmp x,_head wz + if_nz test data,#$FF wz + if_nz mov x,par + if_nz add x,#11*4 + if_nz add x,_head + if_nz add x,_head + if_nz wrword data,x + if_nz add _head,#1 + if_nz and _head,#$F + + test stat,#4 wc 'if not configure flag, done + if_nc jmp #update 'else configure to update leds +' +' +' Configure keyboard +' +configure mov data,#$F3 'set keyboard auto-repeat + call #transmit + mov data,_auto + and data,#%11_11111 + call #transmit + + mov data,#$ED 'set keyboard lock-leds + call #transmit + mov data,_locks + rev data,#-3 & $1F + test data,#%100 wc + rcl data,#1 + and data,#%111 + call #transmit + + mov x,_locks 'insert locks into _states + and x,#%111 + shl _states+7,#3 + or _states+7,x + ror _states+7,#3 + + mov _present,#1 'set _present + + jmp #update 'done +' +' +' Lookup byte in table +' +look ror data,#2 'perform lookup + movs :reg,data + add :reg,#table + shr data,#27 + mov x,data +:reg mov data,0 + shr data,x + + jmp #rand 'isolate byte +' +' +' Transmit byte to keyboard +' +transmit +_c1 or dira,cmask 'pull clock low + movs napshr,#13 'hold clock for ~128us (must be >100us) + call #nap +_d1 or dira,dmask 'pull data low + movs napshr,#18 'hold data for ~4us + call #nap +_c2 xor dira,cmask 'release clock + + test data,#$0FF wc 'append parity and stop bits to byte + muxnc data,#$100 + or data,dlsb + + mov x,#10 'ready 10 bits +transmit_bit call #wait_c0 'wait until clock low + shr data,#1 wc 'output data bit +_d2 muxnc dira,dmask + mov wcond,c1 'wait until clock high + call #wait + djnz x,#transmit_bit 'another bit? + + mov wcond,c0d0 'wait until clock and data low + call #wait + mov wcond,c1d1 'wait until clock and data high + call #wait + + call #receive_ack 'receive ack byte with timed wait + cmp data,#$FA wz 'if ack error, reset keyboard + if_nz jmp #reset + +transmit_ret ret +' +' +' Receive byte from keyboard +' +receive test _cpin,#$20 wc 'wait indefinitely for initial clock low + waitpne cmask,cmask +receive_ack + mov x,#11 'ready 11 bits +receive_bit call #wait_c0 'wait until clock low + movs napshr,#16 'pause ~16us + call #nap +_d3 test dmask,ina wc 'input data bit + rcr data,#1 + mov wcond,c1 'wait until clock high + call #wait + djnz x,#receive_bit 'another bit? + + shr data,#22 'align byte + test data,#$1FF wc 'if parity error, reset keyboard + if_nc jmp #reset +rand and data,#$FF 'isolate byte + +look_ret +receive_ack_ret +receive_ret ret +' +' +' Wait for clock/data to be in required state(s) +' +wait_c0 mov wcond,c0 '(wait until clock low) + +wait mov y,tenms 'set timeout to 10ms + +wloop movs napshr,#18 'nap ~4us + call #nap +_c3 test cmask,ina wc 'check required state(s) +_d4 test dmask,ina wz 'loop until got state(s) or timeout +wcond if_never djnz y,#wloop '(replaced with c0/c1/c0d0/c1d1) + + tjz y,#reset 'if timeout, reset keyboard +wait_ret +wait_c0_ret ret + + +c0 if_c djnz y,#wloop '(if_never replacements) +c1 if_nc djnz y,#wloop +c0d0 if_c_or_nz djnz y,#wloop +c1d1 if_nc_or_z djnz y,#wloop +' +' +' Nap +' +nap rdlong t,#0 'get clkfreq +napshr shr t,#18/16/13 'shr scales time + min t,#3 'ensure waitcnt won't snag + add t,cnt 'add cnt to time + waitcnt t,#0 'wait until time elapses (nap) + +nap_ret ret +' +' +' Initialized data +' +' +dlsb long 1 << 9 +tenms long 10_000 / 4 +' +' +' Lookup table +' ascii scan extkey regkey ()=keypad +' +table word $0000 '00 + word $00D8 '01 F9 + word $0000 '02 + word $00D4 '03 F5 + word $00D2 '04 F3 + word $00D0 '05 F1 + word $00D1 '06 F2 + word $00DB '07 F12 + word $0000 '08 + word $00D9 '09 F10 + word $00D7 '0A F8 + word $00D5 '0B F6 + word $00D3 '0C F4 + word $0009 '0D Tab + word $0060 '0E ` + word $0000 '0F + word $0000 '10 + word $F5F4 '11 Alt-R Alt-L + word $00F0 '12 Shift-L + word $0000 '13 + word $F3F2 '14 Ctrl-R Ctrl-L + word $0071 '15 q + word $0031 '16 1 + word $0000 '17 + word $0000 '18 + word $0000 '19 + word $0079 '1A z y + word $0073 '1B s + word $0061 '1C a + word $0077 '1D w + word $0032 '1E 2 + word $F600 '1F Win-L + word $0000 '20 + word $0063 '21 c + word $0078 '22 x + word $0064 '23 d + word $0065 '24 e + word $0034 '25 4 + word $0033 '26 3 + word $F700 '27 Win-R + word $0000 '28 + word $0020 '29 Space + word $0076 '2A v + word $0066 '2B f + word $0074 '2C t + word $0072 '2D r + word $0035 '2E 5 + word $CC00 '2F Apps + word $0000 '30 + word $006E '31 n + word $0062 '32 b + word $0068 '33 h + word $0067 '34 g + word $007A '35 y z + word $0036 '36 6 + word $CD00 '37 Power + word $0000 '38 + word $002C '39 , + word $006D '3A m + word $006A '3B j + word $0075 '3C u + word $0037 '3D 7 + word $0038 '3E 8 + word $CE00 '3F Sleep + word $0000 '40 + word $002C '41 , + word $006B '42 k + word $0069 '43 i + word $006F '44 o + word $0030 '45 0 + word $0039 '46 9 + word $0000 '47 + word $0000 '48 + word $002E '49 . + word $002D '4A (/) / - + word $006C '4B l + word $007B '4C } ö + word $0070 '4D p + word $002B '4E + + word $0000 '4F + word $0000 '50 + word $0000 '51 + word $007D '52 { ä + word $0000 '53 + word $005B '54 [ Ü + word $003D '55 = + word $0000 '56 + word $0000 '57 + word $00DE '58 CapsLock + word $00F1 '59 Shift-R + word $EB0D '5A (Enter) Enter + word $005D '5B ] + word $0000 '5C + word $0023 '5D \ # + word $CF00 '5E WakeUp + word $0000 '5F + word $0000 '60 + word $003C '61 < + word $0000 '62 + word $0000 '63 + word $0000 '64 + word $0000 '65 + word $00C8 '66 BackSpace + word $0000 '67 + word $0000 '68 + word $C5E1 '69 End (1) + word $0000 '6A + word $C0E4 '6B Left (4) + word $C4E7 '6C Home (7) + word $0000 '6D + word $0000 '6E + word $0000 '6F + word $CAE0 '70 Insert (0) + word $C9EA '71 Delete (.) + word $C3E2 '72 Down (2) + word $00E5 '73 (5) + word $C1E6 '74 Right (6) + word $C2E8 '75 Up (8) + word $00CB '76 Esc + word $00DF '77 NumLock + word $00DA '78 F11 + word $00EC '79 (+) + word $C7E3 '7A PageDn (3) + word $00ED '7B (-) + word $DCEE '7C PrScr (*) + word $C6E9 '7D PageUp (9) + word $00DD '7E ScrLock + word $0000 '7F + word $0000 '80 + word $0000 '81 + word $0000 '82 + word $00D6 '83 F7 + +keypad1 byte $CA, $C5, $C3, $C7, $C0, 0, $C1, $C4, $C2, $C6, $C9, $0D, "+-*/" + +keypad2 byte "0123456789.", $0D, "+-*/" + +shift1 byte "{|}__°________" '5B..60 + '"{|}", 0, 0, "~" + +shift2 byte "}___*;_:?=!",$22,"@$%&/()eÖ>+" '24..3D + '$22, 0, 0, 0, 0, "<_>?)!@#$%^&*(", 0, ":", 0, "+" +' +' +' Uninitialized data +' +dmask res 1 +cmask res 1 +stat res 1 +data res 1 +x res 1 +y res 1 +t res 1 + +_head res 1 'write-only +_present res 1 'write-only +_states res 8 'write-only +_dpin res 1 'read-only at start +_cpin res 1 'read-only at start +_locks res 1 'read-only at start +_auto res 1 'read-only at start + +'' +'' +'' _________ +'' Key Codes +'' +'' 00..DF = keypress and keystate +'' E0..FF = keystate only +'' +'' +'' 09 Tab +'' 0D Enter +'' 20 Space +'' 21 ! +'' 22 " +'' 23 # +'' 24 $ +'' 25 % +'' 26 & +'' 27 ' +'' 28 ( +'' 29 ) +'' 2A * +'' 2B + +'' 2C , +'' 2D - +'' 2E . +'' 2F / +'' 30 0..9 +'' 3A : +'' 3B ; +'' 3C < +'' 3D = +'' 3E > +'' 3F ? +'' 40 @ +'' 41..5A A..Z +'' 5B [ +'' 5C \ +'' 5D ] +'' 5E ^ +'' 5F _ +'' 60 ` +'' 61..7A a..z +'' 7B { +'' 7C | +'' 7D } +'' 7E ~ +'' +'' 80-BF (future international character support) +'' +'' C0 Left Arrow +'' C1 Right Arrow +'' C2 Up Arrow +'' C3 Down Arrow +'' C4 Home +'' C5 End +'' C6 Page Up +'' C7 Page Down +'' C8 Backspace +'' C9 Delete +'' CA Insert +'' CB Esc +'' CC Apps +'' CD Power +'' CE Sleep +'' CF Wakeup +'' +'' D0..DB F1..F12 +'' DC Print Screen +'' DD Scroll Lock +'' DE Caps Lock +'' DF Num Lock +'' +'' E0..E9 Keypad 0..9 +'' EA Keypad . +'' EB Keypad Enter +'' EC Keypad + +'' ED Keypad - +'' EE Keypad * +'' EF Keypad / +'' +'' F0 Left Shift +'' F1 Right Shift +'' F2 Left Ctrl +'' F3 Right Ctrl +'' F4 Left Alt +'' F5 Right Alt +'' F6 Left Win +'' F7 Right Win +'' +'' FD Scroll Lock State +'' FE Caps Lock State +'' FF Num Lock State +'' +'' +100 if Shift +'' +200 if Ctrl +'' +400 if Alt +'' +800 if Win +'' +'' eg. Ctrl-Alt-Delete = $6C9 +'' +'' +'' Note: Driver will buffer up to 15 keystrokes, then ignore overflow. + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} \ No newline at end of file diff --git a/source/stracker/bellatrix/stmouse.spin b/source/stracker/bellatrix/stmouse.spin new file mode 100644 index 0000000..cbcee65 --- /dev/null +++ b/source/stracker/bellatrix/stmouse.spin @@ -0,0 +1,470 @@ +''***************************** +''* PS/2 Mouse Driver v1.1 * +''* (C) 2006 Parallax, Inc. * +''***************************** + +' v1.0 - 01 May 2006 - original version +' v1.1 - 01 Jun 2006 - bound coordinates added to simplify upper objects + + +VAR + + long cog + + long oldx, oldy, oldz 'must be followed by parameters (10 contiguous longs) + + long par_x 'absolute x read-only (7 contiguous longs) + long par_y 'absolute y read-only + long par_z 'absolute z read-only + long par_buttons 'button states read-only + long par_present 'mouse present read-only + long par_dpin 'data pin write-only + long par_cpin 'clock pin write-only + + long bx_min, by_min, bz_min 'min/max must be contiguous + long bx_max, by_max, bz_max + long bx_div, by_div, bz_div + long bx_acc, by_acc, bz_acc + + +PUB start(dpin, cpin) : okay + +'' Start mouse driver - starts a cog +'' returns false if no cog available +'' +'' dpin = data signal on PS/2 jack +'' cpin = clock signal on PS/2 jack +'' +'' use 100-ohm resistors between pins and jack +'' use 10K-ohm resistors to pull jack-side signals to VDD +'' connect jack-power to 5V, jack-gnd to VSS + + stop + par_dpin := dpin + par_cpin := cpin + okay := cog := cognew(@entry, @par_x) + 1 + + +PUB stop + +'' Stop mouse driver - frees a cog + + if cog + cogstop(cog~ - 1) + longfill(@oldx, 0, 10) + + +PUB present : type + +'' Check if mouse present - valid ~2s after start +'' returns mouse type: +'' +'' 3 = five-button scrollwheel mouse +'' 2 = three-button scrollwheel mouse +'' 1 = two-button or three-button mouse +'' 0 = no mouse connected + + type := par_present + + +PUB button(b) : state + +'' Get the state of a particular button +'' returns t|f + + state := -(par_buttons >> b & 1) + + +PUB buttons : states + +'' Get the states of all buttons +'' returns buttons: +'' +'' bit4 = right-side button +'' bit3 = left-side button +'' bit2 = center/scrollwheel button +'' bit1 = right button +'' bit0 = left button + + states := par_buttons + + +PUB abs_x : x + +'' Get absolute-x + + x := par_x + + +PUB abs_y : y + +'' Get absolute-y + + y := par_y + + +PUB abs_z : z + +'' Get absolute-z (scrollwheel) + + z := par_z + + +PUB delta_reset + +'' Reset deltas + + oldx := par_x + oldy := par_y + oldz := par_z + + +PUB delta_x : x | newx + +'' Get delta-x + + newx := par_x + x := newx - oldx + oldx := newx + + +PUB delta_y : y | newy + +'' Get delta-y + + newy := par_y + y := newy - oldy + oldy := newy + + +PUB delta_z : z | newz + +'' Get delta-z (scrollwheel) + + newz := par_z + z := newz - oldz + oldz := newz + + +PUB bound_limits(xmin, ymin, zmin, xmax, ymax, zmax) | i + +'' Set bounding limits + + longmove(@bx_min, @xmin, 6) + + +PUB bound_scales(x_scale, y_scale, z_scale) + +'' Set bounding scales (usually +/-1's, bigger values divide) + + longmove(@bx_div, @x_scale, 3) + + +PUB bound_preset(x, y, z) | i, d + +'' Preset bound coordinates + + repeat i from 0 to 2 + d := ||bx_div[i] + bx_acc[i] := (x[i] - bx_min[i]) * d + d >> 1 + + +PUB bound_x : x + +'' Get bound-x + + x := bound(0, delta_x) + + +PUB bound_y : y + +'' Get bound-y + + y := bound(1, delta_y) + + +PUB bound_z : z + +'' Get bound-z + + z := bound(2, delta_z) + + +PRI bound(i, delta) : b | d + + d := bx_div[i] + b := bx_min[i] + (bx_acc[i] := bx_acc[i] + delta * (d < 0) | 1 #> 0 <# (bx_max[i] - bx_min[i] + 1) * ||d - 1) / ||d + + +DAT + +'*************************************** +'* Assembly language PS/2 mouse driver * +'*************************************** + + org +' +' +' Entry +' +entry mov p,par 'load input parameters: + add p,#5*4 '_dpin/_cpin + rdlong _dpin,p + add p,#4 + rdlong _cpin,p + + mov dmask,#1 'set pin masks + shl dmask,_dpin + mov cmask,#1 + shl cmask,_cpin + + test _dpin,#$20 wc 'modify port registers within code + muxc _d1,dlsb + muxc _d2,dlsb + muxc _d3,#1 + muxc _d4,#1 + test _cpin,#$20 wc + muxc _c1,dlsb + muxc _c2,dlsb + muxc _c3,#1 + + movd :par,#_x 'reset output parameters: + mov p,#5 '_x/_y/_z/_buttons/_present +:par mov 0,#0 + add :par,dlsb + djnz p,#:par +' +' +' Reset mouse +' +reset mov dira,#0 'reset directions + mov dirb,#0 + + mov stat,#1 'set reset flag +' +' +' Update parameters +' +update movd :par,#_x 'update output parameters: + mov p,par '_x/_y/_z/_buttons/_present + mov q,#5 +:par wrlong 0,p + add :par,dlsb + add p,#4 + djnz q,#:par + + test stat,#1 wc 'if reset flag, transmit reset command + if_c mov data,#$FF + if_c call #transmit +' +' +' Get data packet +' + mov stat,#0 'reset state + + call #receive 'receive first byte + + cmp data,#$AA wz 'powerup/reset? + if_z jmp #init + + mov _buttons,data 'data packet, save buttons + + call #receive 'receive second byte + + test _buttons,#$10 wc 'adjust _x + muxc data,signext + add _x,data + + call #receive 'receive third byte + + test _buttons,#$20 wc 'adjust _y + muxc data,signext + add _y,data + + and _buttons,#%111 'trim buttons + + cmp _present,#2 wc 'if not scrollwheel mouse, update parameters + if_c jmp #update + + + call #receive 'scrollwheel mouse, receive fourth byte + + cmp _present,#3 wz 'if 5-button mouse, handle two extra buttons + if_z test data,#$10 wc + if_z_and_c or _buttons,#%01000 + if_z test data,#$20 wc + if_z_and_c or _buttons,#%10000 + + shl data,#28 'adjust _z + sar data,#28 + sub _z,data + + jmp #update 'update parameters +' +' +' Initialize mouse +' +init call #receive '$AA received, receive id + + movs crate,#100 'try to enable 3-button scrollwheel type + call #checktype + movs crate,#200 'try to enable 5-button scrollwheel type + call #checktype + shr data,#1 'if neither, 3-button type + add data,#1 + mov _present,data + + movs srate,#200 'set 200 samples per second + call #setrate + + mov data,#$F4 'enable data reporting + call #transmit + + jmp #update +' +' +' Check mouse type +' +checktype movs srate,#200 'perform "knock" sequence to enable + call #setrate '..scrollwheel and extra buttons + +crate movs srate,#200/100 + call #setrate + + movs srate,#80 + call #setrate + + mov data,#$F2 'read type + call #transmit + call #receive + +checktype_ret ret +' +' +' Set sample rate +' +setrate mov data,#$F3 + call #transmit +srate mov data,#0 + call #transmit + +setrate_ret ret +' +' +' Transmit byte to mouse +' +transmit +_c1 or dira,cmask 'pull clock low + movs napshr,#13 'hold clock for ~128us (must be >100us) + call #nap +_d1 or dira,dmask 'pull data low + movs napshr,#18 'hold data for ~4us + call #nap +_c2 xor dira,cmask 'release clock + + test data,#$0FF wc 'append parity and stop bits to byte + muxnc data,#$100 + or data,dlsb + + mov p,#10 'ready 10 bits +transmit_bit call #wait_c0 'wait until clock low + shr data,#1 wc 'output data bit +_d2 muxnc dira,dmask + mov wcond,c1 'wait until clock high + call #wait + djnz p,#transmit_bit 'another bit? + + mov wcond,c0d0 'wait until clock and data low + call #wait + mov wcond,c1d1 'wait until clock and data high + call #wait + + call #receive_ack 'receive ack byte with timed wait + cmp data,#$FA wz 'if ack error, reset mouse + if_nz jmp #reset + +transmit_ret ret +' +' +' Receive byte from mouse +' +receive test _cpin,#$20 wc 'wait indefinitely for initial clock low + waitpne cmask,cmask +receive_ack + mov p,#11 'ready 11 bits +receive_bit call #wait_c0 'wait until clock low + movs napshr,#16 'pause ~16us + call #nap +_d3 test dmask,ina wc 'input data bit + rcr data,#1 + mov wcond,c1 'wait until clock high + call #wait + djnz p,#receive_bit 'another bit? + + shr data,#22 'align byte + test data,#$1FF wc 'if parity error, reset mouse + if_nc jmp #reset + and data,#$FF 'isolate byte + +receive_ack_ret +receive_ret ret +' +' +' Wait for clock/data to be in required state(s) +' +wait_c0 mov wcond,c0 '(wait until clock low) + +wait mov q,tenms 'set timeout to 10ms + +wloop movs napshr,#18 'nap ~4us + call #nap +_c3 test cmask,ina wc 'check required state(s) +_d4 test dmask,ina wz 'loop until got state(s) or timeout +wcond if_never djnz q,#wloop '(replaced with c0/c1/c0d0/c1d1) + + tjz q,#reset 'if timeout, reset mouse +wait_ret +wait_c0_ret ret + + +c0 if_c djnz q,#wloop '(if_never replacements) +c1 if_nc djnz q,#wloop +c0d0 if_c_or_nz djnz q,#wloop +c1d1 if_nc_or_z djnz q,#wloop +' +' +' Nap +' +nap rdlong t,#0 'get clkfreq +napshr shr t,#18/16/13 'shr scales time + min t,#3 'ensure waitcnt won't snag + add t,cnt 'add cnt to time + waitcnt t,#0 'wait until time elapses (nap) + +nap_ret ret +' +' +' Initialized data +' +dlsb long 1 << 9 +tenms long 10_000 / 4 +signext long $FFFFFF00 +' +' +' Uninitialized data +' +dmask res 1 +cmask res 1 +stat res 1 +data res 1 +p res 1 +q res 1 +t res 1 + +_x res 1 'write-only +_y res 1 'write-only +_z res 1 'write-only +_buttons res 1 'write-only +_present res 1 'write-only +_dpin res 1 'read-only +_cpin res 1 'read-only \ No newline at end of file diff --git a/source/stracker/bellatrix/stvga.spin b/source/stracker/bellatrix/stvga.spin new file mode 100644 index 0000000..2a7841d --- /dev/null +++ b/source/stracker/bellatrix/stvga.spin @@ -0,0 +1,543 @@ +{{ +┌────────────────────────────────────────┬────────────────┬────────────────────────┬──────────────────┐ +│ VGA 1024x768 Tile Driver v0.9 │ by Chip Gracey │ (C)2006 Parallax, Inc. │ 11 November 2006 │ +├────────────────────────────────────────┴────────────────┴────────────────────────┴──────────────────┤ +│ │ +│ This object generates a 1024x768 VGA display from a 64x48 array of 16x16-pixel 4-color tiles. │ +│ It requires two cogs (or three with optional cursor enabled) and at least 80 MHz. │ +│ │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +}} +CON + +' 1024 x 768 @ 60Hz settings + + hp = 1024 'horizontal pixels + vp = 768 'vertical pixels + hf = 24 'horizontal front porch pixels + hs = 136 'horizontal sync pixels + hb = 160 'horizontal back porch pixels + vf = 3 'vertical front porch lines + vs = 6 'vertical sync lines + vb = 29 'vertical back porch lines + pr = 65 'pixel rate in MHz at 80MHz system clock (5MHz granularity) + + ht = hp + hf + hs + hb 'total scan line pixels + +' Tile array + + xtiles = hp / 16 + ytiles = vp / 16 + + +VAR + + long cog[3] + + long dira_ '9 contiguous longs + long dirb_ + long vcfg_ + long cnt_ + long array_ptr_ + long color_ptr_ + long cursor_ptr_ + long sync_ptr_ + long mode_ + + +PUB start(base_pin, array_ptr, color_ptr, cursor_ptr, sync_ptr, mode) : okay | i, j + +'' Start driver - starts two or three cogs +'' returns false if cogs not available +'' +'' base_pin = First of eight VGA pins, must be a multiple of eight (0, 8, 16, 24, etc): +'' +'' 240Ω 240Ω 240Ω 240Ω +'' +7 ───┳─ Red +5 ───┳─ Green +3 ───┳─ Blue +1 ── H +'' 470Ω │ 470Ω │ 470Ω │ 240Ω +'' +6 ───┘ +4 ───┘ +2 ───┘ +0 ── V +'' +'' array_ptr = Pointer to 3,072 long-aligned words, organized as 64 across by 48 down, +'' which will serve as the tile array. Each word specifies a tile bitmap and +'' a color palette for its tile area. The top 10 bits of each word form the +'' base address of a 16-long tile bitmap, while the lower 6 bits select a +'' color palette for the bitmap. For example, $B2E5 would specify the tile +'' bitmap spanning $B2C0..$B2FF and color palette $25. +'' +'' color_ptr = Pointer to 64 longs which will define the 64 color palettes. The RGB data +'' in each long is arranged as %%RGBx_RGBx_RGBx_RGBx with the sub-bytes 3..0 +'' providing the color data for pixel values %11..%00, respectively: +'' +'' %%3330_0110_0020_3300: %11=white, %10=dark cyan, %01=blue, %00=gold +'' +'' cursor_ptr = Pointer to 4 longs which will control the cursor, or 0 to disable the +'' cursor. If a pointer is given, an extra cog will be started to generate +'' the cursor overlay. Here are the 4 longs that control the cursor: +'' +'' cursor_x - X position of cursor: ..0..1023.. (left to right) +'' cursor_y - Y position of cursor: ..0..767.. (bottom to top) +'' +'' cursor_color - Cursor color to be OR'd to background color as %%RGBx: +'' %%3330=white, %%2220 or %%1110=translucent, %%0000=off +'' +'' cursor_shape - 0 for arrow, 1 for crosshair, or pointer to a cursor +'' definition. A cursor definition consists of 32 longs +'' containing a 32x32 pixel cursor image, followed by two +'' bytes which define the X and Y center-pixel offsets +'' within the image. +'' +'' sync_ptr = Pointer to a long which will be set to -1 after each refresh, or 0 to +'' disable this function. This is useful in advanced applications where +'' awareness of display timing is important. +'' +'' mode = 0 for normal 16x16 pixel tiles or 1 for taller 16x32 pixel tiles. Mode 1 +'' is useful for displaying the internal font while requiring half the array +'' memory; however, the 3-D bevel characters will not be usable because of +'' the larger vertical tile granularity of this mode. + + 'If driver is already running, stop it + stop + + 'Ready i/o settings + i := $FF << (base_pin & %011000) + j := base_pin & %100000 == 0 + dira_ := i & j + dirb_ := i & !j + vcfg_ := $300000FF + (base_pin & %111000) << 6 + + 'Ready cnt value to sync cogs by + cnt_ := cnt + $100000 + + 'Ready pointers and mode + longmove(@array_ptr_, @array_ptr, 5) + + 'Launch cogs, abort if error + repeat i from 0 to 2 + if i == 2 'cursor cog? + ifnot cursor_ptr 'cursor enabled? + quit 'if not, quit loop + waitcnt($2000 + cnt) 'cursor cog, allow prior cog to launch + vcfg_ ^= $10000000 'set two-color mode + array_ptr_~ 'flag cursor function + ifnot cog[i] := cognew(@entry, @dira_ + i << 15) + 1 + stop + return {false} + + 'Successful + return true + + +PUB stop | i + +'' Stop driver - frees cogs + + 'If already running, stop any VGA cogs + repeat i from 0 to 2 + if cog[i] + cogstop(cog[i]~ - 1) + + +DAT + +' ┌─────────────────────────────┐ +' │ Initialization - all cogs │ +' └─────────────────────────────┘ + + org + +' Move field loop into position + +entry mov field,field_code + add entry,d0s0_ + djnz regs,#entry + +' Acquire settings + + mov regs,par 'dira_ ─ dira + cmpsub regs,bit15 wc 'dirb_ ─ dirb +:next movd :read,sprs 'vcfg_ ─ vcfg + or :read,d8_d4 'cnt_ ─ cnt + shr sprs,#4 'array_ptr_ ─ ctrb +:read rdlong dira,regs 'color_ptr_ ─ frqb + add regs,#4 'cursor_ptr_ ─ vscl + tjnz sprs,#:next 'sync_ptr_ ─ phsb + + sumc vf_lines,#2 'alter scan line settings by cog + sumnc vb_lines,#2 + sumnc tile_line,#2 * 4 + + rdlong regs,regs wz 'if mode not 0, set tile size to 16 x 32 pixels + if_nz movs tile_bytes,#32 * 4 + if_nz shr array_bytes,#1 + + mov regs,vscl 'save cursor pointer + +' Synchronize all cogs' video circuits so that waitvid's will be pixel-locked + + movi frqa,#(pr / 5) << 2 'set pixel rate (VCO runs at 2x) + mov vscl,#1 'set video shifter to reload on every pixel + waitcnt cnt,d8_d4 'wait for sync count, add ~3ms - cogs locked! + movi ctra,#%00001_110 'enable PLLs now - NCOs locked! + waitcnt cnt,#0 'wait ~3ms for PLLs to stabilize - PLLs locked! + mov vscl,#100 'subsequent WAITVIDs will now be pixel-locked! + +' Determine if this cog is to perform one of two field functions or the cursor function + + tjnz ctrb,#vsync 'if array ptr, jump to field function + 'else, cursor function follows + +' ┌─────────────────────────┐ +' │ Cursor Loop - one cog │ +' └─────────────────────────┘ + +' Do vertical sync lines minus three + +cursor mov par,#vf + vs + vb - 6 + +:loop mov vscl,vscl_line +:vsync waitvid ccolor,#0 + djnz par,#:vsync + +' Do three lines minus horizontal back porch pixels to buy a big block of time + + mov vscl,vscl_three_lines_mhb + waitvid ccolor,#0 + +' Get cursor data + + rdlong cx,regs 'get cursor x + add regs,#4 + rdlong cy,regs 'get cursor y + add regs,#4 + rdlong ccolor,regs 'get cursor color + add regs,#4 + rdlong cshape,regs 'get cursor shape + sub regs,#3 * 4 + + and ccolor,#$FC 'trim and justify cursor color + shl ccolor,#8 + +' Build cursor pixels + + mov par,#32 'ready for 32 cursor segments + movd :pix,#cpix + mov cnt,cshape + +:pixloop cmp cnt,#1 wc, wz 'arrow, crosshair, or custom cursor? + if_a jmp #:custom + if_e jmp #:crosshair + + cmp par,#32 wz 'arrow + cmp par,#32-21 wc + if_z mov cseg,h80000000 + if_nz_and_nc sar cseg,#1 + if_nz_and_c shl cseg,#2 + mov coff,#0 + jmp #:pix + +:crosshair cmp par,#32-15 wz 'crosshair + if_ne mov cseg,h00010000 + if_e neg cseg,#2 + cmp par,#1 wz + if_e mov cseg,#0 + mov coff,h00000F0F + jmp #:pix + +:custom rdlong cseg,cshape 'custom + add cshape,#4 + rdlong coff,cshape + +:pix mov cpix,cseg 'save segment into pixels + add :pix,d0 + + djnz par,#:pixloop 'another segment? + +' Compute cursor position + + mov cseg,coff 'apply cursor center-pixel offsets + and cseg,#$FF + sub cx,cseg + shr coff,#8 + and coff,#$FF + add cy,coff + + cmps cx,neg31 wc 'if x out of range, hide cursor via y + if_nc cmps pixels_m1,cx wc + if_c neg cy,#1 + + mov cshr,#0 'adjust for left-edge clipping + cmps cx,#0 wc + if_c neg cshr,cx + if_c mov cx,#0 + + mov cshl,#0 'adjust for right-edge clipping + cmpsub cx,pixels_m32 wc + if_c mov cshl,cx + if_c mov cx,pixels_m32 + + add cx,#hb 'bias x and y for display + sub cy,lines_m1 + +' Do visible lines with cursor + + mov par,lines 'ready for visible scan lines + +:line andn cy,#$1F wz, nr 'check if scan line in cursor range + + if_z movs :seg,cy 'if in range, get cursor pixels + if_z add :seg,#cpix + if_nz mov cseg,#0 'if out of range, use blank pixels +:seg if_z mov cseg,cpix + if_z rev cseg,#0 'reverse pixels so they map sensibly + if_z shr cseg,cshr 'perform any edge clipping on pixels + if_z shl cseg,cshl + + mov vscl,cx 'do left blank pixels (hb+cx) + waitvid ccolor,#0 + + mov vscl,vscl_cursor 'do cursor pixels (32) + waitvid ccolor,cseg + + mov vscl,vscl_line_m32 'do right blank pixels (hp+hf+hs-32-cx) + sub vscl,cx + waitvid ccolor,#0 + + add cy,#1 'another scan line? + djnz par,#:line + +' Do horizontal back porch pixels and loop + + mov vscl,#hb + waitvid ccolor,#0 + + mov par,#vf + vs + vb - 3 'ready to do vertical sync lines + jmp #:loop + +' Cursor data + +vscl_line long ht 'total pixels per scan line +vscl_three_lines_mhb long ht * 3 - hb 'total pixels per three scan lines minus hb +vscl_line_m32 long ht - 32 'total pixels per scan line minus 32 +vscl_cursor long 1 << 12 + 32 '32 pixels per cursor with 1 clock per pixel +lines long vp 'visible scan lines +lines_m1 long vp - 1 'visible scan lines minus 1 +pixels_m1 long hp - 1 'visible pixels minus 1 +pixels_m32 long hp - 32 'visible pixels minus 32 +neg31 long -31 + +h80000000 long $80000000 'arrow/crosshair cursor data +h00010000 long $00010000 +h00000F0F long $00000F0F + +' Initialization data + +d0s0_ long 1 << 9 + 1 'd and s field increments +regs long $1F0 - field 'number of registers in field loop space +sprs long $DFB91E76 'phsb/vscl/frqb/ctrb/cnt/vcfg/dirb/dira nibbles +bit15 long $8000 'bit15 mask used to differentiate cogs in par +d8_d4 long $0003E000 'bit8..bit4 mask for d field + +field_code 'field loop code begins at this offset + +' Undefined cursor data + +cx res 1 +cy res 1 +ccolor res 1 +cshape res 1 +coff res 1 +cseg res 1 +cshr res 1 +cshl res 1 +cpix res 32 + + +' ┌─────────────────────────┐ +' │ Field Loop - two cogs │ +' └─────────────────────────┘ + + org + +' Allocate buffers + +palettes res 64 'palettes of colors +colors res xtiles 'colors for tile row +pixels0 res xtiles 'pixels for tile row line +0 +pixels1 res xtiles 'pixels for tile row line +1 +pixels2 res xtiles 'pixels for tile row line +2 +pixels3 res xtiles 'pixels for tile row line +3 + +' Each cog alternately builds and displays four scan lines + +field mov cnt,#ytiles * 4 / 2 'ready number of four-scan-line builds/displays + +' Build four scan lines + +build_4y movd col0,#colors+0 'reset pointers for scan line buffers + movd col1,#colors+1 + movd pix0,#pixels0+0 + movd pix1,#pixels1+0 + movd pix2,#pixels2+0 + movd pix3,#pixels3+0 + movd pix4,#pixels0+1 + movd pix5,#pixels1+1 + movd pix6,#pixels2+1 + movd pix7,#pixels3+1 + + mov ina,#2 'four scan lines require two waitvid's + +build_32x mov vscl,vscl_two_lines 'output lows for two scan lines so other cog +:zero waitvid :zero,#0 '..can display while this cog builds (twice) + + mov inb,#xtiles / 2 / 2 'build four scan lines for half a row + +build_2x rdlong vscl,ctrb 'get pair of words from the tile array + + movs col0,vscl 'get color bits from even tile + andn col0,#$1C0 + + andn vscl,#$3F 'strip color bits and add tile line offset + add vscl,tile_line + +col0 mov colors+0,palettes 'get even tile color + add col0,d1 + +pix0 rdlong pixels0+0,vscl 'get line +0 even tile pixels + add pix0,d1 + add vscl,#4 + +pix1 rdlong pixels1+0,vscl 'get line +1 even tile pixels + add pix1,d1 + add vscl,#4 + +pix2 rdlong pixels2+0,vscl 'get line +2 even tile pixels + add pix2,d1 + add vscl,#4 + +pix3 rdlong pixels3+0,vscl 'get line +3 even tile pixels + add pix3,d1 + + add ctrb,#2 * 2 'point to next pair of tile words + shr vscl,#16 'shift odd tile word into position + + movs col1,vscl 'get color bits from odd tile + andn col1,#$1C0 + + andn vscl,#$3F 'strip color bits and add tile line offset + add vscl,tile_line + +col1 mov colors+1,palettes 'get odd tile color + add col1,d1 + +pix4 rdlong pixels0+1,vscl 'get line +0 odd tile pixels + add pix4,d1 + add vscl,#4 + +pix5 rdlong pixels1+1,vscl 'get line +1 odd tile pixels + add pix5,d1 + add vscl,#4 + +pix6 rdlong pixels2+1,vscl 'get line +2 odd tile pixels + add pix6,d1 + add vscl,#4 + +pix7 rdlong pixels3+1,vscl 'get line +3 odd tile pixels + add pix7,d1 + djnz inb,#build_2x 'loop for next tile pair (48 inst/loop) + + djnz ina,#build_32x 'if first half done, loop for 2nd waitvid + + sub ctrb,#xtiles * 2 'back up to start of same row + +' Display four scan lines + + mov inb,#4 'ready for four scan lines + movs :waitvid,#pixels0 'reset waitvid pixel pointer + +:line mov ina,#xtiles 'ready for tiles + movd :waitvid,#colors 'reset waitvid color pointer + mov vscl,vscl_tile 'set pixel rate for tiles + +:tile cmp ina,#1 wz 'check if last tile + add :waitvid,d0s0 'advance pointers (waitvid already read) +:waitvid waitvid colors,pixels0 'do tile slice + if_nz djnz ina,#:tile 'strange loop allows hsync timing and ina=1 + + call #hsync 'do horizontal sync (ina=1) + + djnz inb,#:line 'another scan line? + +' Another four scan lines? + + add tile_line,#8 * 4 'advance eight scan lines within tile row +tile_bytes cmpsub tile_line,#16 * 4 wc 'tile row done? (# doubled for mode 1) + if_c add ctrb,#xtiles * 2 'if done, advance array pointer to next row + + djnz cnt,#build_4y 'another four scan lines? + + sub ctrb,array_bytes 'display done, reset array pointer to top row + +' Visible section done, handle sync indicator + + cmp cnt,phsb wz 'sync enabled? (cnt=0) + if_nz wrlong neg1,phsb 'if so, write -1 to sync indicator + +' Do vertical sync lines and loop + +vf_lines mov ina,#vf + 2 'do vertical front porch lines (adjusted ±2) + call #blank + +vsync mov ina,#vs 'do vertical sync lines + call #blank_vsync + +vb_lines mov ina,#vb - 2 'do vertical back porch lines (adjusted ±2) + movs blank_vsync_ret,#field '(loop to field, blank_vsync follows) + +' Subroutine - do blank lines + +blank_vsync xor hv_sync,#$0101 'flip vertical sync bits + +blank mov vscl,vscl_blank 'do horizontal blank pixels + waitvid hv_sync,#0 + +hsync mov vscl,#hf 'do horizontal front porch pixels + waitvid hv_sync,#0 + + mov vscl,#hs 'do horizontal sync pixels + waitvid hv_sync,#1 + + rdlong vscl,frqb 'update another palette + and vscl,color_mask +:palette mov palettes,vscl + add :palette,d0 + add frqb,#4 + add par,count_64 wc + if_c movd :palette,#palettes + if_c sub frqb,#64 * 4 + + mov vscl,#hb 'do horizontal back porch pixels + waitvid hv_sync,#0 + + djnz ina,#blank 'another blank line? +hsync_ret +blank_ret +blank_vsync_ret ret + +' Data + +d0s0 long 1 << 9 + 1 'd and s field increments +d0 long 1 << 9 'd field increment +d1 long 2 << 9 'd field double increment + +tile_line long 2 * 4 'tile line offset (adjusted ±2 * 4) +array_bytes long xtiles * ytiles * 2 'number of bytes in tile array + +vscl_two_lines long ht * 2 'total pixels per two scan lines +vscl_tile long 1 << 12 + 16 '16 pixels per tile with 1 clock per pixel +vscl_blank long hp 'visible pixels per scan line + +hv_sync long $0200 '+/-H,-V states +count_64 long $04000000 'addend that sets carry every 64th addition +color_mask long $FCFCFCFC 'mask to isolate R,G,B bits from H,V +neg1 long $FFFFFFFF 'negative 1 to be written to sync indicator \ No newline at end of file diff --git a/source/stracker/regnatix/stplay.bin b/source/stracker/regnatix/stplay.bin new file mode 100644 index 0000000..6648434 Binary files /dev/null and b/source/stracker/regnatix/stplay.bin differ diff --git a/source/stracker/regnatix/stplay.spin b/source/stracker/regnatix/stplay.spin new file mode 100644 index 0000000..7c71b6a --- /dev/null +++ b/source/stracker/regnatix/stplay.spin @@ -0,0 +1,625 @@ +{{ +┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Autor: Ingo Kripahle │ +│ Copyright (c) 2010 Ingo Kripahle │ +│ See end of file for terms of use. │ +│ Die Nutzungsbedingungen befinden sich am Ende der Datei │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────┘ + +Informationen : hive-project.de +Kontakt : drohne235@googlemail.com +System : TriOS +Name : StarTracker +Chip : Regnatix +Typ : Programm +Version : 1 +Subversion : 1 +Funktion : HSS-Player mit LCARS-Oberfläche, Wiedergabe von allen Moduldateien im gleichen Verzeichnis +Installation : Folgende Dateien müssen in das Verzeichnis mit den HSS-Dateien kopiert werden: + + stplay.bin Regnatix-Code, Startdatei + stint.bel Bellatrix-Code des Players + +Komponenten : Bellatrix-Code basiert auf einer Idee und dem Testprogramm "lcars_xga_test" von Rayman. + Infos zum Programm von Rayman: + http://forums.parallax.com/forums/default.aspx?f=25&m=257204&p=1&ord=a + http://rayslogic.com/ + Assimilation zum Multiprop-Code: drohne235 + + Regnatix-Code stplay.spin Regnatix-Code + Bellatrix-Code stint.spin Bellatrix-Code + Bellatrix-Code stkeyb.spin + Bellatrix-Code stvga.spin + +COG's : 1 Cog +Logbuch : + +31.01.2009 - aus play.spin eine erste lauffähige version mit startreck-interface erstellt +01.02.2009 - tastenfunktionen +08.08.2009 - anpassung an module welche endflag setzen (player bieb dabei hängen) + - ursache: sync wartet obwohl player gestopt hat +01.12.2011 - anpassung an trios + - jetzt verwendung einer std.-ios + - funktioniert jetzt auch im unterverzeichnis + - kosmetische änderungen + +Kommandoliste : +Notizen : + +}} + +OBJ + ios: "reg-ios" + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +OS_TIBLEN = 64 'größe des inputbuffers + +'definition der interfaceelemente + +title = 0 +footer = 1 +button1 = 2 +button2 = 3 +button3 = 4 +button4 = 5 +button5 = 6 +button6 = 7 +button7 = 8 +button8 = 9 +button9 = 10 +corner_topleft = 11 +corner_topright = 12 +corner_bottomLeft = 13 +endcap_med_left = 14 +endcap_med_right = 15 +endcap_small_left = 16 +endcap_small_right = 17 + +CON 'BELLATRIX-FUNKTIONEN -------------------------------------------------------------------------- + +' einzeichen-steuercodes + +#$0, BEL_CMD 'esc-code für zweizeichen-steuersequenzen + BEL_CLS + BEL_HOME + BEL_POS1 + BEL_CURON + BEL_CUROFF + BEL_SCRLUP + BEL_SCRLDOWN + BEL_BS + BEL_TAB + +' zweizeichen-steuersequenzen +' [BEL_CMD][...] + +#$1, BEL_KEY_STAT + BEL_KEY_CODE + BEL_SCRCMD 'esc-code für dreizeichen-sequenzen + BEL_KEY_SPEC + BEL_SCR_LOGO + BEL_SCR_CHAR + BEL_BLKTRANS + +#$57, BMGR_LOAD + BMGR_WSCR + BMGR_DSCR + BMGR_GETCOLOR + BMGR_SETCOLOR + BMGR_GETRESX + BMGR_GETRESY + BMGR_GETCOLS + BMGR_GETROWS + BMGR_GETCOGS + BMGR_GETSPEC + BMGR_GETVER + BMGR_REBOOT + +' dreizeichen-steuersequenzen +' [BEL_CMD][BEL_SCRCMD][...] + +#$1, BEL_SETCUR + BEL_SETX + BEL_SETY + BEL_GETX + BEL_GETY + BEL_SETCOL + BEL_SLINE + BEL_ELINE + BEL_SINIT + BEL_TABSET + +VAR + + long lcnt 'zeiger für dateiliste + byte fn[12] 'puffer für dateinamen + byte gcol 'grundfarbe + byte cmdstat 'aktuelles kommandobutton + byte cmdreload + byte cmdnext + byte cmdps + +PUB main | wflag + + wflag := ios.start 'ios initialisieren + + ios.belload(string("stint.bel")) 'grafiktreiber laden + ios.admsetsyssnd(0) + + scr_sline(0) + + frame1 'interface zeichnen + cmdstat := 0 + cmdps := 0 + cmdreload := 0 + cmdnext := 0 + command + repeat + playint 'playliste abspielen + repeat + ios.hss_stop + if ios.keystat > 0 + command + while cmdps 'warten solange stopmodus + +PUB playint | fnadr,len,fcnt,i 'alle songs auf der sd-card abspielen + + ios.curhome + ios.sddir 'kommando: verzeichnis öffnen + startlist 'zum listenanfang + fcnt := 0 'zähler für dateianzahl + repeat while (fnadr := ios.sdnext) 'dateiliste einlesen + if str_find(fnadr,@ext1) + printmcnt(++fcnt) + wrfn(fnadr) + startlist 'zum listenanfang + if fcnt + repeat i from 0 to fcnt-1 'dateiliste abspielen + rdfn(@fn) + playsong(@fn) + if cmdnext==0 AND cmdps==0 AND cmdreload==0 'ausblenden nur bei playliste + fadeout + else + cmdnext := 0 + ios.hss_stop + if cmdreload + cmdreload := 0 + quit + if cmdps + quit + +PUB str_find(string1, string2) : buffer | counter 'sys: string suchen + + repeat strsize(string1--) + if(byte[++string1] == byte[string2]) + repeat counter from 0 to (strsize(string2) - 1) + if(byte[string1][counter] <> byte[string2][counter]) + buffer~~ + ifnot(buffer~) + return string1 + +PUB playsong(stradr) | n,i,note,okt,vol,fx,ins,rep,cc1,cc2,cc3,cc4,eflag 'spielt einen song ab + printsong(stradr) + ios.hss_stop + ios.hss_playfile(stradr) + cc1 := 0 + cc2 := 0 + cc3 := 0 + cc4 := 0 + repeat + sync 'synchronisation mit beat + rep := ios.hss_intreg(ios#iRepeat) 'loopzähler auslesen + eflag := ios.hss_intreg(ios#iEndFlag) 'endflag abfragen + printrep(rep) 'zähler auf screen aktualisieren + if ios.keystat > 0 'tasteneingabe? + command + repeat i from 1 to 4 'schleife für die vier kanäle + + note := ios.hss_intreg(i*5+ios#iNote) + okt := ios.hss_intreg(i*5+ios#iOktave) + vol := ios.hss_intreg(i*5+ios#iVolume) + fx := ios.hss_intreg(i*5+ios#iEffekt) + ins := ios.hss_intreg(i*5+ios#iInstrument) + printchan(33,2+i,note,okt,vol,fx,ins) + + '---------------------------------------- + if note > 0 'bei note bargraph triggern + case i + 1: cc1 := 1 + 2: cc2 := 1 + 3: cc3 := 1 + 4: cc4 := 1 + '---------------------------------------- + case i 'numerischen pegelwert ausgeben + 1: ios.printhex(cc1,2) + 2: ios.printhex(cc2,2) + 3: ios.printhex(cc3,2) + 4: ios.printhex(cc4,2) + if rep == 3 + cc1 := 10 + cc2 := 10 + cc3 := 10 + cc4 := 10 + bar(8,5 ,button1,0,cc1) 'bargraphen zeichen + bar(8,8 ,button2,1,cc2) + bar(8,11,button3,2,cc3) + bar(8,14,button4,3,cc4) + if cc1 < 10 'pegel absenken + cc1++ + if cc2 < 10 + cc2++ + if cc3 < 10 + cc3++ + if cc4 < 10 + cc4++ + until rep == 3 OR cmdnext OR cmdreload OR cmdps OR eflag == 1 'drei loops, endflag oder kommandos brechen ab + +PUB command | k 'tastatur abfragen + k := ios.key + case k + 4: if cmdstat > 0 'pfeil hoch + cmdstat-- + else + cmdstat := 3 + 5: if cmdstat < 3 'pfeil runter + cmdstat++ + else + cmdstat := 0 + 13: case cmdstat 'eingabetaste + 0: if cmdps == 1 + cmdps := 0 + else + cmdps := 1 + 1: cmdreload := 1 + 2: cmdnext := 1 + 3: ios.printcls + ios.hss_stop 'hss-player stoppen + ios.ram_wrbyte(ios#sysmod,0,ios#SIFLAG)'screeninit für cli aktivieren + ios.admsetsyssnd(1) 'systemklänge wieder anschalten + ios.sddmact(ios#DM_ROOT) 'suche in root + ios.belreset 'systemgrafiktreiber laden + ios.stop 'programm beenden + + case cmdstat 'led-buttons neu zeichen + 0: button(8,22,13,button6,1,0,0) + button(8,25,13,button7,2,0,0) + button(8,28,13,button8,2,0,0) + button(8,31,13,button9,2,0,0) + 1: button(8,22,13,button6,2,0,0) + button(8,25,13,button7,1,0,0) + button(8,28,13,button8,2,0,0) + button(8,31,13,button9,2,0,0) + 2: button(8,22,13,button6,2,0,0) + button(8,25,13,button7,2,0,0) + button(8,28,13,button8,1,0,0) + button(8,31,13,button9,2,0,0) + 3: button(8,22,13,button6,2,0,0) + button(8,25,13,button7,2,0,0) + button(8,28,13,button8,2,0,0) + button(8,31,13,button9,1,0,0) + +PUB sync 'synchronisation mit beat + repeat + until ios.hss_intreg(ios#iRowFlag) == 0 or ios.hss_intreg(ios#iEndFlag) == 1 + repeat + until ios.hss_intreg(ios#iRowFlag) == 1 or ios.hss_intreg(ios#iEndFlag) == 1 + +PUB fadeout | i 'song langsam ausblenden + repeat i from 0 to 15 + ios.hss_vol(15 - i) + if ios.keystat > 0 + command + waitcnt(cnt + 60_000_000) + waitcnt(cnt + 30_000_000) + +PUB wrfn(stradr) | len,i 'kopiert dateinamen bei lcnt in eram + len := strsize(stradr) + repeat i from 0 to len-1 + ios.ram_wrbyte(ios#usrmod,byte[stradr][i],lcnt++) + ios.ram_wrbyte(ios#usrmod,0,lcnt++) + +PUB rdfn(stradr) | i,n 'liest dateinamen bei lcnt aus eram, lcnt wird dabei erhöht + i := 0 + repeat + n := ios.ram_rdbyte(ios#usrmod,lcnt++) + byte[stradr][i++] := n + while n <> 0 + +PUB startlist 'zeiger auf listenanfang (dateinamen) + lcnt := 0 + +PUB printnote(n) 'nummer --> notenzeichen +'C1,C#1,D1,D#1,E1,F1,F#1,G1,G#1,A1,A#1,H1 + case n + 0: ios.printq(string("▶ ")) + 1: ios.printq(string("C ")) + 2: ios.printq(string("C• ")) + 3: ios.printq(string("D ")) + 4: ios.printq(string("D• ")) + 5: ios.printq(string("E ")) + 6: ios.printq(string("F ")) + 7: ios.printq(string("F• ")) + 8: ios.printq(string("G ")) + 9: ios.printq(string("G• ")) + 10: ios.printq(string("A ")) + 11: ios.printq(string("A• ")) + 12: ios.printq(string("H ")) + +PUB printmcnt(n) 'ausgabe der anzahl + printat(25,13,0,string("Anzahl Dateien : ")) + ios.printdec(n) + +PUB printsong(stradr) 'ausgabe des songnamens + printat(25,14,0, string("PlaySong : ")) + printat(42,14,0,string(" ")) + printat(42,14,0,stradr) + dtext(button5,string("____________________")) + dtext(button5,stradr) + +PUB printrep(rep) 'ausgabe der loops + printat(25,15,0,string("Repeat : ")) + printatdec(42,15,0,rep) + +PUB printeflag(eflag) 'ausgabe EndFlag + printat(25,16,0,string("EndFlag : ")) + printatdec(42,16,0,eflag) + +{ +PUB printdeb(deb) 'ausgabe debug-marke + printat(25,17,0,string("Mark : ")) + printatdec(42,17,0,deb) +} + +PUB at(x,y,color) 'cursorposition und farbe setzen + ios.cursetx(x) + ios.cursety(y) + ios.setcolor(color) + +PUB printat(x,y,color,strptr) 'string bei position mit farbe ausgeben + at(x,y,color) + ios.print(strptr) + +PUB printatdec(x,y,color,wert) 'zahl bei position mit farbe ausgeben + ios.cursetx(x) + ios.cursety(y) + ios.setcolor(color) + ios.printdec(wert) + +PUB frame1 | i,sline 'hauptframe zeichnen + ios.curoff + ios.printcls + gcol := 0 + sline := 24 +' 64 x 48 - 32,24 + + dtext(title,string("STARTRACKER ",95," LOADING ...")) 'text in button rendern + top(8,sline) 'initiale ladezeile zeichnen + ton1 + + dtext(footer,string("DROHNE235 ",95," 2009 ")) 'restliche buttons rendern + dtext(button1,string("ENGINE A ")) + dtext(button2,string("ENGINE B ")) + dtext(button3,string("ENGINE C ")) + dtext(button4,string("ENGINE D ")) + dtext(button5,string(" DATEI ")) + dtext(button6,string("PLAY ",95," STOP")) + dtext(button7,string("RELOAD ")) + dtext(button8,string("NEXT SONG ")) + dtext(button9,string("QUIT ")) + + + repeat (sline / 2) - 1 'ladezeile nach oben verschieben + ios.scrollup + waitcnt(cnt + 1_000_000) + + top(8,2) 'kopfzeile zeichnen + ton1 + dtext(title,string("STARTRACKER ",95," HIVE-PROJEKT")) + + repeat i from 0 to 10 'pegel zeichnen + 'x,y,nButton,color,pegel + bar(8,5 ,button1,0,i) + bar(8,8 ,button2,1,i) + bar(8,11,button3,2,i) + bar(8,14,button4,3,i) + ios.sfx_fire($f1,0) + waitcnt(cnt + 4_000_000) + + log2(24,5) + + 'x,y,len,nButton,col1,col2,col3 + 'orange=0,blue=1,past=2,purple=3,weiß=4,magenta=5 + button(8,22,13,button6,2,0,0) + button(8,25,13,button7,2,0,0) + button(8,28,13,button8,2,0,0) + button(8,31,13,button9,2,0,0) + + info(25,22,15,button5,0,1) + + bottom(8,36) + +PUB info(x,y,len,nButton,col1,col2) 'infobereich zeichnen + bmap(endcap_med_left,x,y,1,2,col1) + box(x+1,y,2,2,col1,false,false,false) + box(x+13,y,len-13,2,col1,false,false,false) + bmap(nButton,x+4,y,8,2,col2) + bmap(endcap_med_right,x+len,y,1,2,col1) + +PUB log1(x,y) 'einen vollen logbereich zeichnen + 'left,top,width,height,clr,bBottomBreak,bRightBreak,bTrimRight + 'top + bmap(corner_topleft,x,y,6,2,1) + box(x+6,y,8,1,1,false,true,false) + box(x+14,y,5,1,2,false,true,false) + box(x+19,y,11,1,0,false,true,false) + 'middle + box(x,y+2,4,1,1,true,false,false) + box(x,y+3,4,4,3,true,false,false) + box(x,y+7,4,2,0,true,false,false) + box(x,y+9,4,5,2,true,false,false) + 'box(x,y+4,4,1,1,false,false,false) + 'bottom + bmap(corner_bottomleft,x,y+14,6,2,1) + box(x+6,y+15,3,1,1,false,true,false) + box(x+9,y+15,12,1,0,false,true,false) + box(x+21,y+15,4,1,2,false,true,false) + box(x+25,y+15,5,1,1,false,true,false) + +PUB log2(x,y) 'einen halben logbereich zeichnen + 'left,top,width,height,clr,bBottomBreak,bRightBreak,bTrimRight + 'mitte + box(x,y,4,1,1,true,false,false) + box(x,y+1,4,4,3,true,false,false) + box(x,y+5,4,2,0,true,false,false) + box(x,y+7,4,5,2,true,false,false) + 'box(x,y+4,4,1,1,false,false,false) + 'unten + bmap(corner_bottomleft,x,y+12,6,2,1) + box(x+6,y+13,3,1,1,false,true,false) + box(x+9,y+13,12,1,0,false,true,false) + box(x+21,y+13,4,1,2,false,true,false) + box(x+25,y+13,5,1,1,false,true,false) + +PUB button(x,y,len,nButton,col1,col2,col3) 'zeichnet schaltfläche + box(x,y,1,2,col1,false,false,false) + box(x+2,y,len-2,2,col2,false,false,false) + bmap(nButton,x+2,y,8,2,col2) + bmap(endcap_med_right,x+len,y,1,2,col2) + +PUB top(x,y) 'zeichnet kopfzeile + bmap(title,x+15,y,21,2,gcol) + box(x+2,y,12,2,2,false,false,false) + box(x+34,y,12,2,2,false,false,false) + bmap(endcap_med_left,x,y,1,2,1) + bmap(endcap_med_right,x+47,y,1,2,1) + +PUB bottom(x,y) 'zeichnet kopfzeile + bmap(footer,x+2,y,15,2,gcol) + box(x+14,y,32,2,2,false,false,false) + bmap(endcap_med_left,x,y,1,2,1) + bmap(endcap_med_right,x+47,y,1,2,1) + +PUB bar(x,y,nButton,color,pegel) 'zeichnet einen bargraf + bmap(endcap_med_left,x,y,1,2,color) + bmap(nButton,x+2,y,pegel,2,gcol) + box(x+2+pegel,y,x+4-pegel,2,color,false,false,false) + +PUB ton1 'ultimativerstartrecksound + repeat 4 + ios.sfx_fire($f1,0) + waitcnt(cnt + 4_000_000) + +CON 'INTERFACEROUTINEN + +PUB bmap(nBitmap,xPos,yPos,xSize,ySize,clr) 'screen: 1bit-bitmap zeichnen +{{ nBitmap: + 0: title + 1: footer + 2: button1 + 3: button2 + 4: button3 + 5: button4 + 6: button5 + 7: corner_topleft + 8: corner_topright + 9: corner_bottomLeft + 10: endcap_med_left + 11: endcap_med_right + 12: endcap_small_left + 13: endcap_small_right +}} + + ios.bus_putchar2(0) + ios.bus_putchar2(10) + ios.bus_putchar2(nBitmap) + ios.bus_putchar2(xPos) + ios.bus_putchar2(yPos) + ios.bus_putchar2(xSize) + ios.bus_putchar2(ySize) + ios.bus_putchar2(clr) + +PUB box(pleft,ptop,pwidth,pheight,pclr,bBottomBreak,bRightBreak,bTrimRight) 'screen: farbige box zeichnen + 'blue=1 + 'purple=3 + 'orange=0 + 'red=2 + + ios.bus_putchar2(0) + ios.bus_putchar2(11) + ios.bus_putchar2(pleft) + ios.bus_putchar2(ptop) + ios.bus_putchar2(pwidth) + ios.bus_putchar2(pheight) + ios.bus_putchar2(pclr) + ios.bus_putchar2(bBottomBreak) + ios.bus_putchar2(bRightBreak) + ios.bus_putchar2(bTrimRight) + + +PUB dtext(nButton,stradr) | nLen 'screen: text in button zeichnen +{{Nur Großbuchstaben!}} + nLen := strsize(stradr) + ios.bus_putchar2(0) + ios.bus_putchar2(12) + ios.bus_putchar2(nButton) + ios.bus_putchar2(nLen) + repeat nLen + ios.bus_putchar2(byte[stradr++]) + +PRI printchan(x,y,note,okt,vol,fx,ins) + + ios.bus_putchar2(0) + ios.bus_putchar2(13) + ios.bus_putchar2(x) + ios.bus_putchar2(y) + ios.bus_putchar2(note) + ios.bus_putchar2(okt) + ios.bus_putchar2(vol) + ios.bus_putchar2(fx) + ios.bus_putchar2(ins) + +PUB printctrl(c) 'screen: präfix für steuersequenzen +{{printctrl(c) - screen: steuerzeichen von $100 bis $1FF wird an terminal gesendet}} + ios.bus_putchar2(BEL_CMD) 'kommandosequenz einleiten + ios.bus_putchar2(BEL_SCRCMD) 'code 3 = sonderzeichen senden + ios.bus_putchar2(c & $0FF) 'unteres byte senden ' + + +PUB scr_sline(n) 'screen: startzeile scrollbereich setzen +{{sline(n) - startzeile scrollbereich setzen}} + printctrl(BEL_SLINE) + ios.bus_putchar2(n) + +PUB scr_eline(n) 'screen: endzeile scrollbereich setzen +{{sline(n) - endzeile scrollbereich setzen}} + printctrl(BEL_ELINE) + ios.bus_putchar2(n) + + +DAT +ext1 byte ".HSS",0 + +DAT + +{{ + +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ TERMS OF USE: MIT License │ +├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ +│Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ +│files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ +│modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ +│is furnished to do so, subject to the following conditions: │ +│ │ +│The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ +│ │ +│THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ +│WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ +│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ +│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +}} diff --git a/source/vecdem/vecdem.spin b/source/vecdem/vecdem.spin new file mode 100644 index 0000000..01565ac --- /dev/null +++ b/source/vecdem/vecdem.spin @@ -0,0 +1,257 @@ +{{ + +Hive-Computer-Projekt + +Name : Vektron VGA-Vektorgrafik-Engine +Chip : Bellatrix-Code (bios) +Version : 0 +Dateien : + +23.10.2008 - idee und frame + +}} + +CON + +_CLKMODE = XTAL1 + PLL16X +_XINFREQ = 5_000_000 + +'signaldefinitionen regnatix + +#0, D0,D1,D2,D3,D4,D5,D6,D7 'datenbus +#8, BEL_VGABASE 'vga-signale (8pin) +#16, BEL_KEYBC,BEL_KEYBD 'keyboard-signale +#18, BEL_MOUSEC,BEL_MOUSED 'maus-signale +#20, BEL_VIDBASE 'video-signale(3pin) +#23, BEL_SELECT 'belatrix-auswahlsignal +#24, HBEAT 'front-led + BUSCLK 'bustakt + BUS_WR '/wr - schreibsignal + BUS_HS ' '/hs - quittungssignal + + +VGA_BASPORT = 8 'vga startport +KEYB_DPORT = BEL_KEYBD 'tastatur datenport +KEYB_CPORT = BEL_KEYBC 'tastatur taktport + +DB_WAIT = %00000001_00000000_00000000_00000000 'dira-wert f?r wait-status am bus +DB_IN = %00001001_00000000_00000000_00000000 'dira-wert f?r datenbuseingabe +DB_OUT = %00001001_00000000_00000000_11111111 'dira-wert f?r datenbusausgabe +CNT_HBEAT = 5_000_0000 'blinkgeschw. front-led + +'512x384 + +tiles = vec#tiles + +OBJ + + vec : "vectron-1-asm" + key : "bel-keyb" + +PUB MainLoop|h,i,deg,x,y,char,j,k,n + + vec.start + key.start(keyb_dport, keyb_cport) 'tastaturport starten + + + repeat i from 0 to tiles - 1 'init tile colors to white on black +'' hintergrund vordergrund +'' "1" "0" "1" "0" +'' %RRGGBB00_RRGGBB00_RRGGBB00_RRGGBB00 + vec.color(i,%00000000_00000000_11000000_00000000) 'rot auf schwarz +' vec.color(i,%00000000_00000000_11000000_10100000) 'rot auf gold +' vec.color(i,$FF<<8+i) 'init tile colors "Nice view" + + vec.pointcolor(1) + + repeat + vec.pointcolor(1) + + back1 'rot auf schwarz + + repeat 1 'dreieck größer + repeat j from 10 to 280 step 8 + ifexit + repeat i from 0 to 359 step 1 + n := vec.deg(i) + vec.shape(256,192,j,j,3,n) + + repeat 2 'dreiecke hive blinkt + repeat i from 0 to 359 step 1 + ifexit + 'vec.syncvid + n := vec.deg(i) + vec.shape(256,192,280,280,3,n) + n := vec.deg(i<<2) + vec.shape(256,192,280,280,3,n) + n := i & i>>3 + ifnot n + vec.text(195,175,string("◀ Hive ▶")) + + repeat 5 'dreiecke hive + repeat i from 0 to 359 step 1 + ifexit + 'vec.syncvid + n := vec.deg(i) + vec.shape(256,192,280,280,3,n) + n := vec.deg(i<<2) + vec.shape(256,192,280,280,3,n) + vec.text(195,175,string("◀ Hive ▶")) + + repeat 2 'dreiecke hive blinkt + repeat i from 0 to 359 step 1 + ifexit + 'vec.syncvid + n := vec.deg(i) + vec.shape(256,192,280,280,3,n) + n := vec.deg(i<<2) + vec.shape(256,192,280,280,3,n) + n := i & i>>3 + ifnot n + vec.text(195,175,string("◀ Hive ▶")) + + repeat 1 'dreieck kleiner + repeat j from 280 to 10 step 8 + ifexit + repeat i from 0 to 359 step 1 + 'vec.syncvid + n := vec.deg(i) + vec.shape(256,192,j,j,3,n) + + repeat j from 0 to 900 'gittertext + ifexit + vec.shape(140+(j>>2),90+(j>>3),140,140,3,n<<3) + vec.shape(130+(j>>2),80+(j>>3),120,120,3,n<<3) + vec.shape(120+(j>>2),70+(j>>3),100,100,3,n<<3) + vec.shape(110+(j>>2),60+(j>>3), 80, 80,3,n<<3) + vec.shape(100+(j>>2),50+(j>>3), 60, 60,3,n<<3) + + vec.character(1+k,350,"▶") + vec.character(512-k,350,"◀") + if k++ > 512 + k := 0 + + vec.text(50+j>>3+n>>2,50+j>>3+n>>2,string("◀ Hive: Vectron ▶")) + repeat i from 1 to 90 step 5 + n := (vec.sine(vec.deg(i+j)) >> 7) + vec.line(n,0,n,384) + repeat i from 1 to 90 step 5 + n := (vec.sine(vec.deg(i+j)) >> 7) + vec.line(0,n,512,n) + + repeat j from 0 to 200 'gitter + ifexit + repeat i from 1 to 90 step 5 + n := (vec.sine(vec.deg(i+j)) >> 7) + vec.line(n,0,n,384) + repeat i from 1 to 90 step 5 + n := (vec.sine(vec.deg(i+j)) >> 7) + vec.line(0,n,512,n) + + back2 'hintergrund farbig + repeat 150 'scroller + ifexit + repeat i from 0 to 359 step 5 + 'vec.syncvid + vec.text(195,0,string("◀ Vectron ▶")) + n := vec.deg(i) + k := vec.sine(vec.deg(i/2))>>9 + vec.shape(256-150,240-k,100,100,3,n) + vec.shape(256 ,240-k,100,100,3,n) + vec.shape(256+150,240-k,100,100,3,n) + case y + 0: vec.text(600-x,350,string("◀ Vectron: ")) + 1: vec.text(512-x,350,string("• Vektor-Koprozessor •")) + 2: vec.text(512-x,350,string("• Objekt-Koprozessor •")) + 3: vec.text(512-x,350,string("• VGA-Signal •")) + 4: vec.text(512-x,350,string("• 512 x 384 Pixel •")) + 5: vec.text(512-x,350,string("• 64 Farben •")) + 6: vec.text(512-x,350,string("• 1 Farben pro 32x32 Tile •")) + 7: vec.text(512-x,350,string("• Vectrex-Retro-Style •")) + 8: vec.text(512-x,350,string("• Hive-Project: ")) + 9: vec.text(512-x,350,string("• hive-project.de ▶")) + if x++ > 800 + x := 0 + if y++ > 9 + y := 0 + +PRI ifexit + + if key.key == key#Esc + reboot + +PRI back1 | i + repeat i from 0 to tiles - 1 'init tile colors to white on black +'' hintergrund vordergrund +'' "1" "0" "1" "0" +'' %RRGGBB00_RRGGBB00_RRGGBB00_RRGGBB00 + vec.color(i,%00000000_00000000_11000000_00000000) 'rot auf schwarz + +PRI back2 | i +''tiles := xtiles=16 * ytiles=12 + i := 0 + repeat 2 + repeat 16 +'' hintergrund vordergrund +'' "1" "0" "1" "0" +'' %RRGGBB00_RRGGBB00_RRGGBB00_RRGGBB00 + vec.color(i++,%00000000_00000000_01010000_00000000) 'rot auf schwarz + + repeat 8 + repeat 5 +'' hintergrund vordergrund +'' "1" "0" "1" "0" +'' %RRGGBB00_RRGGBB00_RRGGBB00_RRGGBB00 + vec.color(i++,%00000000_00000000_11000000_00000000) 'rot auf schwarz + repeat 6 +'' hintergrund vordergrund +'' "1" "0" "1" "0" +'' %RRGGBB00_RRGGBB00_RRGGBB00_RRGGBB00 + vec.color(i++,%00000000_00000000_00110000_00000000) 'rot auf schwarz + repeat 5 +'' hintergrund vordergrund +'' "1" "0" "1" "0" +'' %RRGGBB00_RRGGBB00_RRGGBB00_RRGGBB00 + vec.color(i++,%00000000_00000000_00001100_00000000) 'rot auf schwarz + + repeat 2 + repeat 16 +'' hintergrund vordergrund +'' "1" "0" "1" "0" +'' %RRGGBB00_RRGGBB00_RRGGBB00_RRGGBB00 + vec.color(i++,%00000000_00000000_01010000_00000000) 'rot auf schwarz + +PRI rest |x,y,i,n + + repeat 20 'dreieck + repeat i from 0 to 359 + 'vec.syncvid + n := vec.deg(i) + vec.shape(256,192,145,145,3,n) + + repeat 3 '3 x shape + repeat i from 0 to 359 + 'vec.syncvid + n := vec.deg(i) + vec.shape(256,192,145,145,3,n) + vec.shape(256,192,70,70,4,vec.deg(359-i*2)) + vec.shape(256,192,30,30,5,vec.deg(i*3)) + + repeat 3 + repeat i from 0 to 359 step 5 + repeat x from 100 to 400 step 150 + repeat y from 100 to 300 step 150 + shapes1(x,y,i) + +PRI shapes1(x,y,i) + 'vec.syncvid + vec.shape(x,y,145,145,3,vec.deg(i)) + vec.shape(x,y,70,70,4,vec.deg(359-i*2)) + vec.shape(x,y,30,30,5,vec.deg(i*3)) + +PRI keyreb 'bei teastendruck reboot + + if key.key + reboot + +DAT diff --git a/source/vecdem/vectron-1-asm.spin b/source/vecdem/vectron-1-asm.spin new file mode 100644 index 0000000..142140e --- /dev/null +++ b/source/vecdem/vectron-1-asm.spin @@ -0,0 +1,595 @@ +{ +******************************************** + VGA graphics Engine TestVersion +******************************************** +coded by Beau Schwabe (Parallax) +******************************************** + + +Version 1.0 - initial test release + + +} + +CON + tiles = vga#xtiles * vga#ytiles 'xtiles=16 ytiles 12 + tiles32 = tiles * 32 'tiles32=6144 + + #1, _Sine,_Cosine,_ArcSine,_Plot,_Point,_Character,_Line,_Box + +VAR + long cog, command + long sync, pixels[tiles32] + word colors[tiles] + byte pointcolor_ + byte textdata[33] + +OBJ + vga : "vectron-1-drv" + +CON'############################################################################################################# +' Entry/Exit Routines +'################################################################################################################ +PUB start : okay +'' returns false if no cog available + stop + vga.start(8, @colors, @pixels, @sync) 'start VGA driver + okay := cog := cognew(@loop, @command) + 1 'start VGA graphics & text driver + +PUB stop +'' Stop Assembly Function Engine - frees a cog + if cog + cogstop(cog~ - 1) 'stop VGA graphics & text driver + vga.stop 'stop VGA driver + command~ + +PUB syncvid 'wartet bis sync-fag gesetzt ist + repeat until sync + sync := 0 + +CON'############################################################################################################# +' Spin Assembly Calls +'################################################################################################################ +PUB Sine(Ang)|Arg1_ ' Input = 13-bit angle ranging from 0 to 8191 + 'Output = 16-bit Sine value ranging from $FFFF0001 ('-1') to $0000FFFF ('1') + setcommand(_Sine, @Ang) + Result := Arg1_ + +PUB Cosine(Ang)|Arg1_ ' Input = 13-bit angle ranging from 0 to 8191 + 'Output = 16-bit Cosine value ranging from $FFFF0001 ('-1') to $0000FFFF ('1') + setcommand(_Cosine, @Ang) + Result := Arg1_ + +PUB ArcSine(Ang)|Arg1_ ' Input = signed 16-bit value ranging from $FFFF0001 ('-1') to $0000FFFF ('1') + 'Output = signed 11-bit angle ranging from -2047 (-pi/2) to 2047 (pi/2) + setcommand(_ArcSine, @Ang) + Result := Arg1_ + +PUB ArcCosine(Ang)|Arg1_,sign ' Input = signed 16-bit value ranging from $FFFF0001 ('-1') to $0000FFFF ('1') + sign := Ang 'Output = signed 11-bit angle ranging from -2047 (-pi/2) to 2047 (pi/2) + Ang := || Ang + setcommand(_ArcSine, @Ang) + if sign <> Ang + sign := -1 + else + sign := 1 + Result := (Sin_90 - Arg1_)* sign + +PUB plot(x,y)| Arg2_,Arg3_,Arg4_ 'Sets pixel value at location x,y + Arg2_ := @pixels + Arg3_ := tiles32 + Arg4_ := pointcolor_ + setcommand(_Plot, @x) + +PUB point(x,y)| Arg2_,Arg3_,Arg4_ 'Reads pixel value at location x,y + Arg2_ := @pixels + Arg3_ := tiles32 + setcommand(_Point, @x) + Result := Arg4_ + +PUB character(offX,offY,chr)|Arg3_,Arg4_,Arg5_ 'Place a text character from the ROM table at offset location offsetX,offsetY + Arg5_ := chr + chr := @pixels '<-- Arg2 <--> Arg5 swap to maintain consistency with PLOT and POINT structures + Arg3_ := tiles32 + Arg4_ := pointcolor_ + setcommand(_Character, @offX) + +PUB line (px,py,dx,dy)| Arg4_,Arg5_,Arg6_,Arg7_,Arg8_ 'Draws line from px,py to dx,dy + Arg4_ := pointcolor_ + longmove(@Arg5_,@px,4) + dx := @pixels '<-- Arg2 thru Arg8 shift to maintain consistency with PLOT and POINT structures + dy := tiles32 + setcommand(_Line, @px) + +PUB box(x1,y1,x2,y2)| Arg4_,Arg5_,Arg6_,Arg7_,Arg8_ 'Draws a box from opposite corners x1,y1 and x2,y2 + Arg4_ := pointcolor_ + longmove(@Arg5_,@x1,4) + x2 := @pixels '<-- Arg2 thru Arg8 shift to maintain consistency with PLOT and POINT structures + y2 := tiles32 + setcommand(_Box, @x1) + +CON'############################################################################################################# +' Spin Routines +'################################################################################################################ +PUB color(tile,cval) 'Set Color tiles on VGA screen + colors[tile] := cval + +PUB pointcolor(pc) 'Sets pixel color "1" or "0" + pointcolor_ := pc + +PUB Text(offX,offY,Address)|chr,i 'Place a text string from the ROM table at offset location offsetX,offsetY + i := 0 + repeat + chr := byte[Address + i] + i++ + if chr <> 0 + character(offX,offY,chr) + offX := offX + 16 + else + quit + +PUB shape(x,y,sizeX,sizeY,sides,rotation)|angle,sx1,sy1,sx2,sy2 'Draws a shape with center located at x,y + if sides => 3 'sizeX and sizeY - control shape aspect ratio + repeat angle from 8191/sides to 8191 step 8191/sides ' sides - select the number shape sides + sx1 := x + sine(angle+rotation)*sizeX/131070 ' rotation - determines shape orientation + sy1 := y + cosine(angle+rotation)*sizeY/131070 + sx2 := x + sine(angle+rotation+8191/sides)*sizeX/131070 + sy2 := y + cosine(angle+rotation+8191/sides)*sizeY/131070 + line(sx1,sy1,sx2,sy2) + +PUB deg(angle) 'translate deg(0-360) ---> to ---> 13-bit angle(0-8192) + return (angle * 1024)/45 + +PUB bit13(angle) 'translate 13-bit angle(0-8192) ---> to ---> deg(0-360) + return (angle * 45)/1024 + +PUB SimpleNum(x,y,DecimalNumber,DecimalPoint)|sign,DecimalIndex,TempNum,spacing,DecimalFlag,Digit +{ x,y - upper right text coordinate of MSD (Most Significant Digit) + DecimalNumber - signed Decimal number + DecimalPoint - number of places from the Right the decimal point should be +} + spacing := 16 + DecimalIndex := 0 + + TempNum := DecimalNumber 'Preserve sign of DecimalNumber + DecimalNumber := ||DecimalNumber + if DecimalNumber <> TempNum + sign := 1 + else + sign := 0 + + + if DecimalPoint == 0 + character(x,y,$30) 'Insert Zero + x := x - spacing + repeat 'Print digits + if DecimalIndex == DecimalPoint + character(x,y,$2E) 'Insert decimal point at proper location + x := x - spacing + + + TempNum := DecimalNumber 'Extract the least significant digit + TempNum := DecimalNumber - ((TempNum / 10) * 10) + + Digit := $30 + TempNum 'Display the least significant digit + character(x,y,Digit) + + x := x - spacing + DecimalIndex := DecimalIndex + 1 + DecimalNumber := DecimalNumber / 10 'Divide DecimalNumber by 10 + + if DecimalNumber == 0 'Exit logic + repeat while DecimalIndex < DecimalPoint ' Do this if DecimalNumber is less than where the decimal point should be + character(x,y,$30) + x := x - spacing + DecimalIndex := DecimalIndex + 1 + DecimalFlag := 1 + if DecimalIndex == DecimalPoint ' Set flag if DecimalNumber is equal to where the decimal point should be + DecimalFlag := 1 + if DecimalFlag == 1 + character(x,y,$2E) ' Insert decimal and leading Zero + x := x - spacing + character(x,y,$30) + x := x - spacing + if sign == 1 ' Restore sign of DecimalNumber + character(x,y,$2D) + quit + + +PRI setcommand(cmd, argptr) + command := cmd << 16 + argptr 'write command and pointer + repeat while command 'wait for command to be cleared, signifying receipt + +CON'############################################################################################################# +' Assembly Routines +'################################################################################################################ +DAT + org +' +' +' VGA graphics Engine - main loop +' +' t1..t15 temporäre variablen +loop rdlong t1,par wz 'wait for command + if_z jmp #loop 'wenn zeiger 0 dann ohne parameter + + 't1 zeiger auf parameter + 't2 indexzeiger auf parameter + 't3 schleifenindex + '------------------------------- 9 parameter einlesen + movd :arg,#arg0 'setze zeiger in :arg + mov t2,t1 'zeiger auf parameter + mov t3,#9 'schleifenindex +:arg rdlong arg0,t2 'arg0 <-- (t2) parameter einlesen + add :arg,d0 '(s-field in :arg) + 1 (d0 enthält $200 = 1 << 9) + add t2,#4 'zeiger auf parameter erhöhen + djnz t3,#:arg '9 x schleife + + 't1 zeiger auf parameter + 't2 sprungziel + '------------------------------- + mov AddressLocation,t1 'sichere zeiger um später evtl. resultate an + 'spin zu übergeben + wrlong zero,par 'zero command to signify command received + ror t1,#16+2 'lookup command address 't1 <- (16 + 2) + add t1,#jumps 't1 := t1 + @jumps + movs :table,t1 'code bei :table modifizieren + rol t1,#2 't1 -> 2 + shl t1,#3 't1 >> 3 +:table mov t2,0 'modifizierte quelle nach t2 kopieren + shr t2,t1 + and t2,#$FF + jmp t2 'jump to command +jumps byte 0 '0 + byte Sine_ '1 + byte Cosine_ '2 + byte ArcSine_ '3 + byte Plot_ '─┐ + byte Point_ ' │ + byte Character_ ' ┣─ Additional functions MUST be in groups of 4-bytes (1 long) + byte Line_ '─┘ With this setup, there is a limit of 256 possible functions. + byte Box_ + byte NotUsed_ + byte NotUsed_ + byte NotUsed_ +NotUsed_ + jmp #loop +{################################################################################################################ + +Sine/cosine + +quadrant: 1 2 3 4 +angle: $0000...$07FF $0800...$0FFF $1000...$17FF $1800...$1FFF +table index: $0000...$07FF $0800...$0001 $0000...$07FF $0800...$0001 +mirror: +offset -offset +offset -offset +flip: +sample +sample -sample -sample + +on entry: sin[12..0] holds angle (0° to just under 360°) +on exit: sin holds signed value ranging from $0000FFFF ('1') to $FFFF0001 ('-1') + +} +Cosine_ mov t1, Arg0 '<--- cosine entry + add t1, sin_90 + jmp #CSentry +Sine_ mov t1, Arg0 '<--- sine entry + +CSentry test t1, Sin_90 wc + test t1, Sin_180 wz + negc t1, t1 + or t1, Sin_Table + shl t1, #1 + rdword t1, t1 + negnz t1, t1 + mov t2, AddressLocation 'Write data back to Arg1 + add t2, #4 + wrlong t1, t2 + '<--- cosine/sine exit + jmp #loop 'Go wait for next command +{################################################################################################################ + +ArcSine/ArcCosine + +on entry: t2 holds signed 16-bit value ranging from $FFFF0001 ('-1') to $0000FFFF ('1') +on exit: t7 holds signed 11-bit angle ranging from -2047 (-pi/2) to 2047 (pi/2) + +} +ArcSine_ '<--- ArcSine entry (t2) + mov t2, Arg0 + mov t3, t2 'Preserve sign (t3) ; if '-' then t3 = 1 + shr t3, #31 + abs t2, t2 'Convert to absolute value + mov t4, sin_90 'Preload RefHigh (t4) to 2048 + mov t5, #0 'Preload RefLow (t5) to 0 + mov t6, #11 'Iterations (t6) - equals # of bits on output resolution. +Iteration_Loop + mov t7, t4 'Add RefHigh and RefLow ; divide by 2 to get Pivot point (t7) + add t7, t5 + shr t7, #1 + mov t8, t7 'Lookup sine value from Pivot location ; range 0-2048 ; 0 to pi/2 + or t8, sin_table + shl t8, #1 + rdword t8, t8 't8 holds sine value ranging from $0000FFFF ('1') to $FFFF0001 ('-1') + cmps t2, t8 wc 'Set 'C' if Input (t2) < 'Sine value'(t8) + if_c mov t4, t7 'If Input < 'Sine value' then RefHigh = Pivot + if_nc mov t5, t7 'If Input >= 'Sine value' then RefLow = Pivot + djnz t6, #Iteration_Loop 'Re-Iterate to Pin-Point Reverse Sine lookup value. + cmp t3, #1 wc 'Restore sign from t3 + if_nc neg t7, t7 + mov t1, AddressLocation 'Write data back to Arg1 + add t1, #4 + wrlong t7, t1 + jmp #loop 'Go wait for next command +{################################################################################################################ + +Plot + +Plots a pixel at location x,y ; pixel color must be set with pointcolor + +} '<--- Line entry +LPlot_ mov lp, #1 'Set Line Flag + mov t6, #0 'Clear Point Flag + mov t12, #0 'Clear Character Plot Flag + jmp #PointJump +Point_ '<--- Point entry + mov lp, #0 'Clear Line Flag + mov t6, #1 'Set Point Flag + mov t12, #0 'Clear Character Plot Flag + jmp #PointJump +CPlot_ '<--- Character Plot entry + mov lp, #0 'Clear Line Flag + mov t6, #0 'Clear Point Flag + mov t12, #1 'Set Character Plot Flag + jmp #PointJump +Plot_ '<--- Plot entry + mov lp, #0 'Clear Line Flag + mov t6, #0 'Clear Point Flag + mov t12, #0 'Clear Character Plot Flag + +PointJump cmps Arg0, #0 wc 'Set 'C' if x < 0 + if_nc cmps Arg1, #0 wc 'Set 'C' if y < 0 + if_nc cmps Xlimit, Arg0 wc 'Set 'C' if x > Xlimit + if_nc cmps Ylimit, Arg1 wc 'Set 'C' if y > Ylimit + if_c jmp #loop 'Plot points are out of bounds ; skip function + + 'Go wait for next command + mov t1, Arg1 'Calculate Tile position where pixel is located + shl t1, #4 'Multiply 'y' by 16 + mov t2, Arg0 + shr t2, #5 'Divide 'x' by 32 + add t1, t2 'Get title position + shl t1, #2 '...multiply by 4 for 'long' position offset + mov t4, Arg2 + add t4, t1 'Add offset to pixel address to get tile address + rdlong t5, t4 'Read tile contents + mov t3, #1 + shl t3, Arg0 'Create bit mask + test t6, #1 wc + if_c jmp #Point_Test + test Arg4, #1 wc 'Test if pixel is ON "1" or OFF "0" + if_c jmp #Pixel_On +Pixel_Off andn t5, t3 'Clear pixel using tile contents and bit mask + wrlong t5, t4 'Write tile contents + jmp #PixelDone 'Pixel Done +Pixel_On or t5, t3 'Set pixel using tile contents and bit mask + wrlong t5, t4 'Write tile contents + jmp #PixelDone 'Pixel Done +Point_Test muxc t5, t3 wc + if_c mov t6, #1 + if_nc mov t6, #0 + mov t1, AddressLocation 'Write data back to Arg4 + add t1, #16 + wrlong t6, t1 +PixelDone + test t12, #1 wc 'Test if this is a Character plot + if_c jmp #CharacterPlotDone + test lp, #1 wc 'Test if this is a Line plot + if_c jmp #LinePlot_ret + jmp #loop 'Go wait for next command +{################################################################################################################ + +Character + +Place a text character from the ROM table at offset location offsetX,offsetY + +} +Character_ mov t7, #31 'Preset Y repeat loop +RepeatY mov t8, #15 'Preset X repeat loop +'------------------------------------------------------------------------------------------------ + mov t9, Arg5 + and t9, #1 'chr & 1 + add t9, #30 + mov t10, #1 '|<30 or |<31 + shl t10, t9 'Create bit mask (t10) = |<(30 + chr & 1) +'------------------------------------------------------------------------------------------------ + mov t11, CharacterTable 'CharacterTable = $8000 + mov t9, t7 'y * 4 + shl t9, #2 + add t11, t9 + mov t9, Arg5 'chr * 64 + shl t9, #6 + add t11, t9 + mov t9, Arg5 '(chr & 1)*64 + and t9, #1 + shl t9, #6 + sub t11, t9 + rdlong t11, t11 'Read 32bit character data = long[$8000 + y*4+chr*64-(chr & 1)*64] +'------------------------------------------------------------------------------------------------ +RepeatX test t11, t10 wc + if_c jmp #PlotPoint +NoPointPlot shr t10, #2 + djnz t8, #RepeatX + djnz t7, #RepeatY + jmp #loop 'Go wait for next command +PlotPoint mov offsetX, Arg0 'Hold OffsetX value + mov offsetY, Arg1 'Hold OffsetY value + add Arg0, t8 'Load Arg0(X) for PLOT command + add Arg1, t7 'Load Arg1(Y) for PLOT command + jmp #CPlot_ 'Go PLOT point +CharacterPlotDone 'Return from PLOT point + mov Arg0, offsetX 'Restore OffsetX value + mov Arg1, offsetY 'Restore OffsetY value + jmp #NoPointPlot +{################################################################################################################ + +Line + +Draws line from px,py to dx,dy + +} +BoxLine mov bf, #1 'Set Box flag + jmp #Xcondition +Line_ mov bf, #0 'Clear Box flag +Xcondition sub Arg5, Arg7 nr,wc + if_nc jmp #px_dominant +dx_dominant mov sx, #1 + mov deltaX, Arg7 + sub deltaX, Arg5 + jmp #Ycondition +px_dominant mov sx, #0 + mov deltaX, Arg5 + sub deltaX, Arg7 +Ycondition sub Arg6, Arg8 nr,wc + if_nc jmp #py_dominant +dy_dominant mov sy, #1 + mov deltaY, Arg8 + sub deltaY, Arg6 + jmp #DeltaCondition +py_dominant mov sy, #0 + mov deltaY, Arg6 + sub deltaY, Arg8 +DeltaCondition + mov ratio, #0 + sub deltaY, deltaX nr,wc + if_nc jmp #deltaYdominate +deltaXdominate + mov deltacount, deltaX + add deltacount, #1 +deltaXplot call #LinePlot + test sx, #1 wc + if_c add Arg5, #1 + if_nc sub Arg5, #1 + add ratio, deltaY + sub deltaX, ratio nr,wc + if_c jmp #ratioXoverflow + jmp #deltaXdominateDone +ratioXoverflow + sub ratio, deltaX + test sy, #1 wc + if_c add Arg6, #1 + if_nc sub Arg6, #1 +deltaXdominateDone + djnz deltacount, #deltaXplot + jmp #LineDone +deltaYdominate + mov deltacount, deltaY + add deltacount, #1 +deltaYplot call #LinePlot + test sy, #1 wc + if_c add Arg6, #1 + if_nc sub Arg6, #1 + add ratio, deltaX + sub deltaY, ratio nr,wc + if_c jmp #ratioYoverflow + jmp #deltaYdominateDone +ratioYoverflow + sub ratio, deltaY + test sx, #1 wc + if_c add Arg5, #1 + if_nc sub Arg5, #1 +deltaYdominateDone + djnz deltacount, #deltaYplot + jmp #LineDone +LinePlot mov Arg0, Arg5 + mov Arg1, Arg6 + jmp #LPlot_ +LinePlot_ret ret +LineDone + test bf, #1 wc 'Test if this is a Box line + if_nc jmp #loop 'Go wait for next command +BoxLine_ret ret +{################################################################################################################ +Box + +Draws a box from opposite corners x1,y1 and x2,y2 + +} +Box_ mov x1_, Arg5 + mov y1_, Arg6 + mov x2_, Arg7 + mov y2_, Arg8 + mov Arg7, x1_ + call #BoxLine + mov Arg5, x1_ + mov Arg6, y1_ + mov Arg7, x2_ + mov Arg8, y1_ + call #BoxLine + mov Arg5, x2_ + mov Arg6, y2_ + mov Arg7, x1_ + mov Arg8, y2_ + call #BoxLine + mov Arg5, x2_ + mov Arg6, y2_ + mov Arg7, x2_ + mov Arg8, y1_ + call #BoxLine + jmp #loop 'Go wait for next command + +{ +########################### Defined data ########################### +} + +zero long 0 'constants +d0 long $200 +Xlimit long 511 +Ylimit long 383 +CharacterTable long $8000 + +Sin_90 long $0800 +Sin_180 long $1000 +sin_table long $E000 >> 1 'sine table base shifted right +{ +########################### Undefined data ########################### +} + +t1 res 1 'temp variables available for program overhead +t2 res 1 +t3 res 1 +t4 res 1 +t5 res 1 +t6 res 1 +t7 res 1 +t8 res 1 +t9 res 1 +t10 res 1 +t11 res 1 +t12 res 1 +t13 res 1 +t14 res 1 +t15 res 1 +AddressLocation res 1 +offsetX res 1 +offsetY res 1 +deltaX res 1 +deltaY res 1 +sx res 1 +sy res 1 +ratio res 1 +deltacount res 1 +lp res 1 +bf res 1 +x1_ res 1 +y1_ res 1 +x2_ res 1 +y2_ res 1 + +arg0 res 1 'arguments passed from high-level +arg1 res 1 +arg2 res 1 +arg3 res 1 +arg4 res 1 +arg5 res 1 +arg6 res 1 +arg7 res 1 +arg8 res 1 \ No newline at end of file diff --git a/source/vecdem/vectron-1-drv.spin b/source/vecdem/vectron-1-drv.spin new file mode 100644 index 0000000..23b5590 --- /dev/null +++ b/source/vecdem/vectron-1-drv.spin @@ -0,0 +1,250 @@ +''******************************************** +''* VGA 512x384 2-Color Bitmap Driver v1.0 * +''* (C) 2006 Parallax, Inc. * +''******************************************** +'' +'' This object generates a 512x384 pixel bitmap, signaled as 1024x768 VGA. +'' Each pixel is one bit, so the entire bitmap requires 512 x 384 / 32 longs, +'' or 6,144 longs (24KB). Color words comprised of two byte fields provide +'' unique colors for every 32x32 pixel group. These color words require 512/32 +'' * 384/32 words, or 192 words. Pixel memory and color memory are arranged +'' left-to-right then top-to-bottom. +'' +'' A sync indicator signals each time the screen is drawn (you may ignore). +'' +'' You must provide buffers for the colors, pixels, and sync. Once started, +'' all interfacing is done via memory. To this object, all buffers are read- +'' only, with the exception of the sync indicator which gets written with a +'' non-0 value. You may freely write all buffers to affect screen appearance. +'' + +{{ +notizen: + + + +}} +CON + +' 512x384 settings - signals as 1024 x 768 @ 67Hz + + hp = 512 'horizontal pixels + vp = 384 'vertical pixels + hf = 8 'horizontal front porch pixels + hs = 48 'horizontal sync pixels + hb = 88 'horizontal back porch pixels + vf = 1 'vertical front porch lines + vs = 3 'vertical sync lines + vb = 28 'vertical back porch lines + +' änderung wegen synchronisationsproblemen bei board r13 +' hn = 1 'horizontal normal sync state (0|1) +' vn = 1 'vertical normal sync state (0|1) + hn = 0 'horizontal normal sync state (0|1) + vn = 0 'vertical normal sync state (0|1) + + pr = 35 'pixel rate in MHz at 80MHz system clock (5MHz granularity) + +' Tiles + + xtiles = hp / 32 'xtiles 16 + ytiles = vp / 32 'ytiles 12 + +' H/V inactive states + + hv_inactive = (hn << 1 + vn) * $0101 + + +VAR long cog + +PUB start(BasePin, ColorPtr, PixelPtr, SyncPtr) : okay | i, j + +'' Start VGA driver - starts a COG +'' returns false if no COG available +'' +'' BasePin = VGA starting pin (0, 8, 16, 24, etc.) +'' +'' ColorPtr = Pointer to 192 words which define the "0" and "1" colors for +'' each 32x32 pixel group. The lower byte of each word contains +'' the "0" bit RGB data while the upper byte of each word contains +'' the "1" bit RGB data for the associated group. The RGB +'' data in each byte is arranged as %RRGGBB00 (4 levels each). +'' +'' color word example: %%0020_3300 = "0" = gold, "1" = blue +'' +'' PixelPtr = Pointer to 6,144 longs containing pixels that make up the 512 x +'' 384 pixel bitmap. Longs' LSBs appear left on the screen, while +'' MSBs appear right. The longs are arranged in sequence from left- +'' to-right, then top-to-bottom. +'' +'' SyncPtr = Pointer to long which gets written with non-0 upon each screen +'' refresh. May be used to time writes/scrolls, so that chopiness +'' can be avoided. You must clear it each time if you want to see +'' it re-trigger. + + 'if driver is already running, stop it + stop + + 'implant pin settings and pointers, then launch COG + ' %1111_1111_1111_1111_1111_1111_1111_1111 + ' 2 0 0 0 0 0 F F + ' 0010_0000_0000_0000_0000_0000_1111_1111 + ' || ||| VGroup + ' || |||| |||| VPins Video an allen 8 Pins - VGA + ' || --> 01 VMode VGA-Mode + ' | --> 0 CMode 2-Farbmodus + reg_vcfg := $200000FF + (BasePin & %111000) << 6 'schreibt VGroup in das Konfigurationsregister + i := $FF << (BasePin & %011000) 'acht Bits in der Maske bis zur BasePin-Position verschieben + j := BasePin & %100000 == 0 + reg_dira := i & j + reg_dirb := i & !j + + clrflag := 1 '1 - bildschirm wird bei jedem durchlauf gelöscht + clrline := 2 'tilezeile ab der gelöscht wird + + longmove(@color_base, @ColorPtr, 2) 'kopiert 2 parameter von color_ptr in den asm-bereich color_base + 'color_ptr --> color_base + 'pixel_pointer --> pixel_base + if (cog := cognew(@init, SyncPtr) + 1) + return true + + +PUB stop | i + +'' Stop VGA driver - frees a COG + + if cog + cogstop(cog~ - 1) + + +DAT + +'*********************************************** +'* Assembly language VGA 2-color bitmap driver * +'*********************************************** + + org 'set origin to $000 for start of program + +' Initialization code - init I/O + +init mov dira,reg_dira 'i/o-register konfigurieren + mov dirb,reg_dirb + + movi ctra,#%00001_101 'enable PLL in ctra (VCO runs at 4x) + '25..23 PLLDIV = 101 --> VCO / 4 + '31..26 CTRMODE = 00001 --> PLL intern (Video Mode) + movi frqa,#(pr / 5) << 3 'set pixel rate + ' (35 MHz / 5) << 3 = 56 = 111000 + + mov vcfg,reg_vcfg 'set video configuration + +' Main loop, display field and do invisible sync lines + +field mov color_ptr,color_base 'reset color pointer 'color-pointer auf anfangswert setzen + mov pixel_ptr,pixel_base 'reset pixel pointer 'pixel-pointer auf anfangswert setzen + mov y,#ytiles 'set y tiles +:ytile mov yl,#32 'set y lines per tile +:yline mov yx,#2 'set y expansion +:yexpand mov x,#xtiles 'set x tiles + mov vscl,vscl_pixel 'set pixel vscl + +:xtile rdword color,color_ptr 'get color word 'color <-- (color_ptr) + and color,colormask 'clear h/v bits + or color,hv 'set h/v inactive states + rdlong pixel,pixel_ptr 'get pixel long 'pixel <-- (pixel_ptr) + + '----------------------------------------------------- + +' cmpsub clrline,y wc 'clrline - y +' if_c jmp #:noclr + + and clrflag,clrflag wz 'clrflag = 1 '1 --> pixelspeicher bei jedem durchlauf löschen + if_nz wrlong reg_a,pixel_ptr 'pixelspeicher löschen 'reg_a --> (pixel_ptr) + + '----------------------------------------------------- + +:noclr waitvid color,pixel 'farb- und pixelwerte (32bit) ausgeben + add color_ptr,#2 'point to next color word 'farbe nur zwei byte, also ein word + add pixel_ptr,#4 'point to next pixel long 'pixel vier byte, also ein long + djnz x,#:xtile 'another x tile? 'schleife x * 32bit-pixelwerte + + sub color_ptr,#xtiles * 2 'farbzeiger auf zeilenanfang rücksetzen + sub pixel_ptr,#xtiles * 4 'pixelzeiger auf zeilenanfang rücksetzen + + mov x,#1 'zeilensynchronimpuls + call #hsync + + '----------------------------------------------------- VIDEOZEILEN + + djnz yx,#:yexpand 'y expand? + + '----------------------------------------------------- PIXELZEILEN + + add pixel_ptr,#xtiles * 4 'pixelzeiger auf nächsten zeilenanfang setzen + djnz yl,#:yline 'another y line in same tile? 'schleife y-tilezeilen + + '----------------------------------------------------- TILEZEILEN + + add color_ptr,#xtiles * 2 'farbzeiger auf nächsten zeilenanfang setzen + djnz y,#:ytile 'another y tile? + + '----------------------------------------------------- BILDSCHIRM + + wrlong colormask,par 'ende sichtbarer bereich, sync für software erzeugen + + mov x,#vf 'leerzeilen (vf - vertical front) + call #blank + mov x,#vs 'bildsynchonisation (x zeilen) + call #vsync + mov x,#vb 'do vertical back porch lines + call #vsync + + jmp #field 'field done, loop + + +' Subroutine - do blank lines + +vsync xor hvsync,#$101 'flip vertical sync bits + +blank mov vscl,hvis 'do blank pixels + waitvid hvsync,#0 +hsync mov vscl,#hf 'do horizontal front porch pixels + waitvid hvsync,#0 + mov vscl,#hs 'do horizontal sync pixels + waitvid hvsync,#1 + mov vscl,#hb 'do horizontal back porch pixels + waitvid hvsync,#0 + djnz x,#blank 'another line? +hsync_ret +blank_ret +vsync_ret ret + + +' Data + +reg_dira long 0 'set at runtime +reg_dirb long 0 'set at runtime +reg_vcfg long 0 'set at runtime + +color_base long 0 'set at runtime (2 contiguous longs) +pixel_base long 0 'set at runtime + +vscl_pixel long 1 << 12 + 32 '1 pixel per clock and 32 pixels per set +colormask long $FCFC 'mask to isolate R,G,B bits from H,V +hvis long hp 'visible pixels per scan line +hv long hv_inactive '-H,-V states +hvsync long hv_inactive ^ $200 '+/-H,-V states +reg_a long 0 'temp. register +clrflag long 0 '1 - screen bei darstellung löschen +clrline long 0 'tilezeile ab der gelöscht wird + +' Uninitialized data + +color_ptr res 1 +pixel_ptr res 1 +color res 1 +pixel res 1 +x res 1 +y res 1 +yl res 1 +yx res 1 \ No newline at end of file