StarTracker
Der StarTracker-Player in Aktion. Ein kleines Demoprogramm um ein wenig die Funktionen des Computers zu testen und um sie zu erweitern. Natürlich geht es auch ein wenig um den Spaß an der Freude!
Der Player spielt alle HSS-Soundtracker Module auf der eingelegten SD-Card ab, ist schön bunt und wackelt ein wenig. Mister Spock wäre wirklich stolz auf mich… 😉
Und es werde Sound: Gut, nun haben wir unseren Spaß gehabt und einen Retro-Style-Eigenbau-Computer erschaffen. Eine kleine graue Kiste im schicken 80er-Jahre-Design und mit dem passenden Charme, bastelfreundlich bestückt mit drei Parallax Propellerchips, externem RAM, SD-Card-Laufwerk und gängigen Schnittstellen (VGA, PS2, Sound). Dazu eine einfache Systemsoftware, ein Kommandozeileninterpreter, diverse Tools. Schön wäre jetzt eine etwas komplexere Software, welche die einzelnen Komponenten gemeinsam nutzt. In Erinnerung an die Zeiten der alten 8-Bit-Retrocomputer musste ich an die tolle Gamemusik und die unzähligen Soundtracker Module denken. Die erstmaligen Möglichkeiten dieser Technik haben damals in vielen eine ungeahnte Kreativität geweckt, die aber schnell wieder mit der rasant steigenden Fülle der folgenden Computergenerationen durch blanke Konsumgier erstickt wurde. Im Überfluss kreativ zu bleiben ist eine besondere Gabe.
Einen kleinen Kommandozeilenplayer (play.bin) als Schnittstelle zum HSS (Hydra-Sound-System) hatte ich schon recht frühzeitig realisiert, um die Funktionen von Administra zu testen. Aber dieser war doch recht rudimentär. Ein schicker Player mit einer schönen Oberfläche konnte ich mir als lohnenswertes Projekt vorstellen, wobei man die Gelegenheit hätte, die Schnittstellen zu Administra und Bellatrix weiter verbessern und ein wenig mit Grafik und Sound arbeiten. Als Oberfläche fand ich das LCARS-Startrek-Interface ziemlich schick – inspiriert von Raymond Allens Demo auf dem Propeller. Als Plan musste ich vor dem eigentlichen Player folgende Vorarbeiten leisten:
- Ein leistungsfähiges HSS-Interface.
- Einen Loader-Mechanismus für das Administra-BIOS um Grafiktreiber zu realisieren.
HSS-Interface: Um den HSS-Player in Administra steuern zu können, braucht man vielfältige Status-Informationen zur Wiedergabe des aktuellen Moduls. Aktuelle Position, Ende des Moduls, aktueller Status der vier Soundkanäle… Leider ist eine solche Schnittstelle im HSS-Objekt nicht vorgesehen. In den Demoroutinen werden einige Informationen über eine Peek Funktion dargestellt. Aber das scheint mir eine recht provisorische Geschichte zu sein. Also musste ich die HSS-Routinen genauer untersuchen um zu verstehen wie die Funktionen realisiert werden.
Letztlich habe ich das Interface über ein 5×5 Integer Array realisiert. Die ersten 5 Integer enthalten globale Statusinformationen zum Player, die vier weiteren 5 Integer die entsprechenden Werte für je einen der vier Soundkanäle. So ergibt sich folgender Aufbau des Arrays:
0 | iEndFlag | iRowFlag | iEngineC | iBeatC | iRepeat | globale Playerwerte |
5 | iNote | iOktave | iVolume | iEffekt | iInstrument | Soundkanal 1 |
10 | iNote | iOktave | iVolume | iEffekt | iInstrument | Soundkanal 2 |
15 | iNote | iOktave | iVolume | iEffekt | iInstrument | Soundkanal 3 |
20 | iNote | iOktave | iVolume | iEffekt | iInstrument | Soundkanal 4 |
Die globalen Playerwerte haben folgende Bedeutung:
iEndFlag | Repeat oder Ende wurde erreicht |
iRowFlag | Flag das Songzeile fertig ist |
iEngineC | Patternzähler |
iBeatC | Beatzähler |
iRepeat | Zähler für Loops |
Wenn ich es richtig verstanden habe funktioniert die Abarbeitung der Pattern-Werte folgendermaßen: Grundsätzlich sind die Werte in Beats und Rows unterteilt. In jedem Beat werden verschiedene Kommandos für die einzelnen Kanäle abgearbeitet. Alle Kommandos zusammen bilden eine Zeile (Row). In dieser Zeile können Töne oder diverse Effekte getriggert werden. Sind alle Kommandos einer Zeile abgearbeitet wartet die Soundengine die verbleibende Zeit bis zum Ende des Beats um dann mit der nächsten Trackerzeile fortzusetzen.
[Beat 1] CMD1 CMD2 CMD3 … <– Row 1
[Beat 2] CMD1 CMD2 … CMDn
…
[Beat x]
Ich habe den normalen Player „play.bin“ für das CLI dafür um einige Kommandos erweitert:
reg | HSS-Interface-Registerwerte werden angezeigt; zusätzlich auch die extrahierten Kanaldaten |
intreg | HSS-Interface-Registerwerte werden angezeigt |
list | Anzeige der Trackerliste |
rep | Spielt alle Module auf der SD-Card. Name und iRepeatwert wird angezeigt. Bei drei Loops wird sanft zum nächsten Titel überblendet. |
Mit der IOS-Funktion hss_intreg(n) kann ein Interfaceregister <n> ausgelesen werden. Der Kommandozeilenplayer konnte bisher nur ein Modul endlos abspielen. Um das Ende des Moduls zu erkennen war es nötig die grundlegende Struktur zu erkennen: Jedes Modul besteht aus einer Einleitung die nur einmal abgespielt wird und einem Patternteil der endlos wiederholt wird. Ich habe mit iRepeat einen Zähler eingerichtet, welcher die Wiederholungen zählt. Im Player kann man nun diesen Wert abfragen und sinnvoll nach drei Loops das Modul langsam über die Funktion hss_vol ausblenden und beenden, um das nächste Modul zu laden.
Dieses Interface habe ich anfänglich einzig im Kommandozeilenplayer integriert und getestet. Dort kann man während des Abspielvorgangs alle Register oder ein Trackerlog anzeigen. Die grundlegenden Routinen – einlesen der Dateiliste in den externen RAM und abspielen aller Module habe ich so ebenfalls getestet. Was jetzt noch fehlte war eine gefällige grafische Anzeige für den Player.
SFX-Interface: Um die Sache zum Abschluss zu bringen habe ich auch gleich eine kleine Schnittstelle zu den Sound-FX Funktionen von Administra eingefügt. Insgesamt stehen für Programme 16 freie FX-Slots zur Verfügung, welche durch die Software zur Laufzeit mit Werten gesetzt werden können. Ein Soundeffekt wird dann vom Hostprogramm nur noch getriggert. Folgende neue Funktionen stehen dafür im IOS zur Verfügung:
sfx_setslot(adr,slot) – sfx: sendet SFX-Daten in SFX-Slot
sfx_fire(slot,chan) – sfx: triggert einen bestimmten Soundeffekt
Ein einfaches Tool zum Testen der Funktionen ist das Programm „sfxtool“. Mit ihm kann man im eRAM FX-Werte bearbeiten, diese in ein Slot schreiben und triggern. Neben den frei definierbaren Effekten habe ich zusätzlich eine Palette fester Effekte definiert. Diese sind mit Slot-Nummern über $f0 triggerbar. In System habe ich die entsprechenden Töne als Systemklänge verwendet. So triggern die SD-Card-Funktionen einen zweistufigen (langsamer Puls für Standby, schneller Puls für Datenstrom) Pulsschlag und man kann so wie bei den Retros die Ladeprozedur akustisch verfolgen.
Grafiktreiber: Bisher hatte ich hauptsächlich im Textmodus gearbeitet. Um die vielfältigen Grafikmöglichkeiten flexibel nutzen zu können, wäre es sinnvoll, das starre Bios von Bellatrix durch einen Loader zu ersetzen, der dann softwaregesteuert den Grafiktreiber an Bellatrix sendet und aktiviert. Für Regnatix als Host hatte ich eine solche Möglichkeit in Form des Loaders schon realisiert. Für Bellatrix wollte ich eine einfachere Version realisieren: Der Grafikchip sollte bei Systemstart auf eine Übertragung des Grafiktreibers von Regnatix warten. In der Regel wird dabei durch den Kommandozeileninterpreter Regime der VGA-Texttreiber vga.bin (VGA-Textmodustreiber) durch Regnatix gesendet. Eine beliebige Anwendung kann aber durch ein Kommando (IOS-Funktion bload) ein Reset im Grafikchip auslösen und einen neuen Treiber übertragen. So ist es problemlos möglich zur Laufzeit den Bellatrix-Chip mit entsprechendem speziellen Code zu versorgen, um eine bestimmte Grafik zu erzeugen – alles nur noch eine Sache der Software.
Damit kann das Potential des Propellers als Grafikkarte voll ausgeschöpft werden. Es ist jetzt nicht mehr nötig ein möglichst universelles und optimales Grafikbios zu schaffen, mit all den Kompatibilitätsproblemen, welche spätere Änderungen mitbringen, sondern jedes Programm kann seinen eigenen ganz speziellen Treiber mitbringen. Funktionen welche die Anwendung nicht braucht, sind einfach nicht im Treiber enthalten und verbrauchen auch keine Ressourcen. Diese nun freien Möglichkeiten stehen voll und ganz speziellen Funktionen zur Verfügung. So wäre es denkbar, daß sich Regnatix ganz einer grafischen Oberfläche widmet, Menüs zeichnet, Tastatur- und Mausaktionen in entsprechende Aktionen umsetzt – d.h. eine komplette GUI könnte in diesem Chip unabhängig von den Hauptfunktionen im Host Regnatix laufen. Die Flexibilität ist dadurch optimal.
So nutzt natürlich auch der StarTracker einen eigenen Grafiktreiber (stint.bin), welcher von dem Regnatix-Code des Players aktiviert wird. Dieser Treiber besitzt neben den üblichen Textfunktionen einige neue Funktionen, um die farbigen Elemente eines LCARS-Interfaces zu zeichnen. Im Playercode selbst sind noch einige Subroutinen, um Text exakt zu positionieren und um Buttons und Balkenanzeigen zu zeichnen. Die grundlegenden Routinen des Players hatte ich ja schon im Player für die Kommandozeile realisiert, es war also ein leichtes diese Funktionen letztlich in das grafische Interface zu integrieren.
Durch eine Auslagerung der Basisfunktionen in das Administra-Bios und in den Bellatrix-Grafiktreiber ergibt sich für den eigentlichen Playercode eine sehr geringe Größe:
hubRAM: 4,9 KByte Regnatixcode
Hey, das ist absolut cool! Es sind also noch ca. 27 KByte hubRAM frei. Der externe RAM wird nur unwesentlich benutzt: Einzig die Dateiliste der Moduldateien auf der SD-Card wird dort gespeichert. Mit etwas mehr Mühe könnte man die Liste auch zur Laufzeit stückweise einlesen, ohne die gesamte Liste abzuspeichern, aber so erschien mir die Lösung einfach übersichtlicher.