Das AmigaOS bietet eine Debug-Konsole als einfachen Weg zur Fehlersuche. Log-Daten können über die linkbare Debug.lib geschrieben werden, welche auch von allerlei Tools wie MuForce, Mungwall oder PatchWork genutzt wird. AmigaOS stellt einen einfachen internen Debugger namens ROMWack bereit (der in späteren Versionen durch das noch einfachere SAD ersetzt wurde). Aber auch DiagROM schreibt Diagnosedaten über die serielle Schnittstelle, was praktisch ist, wenn ein RAM-Chip oder etwas im Videobereich defekt ist.
Die Log-Ausgabe wird an die serielle Schnittstelle gesendet und kann von einem daran angeschlossenen Terminal gelesen werden. In den guten alten Zeiten konnten sich nicht so viele Bastler ein echtes Terminal oder einen zweiten Computer dafür leisten, also nutzten wir Tools wie Sushi oder Sashimi, um die Debug-Ausgabe in ein Shell-Fenster umzuleiten, was gut funktionierte, solange das System nicht zu hart abgestürzt war.
Heute gehe ich davon aus, dass fast alle Amiga-Besitzer auch einen zweiten Computer zu Hause haben, und sei es nur ein zweiter Amiga. 😉 Dieser Blogartikel handelt davon, wie du deinen Amiga mit deinem Linux-PC verbindest und die Debug-Ausgabe erhältst.
Hardwareseitig benötigst du eine Konstruktion mit einem weiblichen DB25-Anschluss an dem einen Ende und einem USB-Stecker an dem anderen Ende. Ich benutze einen dieser USB-zu-Seriell-Konverter, die in Hardware-Shops für wenig Geld zu finden sind. Sie sind oft mit einem männlichen DB9-Stecker ausgestattet und sollen an Peripheriegeräte (wie Modems) angeschlossen werden. Um sie mit einem Computer zu verbinden, wird ein sogenanntes Nullmodem benötigt, was einfach ein kleiner Adapter ist, der es ermöglicht, zwei Computer direkt miteinander zu verbinden, indem die Sende- und Empfangsleitungen gekreuzt werden. Schließlich brauchen wir einen DB9-zu-DB25-Stecker mit den richtigen Geschlechtern, um das andere Ende des Nullmodems mit dem Amiga zu verbinden.
Dieser Hardware-Stack wird auf der einen Seite an die serielle Schnittstelle des Amiga und auf der anderen Seite an einen USB-Anschluss des PCs angeschlossen. Denke daran, den Amiga auszuschalten, bevor du etwas an die serielle Schnittstelle anschließt. Im Gegensatz zu USB sind die Anschlüsse alter Computer nicht dafür ausgelegt, Geräte anzuschließen oder zu trennen, während das System eingeschaltet ist. Das könnte das System tatsächlich beschädigen!
Softwareseitig müssen wir auf dem Amiga keine Treiber installieren. Die Debug- oder Diagnoseausgabe wird einfach an den seriellen Anschluss gesendet. Unter Linux können wir jeden Terminal-Emulator verwenden. Der bekannteste ist sicherlich minicom.
Die Standardeinstellungen für die serielle Schnittstelle sind 9600-8N1 (9.600 bps, 8 Bits pro Zeichen, keine Parität, 1 Stoppbit). Allerdings wird die Debug-Ausgabe einfach direkt an den seriellen Anschluss gesendet. Wenn du die seriellen Parameter auf der Amiga-Seite geändert hast und das serial.device für etwas anderes verwendet hast, nutzt die Debug-Ausgabe die aktuellen Einstellungen. Handshake muss jedoch in jedem Fall ausgeschaltet sein.
Der vielleicht einfachste Weg ist, eine Datei namens ~/.minirc.amiga mit folgendem Inhalt zu erstellen (ändere den Wert pu port zu deinem tatsächlichen TTY-USB-Gerät):
pu port /dev/ttyUSB0
pu baudrate 9600
pu bits 8
pu parity N
pu stopbits 1
pu rtscts No
pu xonxoff No
Bei vielen Linux-Distributionen muss der Benutzer außerdem zur Gruppe dialout hinzugefügt werden, um auf ein serielles Gerät zugreifen zu können:
sudo usermod -aG dialout $(whoami)
Starte danach einfach minicom mit dem amiga-Profil:
minicom amiga
Jetzt solltest du die gesamte von AmigaOS erzeugte Debug-Ausgabe auf deinem minicom-Bildschirm sehen. Für interaktive Debugger wie ROMWack kannst du auch Befehle in die Konsole eingeben.
Um minicom zu verlassen, drücke STRG-A und dann Q. 😉
Amiga CD32
Im Gegensatz zu anderen Amiga-Modellen hat das CD32 keinen dedizierten RS-232-Anschluss. Stattdessen bietet es eine einfache serielle Schnittstelle am Aux-Anschluss, die intern mit Paulas UART-Pins verbunden ist.
Um einen Adapter zu bauen, benötigst du ein PS/2-Kabel (z.B. von einem Verlängerungskabel oder einem alten PS/2-Eingabegerät) und einen auf MAX3232 basierenden TTL-zu-DB9-Pegelwandler. Diese Wandler findet man auf Online-Marktplätzen für wenige Euro.
Schneide ein Ende des Kabels ab und verbinde die Adern wie folgt mit dem Konverter:
- Pin 2: TXD
- Pin 3 (und die Abschirmung): GND
- Pin 4: VCC
- Pin 6: RXD
Lass die verbleibenden zwei Adern unverbunden und überprüfe die richtige Polarität, bevor du die Adern an den Konverter anschließt!
Das CD32 bietet keine Steuer- und Handshake-Signale, aber glücklicherweise werden diese für Debugging- und Diagnosezwecke nicht benötigt.
AmigaOS war ein Betriebssystem, das seiner Zeit weit voraus war. Es hatte Funktionen, die anderen Heim-Betriebssystemen (wie Windows oder MacOS) damals fehlten, wie präemptives Multitasking. Es gab auch eine Funktion namens Zuweisungen (Assignments). Das vermisse ich wirklich bei Linux!
Ein Amiga-“Assign” ist ein wenig wie der Laufwerksbuchstabe, den du vielleicht von Windows kennst. Zum Beispiel bezieht sich der Windows-Pfad C:\example.txt auf eine Datei namens example.txt im Hauptverzeichnis der Hauptpartition, während dieselbe Datei auf dem ersten Diskettenlaufwerk A:\example.txt heißt.
Auf dem Amiga heißt die Hauptpartition normalerweise DH0:, die zweite Partition DH1: und so weiter, während das erste Diskettenlaufwerk DF0: heißt. Ein ähnlicher Pfad auf dem Amiga wäre also DH0:example.txt oder DF0:example.txt.
Wie du sehen kannst, kann ein “Laufwerksbuchstabe” auf dem Amiga tatsächlich aus mehreren Zeichen und auch Zahlen bestehen. Dies wird als Zuweisung bezeichnet. Der Name DH0 ist der Hauptfestplattenpartition zugewiesen.
Aber warte, da ist noch mehr!
Du kannst mehrere Assigns haben, die auf dasselbe Ziel verweisen. Zum Beispiel enthält die Hauptpartition normalerweise die Amiga-Desktop-Umgebung namens Workbench. Aus diesem Grund hat die Hauptpartition auch ein Label wie Workbench, und auf die Datei könnte auch als Workbench:example.txt zugegriffen werden.
Das ist eigentlich ein ziemlich cleveres Konzept, besonders für austauschbare Medien. Stellen wir uns zum Beispiel vor, wir haben gerade ein Spiel namens shredzone gestartet, und es muss auf eine Datei Music/Opening.mod auf seiner Installationsdiskette zugreifen (AmigaOS verwendet einen Schrägstrich als Dateitrennzeichen, wie alle ordentlichen Betriebssysteme). Es würde eine Datei namens shredzone:Music/Opening.mod öffnen.
AmigaOS würde sehen, dass es keine Zuweisung namens shredzone gibt, und würde einen solchen Dialog öffnen:

Aus Benutzersicht wüsste ich nun, dass ich ein Medium namens shredzone finden und in den Computer einlegen muss. Es spielt keine Rolle, ob es sich um eine Diskette, eine CD oder sogar um einen Netzwerk-Mount handelt. AmigaOS befiehlt mir auch nicht, das Medium in ein bestimmtes Laufwerk einzulegen. Wenn es eine Diskette ist und ich mehrere Diskettenlaufwerke habe, kann ich einfach das auswählen, das ich möchte. AmigaOS erkennt dann, dass ein Medium mit diesem Namen eingelegt wurde, schließt den Dialog und gewährt dem Spiel Zugriff auf die Datei.
Unter Linux müsste ich auf dieses Medium unter einem Pfad wie /run/media/shred/shredzone zugreifen, was viel zum Tippen ist, meinen Benutzernamen enthält und schwerer zu merken ist als nur shredzone:.
Aber warte, da ist immer noch mehr! 😄
Es ist einfach, dem System über die Befehlszeile Zuweisungen hinzuzufügen. Es ist sogar möglich, Unterverzeichnisse als Zuweisungsziel zu verwenden. Bleiben wir bei unserem shredzone-Spielbeispiel. Ich war es leid, jedes Mal die Installationsdiskette einlegen zu müssen, wenn ich dieses Spiel spielen möchte. Also erstelle ich ein Verzeichnis namens DH2:Games/Shredzone/Files auf meiner Festplatte und kopiere alle Dateien von dieser Diskette in dieses Verzeichnis.
Danach gebe ich diesen Befehl in die Befehlszeile ein:
assign shredzone: DH2:Games/Shredzone/Files
Wenn ich das Spiel jetzt starte, sieht AmigaOS, dass bereits ein shredzone-Assign existiert, und greift dort auf die Dateien zu. Auf die Songdatei shredzone:Music/Opening.mod würde also unter DH2:Games/Shredzone/Files/Music/Opening.mod zugegriffen.
AmigaOS nutzt Zuweisungen auch selbst. Zum Beispiel gibt es eine Standardzuweisung namens C:. Sie zeigt normalerweise auf das Verzeichnis C des bootenden Geräts, wo alle Kommandozeilenbefehle (wie dir, copy, delete usw.) erwartet werden. Dieses Assign ähnelt dem, was $PATH für eine Linux-Shell ist.
Stell dir vor, ich habe eine Reihe von Entwicklungswerkzeugen installiert, wie einen Assembler und einen C-Compiler. Die Befehle dieses Toolsets befinden sich unter DH1:Development/DevTools/C. Auf einem Linux-System würde ich diesen Pfad zur Umgebungsvariablen $PATH hinzufügen, damit ich einfach den Befehlsnamen eingeben kann, um einen dieser Befehle auszuführen.
Auf AmigaOS füge ich diesen Pfad einfach zu einer bestehenden Zuweisung hinzu:
assign add C: DH1:Development/DevTools/C
Nun weiß AmigaOS, dass es, wenn ich einen Befehl in die Befehlszeile eingebe, in Workbench:C danach suchen muss, und wenn er dort nicht gefunden wird, wird es versuchen, ihn in DH1:Development/DevTools/C zu finden. Ich könnte sogar Befehle wie dir C: ausführen und alle Dateien in beiden Verzeichnissen sehen. Natürlich ist dies nicht auf zwei Ziele beschränkt.
Es gibt noch mehr, wie z.B. verzögerte Assigns (deferred assigns). Aber ich möchte dir nur einen allgemeinen Eindruck davon vermitteln, was Amiga-Assigns sind und warum ich sie bei Linux vermisse.
Nach 22 Jahren habe ich ein Update für eine Software veröffentlicht, die ich Ende der 1990er Jahre für die Amiga-Plattform geschrieben habe. Es handelt sich um einen Treiber für die MacroSystem MaestroPro, eine vollständig digitale Soundkarte. Zusammen mit dem Update habe ich den Quellcode dieser Bibliothek offengelegt.
Der Soundtreiber selbst ist eigentlich gar nicht so interessant. Ich glaube nicht, dass es auf dieser Welt noch viele Leute gibt, die diese Soundkarte benutzen. Interessanter ist, wie ich das Projekt verändert habe, um es Open-Source zu machen und unter Linux sowie anderen modernen Plattformen kompilierbar zu machen. Darum geht es in diesem Artikel.
Versionierung (oder das Fehlen davon)
Das erste Problem, auf das ich stieß, kam ziemlich unerwartet. Damals, in den guten alten Amiga-Zeiten, hatte ich keine Versionskontrollsysteme wie CVS verwendet. Da ich nur ein Hobby-Entwickler war, wusste ich weder von ihrer Existenz noch von ihrem Zweck. Stattdessen machte ich häufig Backups meiner Quellcodes, damit ich sie im Falle eines Festplattenausfalls oder nach einem verpfuschten Code-Redesign nicht verliere. Aber abgesehen davon war Programmieren eine Operation am offenen Herzen des Quellcodes, ohne die Möglichkeit, zu einem früheren Zustand zurückzukehren, von dem man wusste, dass er funktionierte.
Als Ergebnis fand ich mehrere verschiedene Versionen des Projekts auf meiner Amiga-Festplatte, und ich musste herausfinden, welche die neueste war. Bei diesem Projekt hatte ich Glück, weil ich der Hauptdatei des Quellcodes ein Changelog hinzugefügt hatte. Ich musste nur die Kopie mit dem neuesten Changelog finden.
Ohne ein Versionskontrollsystem sind die Quellen aller älteren Versionen verloren, also habe ich gar nicht erst versucht, eine Historie aus den Backups wiederherzustellen. Die letzte Version im Aminet war V41.40, aber ich konnte die Quellen dieser Veröffentlichung nicht mehr finden. Was ich stattdessen fand, war eine V41.50, die nie veröffentlicht wurde. Ich kann mich nicht erinnern, warum ich mich entschied, diese Version nicht zu veröffentlichen. Vielleicht stellten sich die Änderungen als Regression heraus? Vielleicht hatte ich einfach das Interesse am Amiga verloren und mir nicht mehr die Mühe gemacht, sie zu veröffentlichen?
Jedenfalls konnte ich zumindest die neueste Version des Quellcodes finden. Was nun damit tun? Da ich in der Zwischenzeit ein professioneller Softwareentwickler geworden war, war mir klar, dass ich nicht einfach nur die neueste Quellcode-Version (und ein paar zufällige Backups) behalten würde, sondern ich wollte jetzt ein Versionskontrollsystem verwenden.
Heute verwende ich am liebsten git. Es würde gut in meine Entwicklungsumgebung passen und mir erlauben, meine Quellcodes in meinem GitHub-Repository zu veröffentlichen. Aber git wurde nie auf den klassischen Amiga portiert, und das wird es aufgrund seiner Komplexität wahrscheinlich auch nie.
Olaf Barthel hat jedoch eine Portierung von subversion gemacht. Die letzte Veröffentlichung war 2009 und basiert auf einer sehr alten Subversion-Version 1.1.4. Es würde nicht viel Spaß machen, sie zu benutzen, aber es wäre machbar.
Es gibt auch eine CVS-Portierung von Frank Wille, aber ich mochte CVS nie wirklich, also war das keine Option für mich.
Also waren svn und git die einzigen Kandidaten, mit einer starken Präferenz für git, aber svn als einzige Option, die auf AmigaOS funktionieren würde. Die Entscheidung war mit der nächsten Frage verknüpft.
Kompilierung
Auf welcher Plattform möchte ich weiterentwickeln?
Ich könnte weitermachen und das Projekt auf dem Amiga entwickeln, so wie ich es in den 1990er Jahren getan habe. Dort hatte ich alles, was ich brauchte. Ich benutzte GoldEd als Editor, mit angepassten Makros zum Kompilieren meiner Projekte. Ich benutzte PhxAss als Assembler und SAS/C als C-Compiler. Keine dieser Softwares wird noch gewartet, und SAS/C war ein kommerzielles Produkt, das nicht mehr erhältlich ist. Mit diesen strengen Anforderungen wären nur wenige Leute technisch in der Lage, sich an dem Projekt zu beteiligen.
Heute verwenden Amiga-Enthusiasten die vbcc-Toolchain für die Entwicklung. Sie wird immer noch aktiv gepflegt. Und sie läuft auf AmigaOS, aber auch auf allen gängigen Betriebssystemen. Als Editor ist Visual Studio Code eine bevorzugte Wahl, da es ein Amiga Assembly Add-on gibt. Es unterstützt Syntax-Highlighting, Inline-Dokumentation, Debugging und vieles mehr.
Das sind die fehlenden Puzzleteile. Mit vbcc ist es möglich, das Projekt unter Linux und anderen Plattformen zu bauen, sodass fast jeder Amiga-Entwickler in der Lage ist, sich zu beteiligen. Die Entwicklung unter Linux ermöglicht es mir auch, git und all die anderen Tools zu nutzen, an die ich mich gewöhnt habe. Aber mit nur wenigen Änderungen am makefile könnte das Projekt immer noch unter AmigaOS gebaut werden.
Ich entschied mich für den Linux-Weg, aber das ist eine Entscheidung, die jeder Retro-Entwickler für sich selbst treffen muss. Das Cross-Kompilieren eines Amiga-Projekts unter Linux wäre komfortabel (und schnell), ist aber nicht wirklich “retro”. Das Bauen unter AmigaOS entspräche dem wahren Retro-Geist, würde mich aber mit einem veralteten und teilweise ungewarteten Toolset zurücklassen.
Portierung
Es war einfach, die Quelldateien auf mein Linux-Dateisystem zu kopieren und dort ein git-Projekt zu initialisieren. Das nächste Problem, auf das ich stieß, war, dass ich das makefile portieren musste. Es war maßgeschneidert für meine AmigaOS-Umgebung, mit speziellen Assigns für Include-Dateien und Binaries.
Ich erstellte ein neues makefile, das stattdessen Umgebungsvariablen verwendet. AMIGA_NDK zeigt nun auf das entpackte AmigaOS 3.2 NDK, während AMIGA_INCLUDES auf die Include-Dateien externer Abhängigkeiten (wie MUI) verweist. Ich habe vbcc installiert, sodass alle Befehle im $PATH waren.
Danach habe ich alle Quellcodedateien restrukturiert und neu angeordnet. Das Projekt enthält nun nur noch meine eigenen Dateien, die für den Bau des Projekts absolut notwendig sind. Ein Aufruf von make baut dann das Projekt auf meinem Linux-Rechner.
I18n
Es gab ein unerwartetes Problem mit dem Zeichensatz. Während alle modernen Betriebssysteme UTF-8 verwenden, unterstützt AmigaOS dies nicht, sondern verwendet stattdessen ISO-8859-1. Das Ergebnis ist, dass das Repository eine furchtbare Mischung aus beiden Zeichensätzen enthielt. Alle Dateien, die für die Verwendung durch die git-Umgebung gedacht sind (wie die README.md-Datei), sind in UTF-8 gespeichert. Andere Dateien, die AmigaOS-bezogen sind (wie AmigaGuide-Dateien), müssen stattdessen in ISO-8859-1 gespeichert werden.
Ich hatte gehofft, dass ich das richtige Encoding für jeden Dateityp in einer .editorconfig-Datei definieren könnte. Aber leider ignoriert Visual Studio Code die Zeichensatz-Einstellungen und verwendet stattdessen standardmäßig UTF-8. Es war zu einfach, auf diese Weise versehentlich alle Sonderzeichen (wie den Umlaut in meinem Nachnamen) zu zerstören.
Die einzige Lösung, die ich fand, war, UTF-8 oder ISO-8859-1 nur dort zu verwenden, wo es absolut notwendig war, aber für die meisten Dateien benutzte ich ASCII als den kleinsten gemeinsamen Nenner. Ein eigenes Make-Target make check überprüft alle Dateien auf illegale Zeichen und erzwingt so die korrekte Verwendung der Encodings.
Testen
Natürlich möchte ich das Ergebnis auf AmigaOS testen (und ausführen), entweder in UAE oder auf einem echten Amiga.
Unter UAE können die erstellten Dateien einfach direkt in das Amiga-Festplattenverzeichnis kopiert und dann sofort im emulierten Amiga verwendet werden.
Für den echten Amiga ist es jedoch etwas schwieriger. Ein Weg ist, eine ADF-Disketten-Datei mit xdftool zu erstellen und die Dateien darauf zu kopieren. Diese ADF-Datei kann dann auf einen USB-Stick kopiert und im Amiga über einen Gotek-Diskettenlaufwerk-Emulator gelesen werden.
Ein besserer Weg ist die Verwendung eines einfachen NFS-Servers, der sowohl auf dem Linux- als auch auf dem Amiga-Rechner gemountet ist. Dateien können so leicht ausgetauscht werden. Natürlich setzt das voraus, dass der Amiga über eine Netzwerkverbindung verfügt.
Veröffentlichung
Damals in den Amiga-Zeiten war das Erstellen eines Releases ein vollständig manueller Prozess. Zu diesem Zweck hatte ich ein separates Verzeichnis mit einer Release-Vorlage. Ich kopierte alle kompilierten Dateien manuell an die entsprechenden Stellen dieser Vorlage, packte sie dann und lud sie ins Aminet hoch.
Jetzt möchte ich, dass das git-Projekt in sich geschlossen ist, also befinden sich alle Dateien der Release-Vorlage im distribution-Verzeichnis. Das make release-Target baut das gesamte Projekt, erstellt dann ein frisches release-Verzeichnis, kopiert alle Dateien an die richtigen Stellen und erstellt ein lha-Paket.
Auf einem modernen Linux-Rechner dauert der gesamte Prozess (von einem sauberen Checkout bis zum Distributionspaket) weniger als eine Sekunde. 🤩
Und das war’s. Der Quellcode der maestix.library ist nun offen und auf GitHub verfügbar. Die erste Version, die in der neuen Umgebung gebaut wurde, kann aus dem AmiNet heruntergeladen werden.
CI/CD
Du hast jetzt vielleicht gelacht, aber es ist wahr: Es ist möglich, CI/CD mit Amiga-Projekten zu machen!
vamos ist eine virtuelle Amiga-Laufzeitumgebung, die es ermöglicht, einfache Amiga-Befehle unter Linux auszuführen. Es ist nur eine CPU- und API-Emulation, kein vollwertiger Emulator wie UAE, aber es reicht aus, um Unit-Test-Suites auszuführen.
Es gibt Docker-Images wie docker4amigavbcc, die es zum Beispiel ermöglichen, Commits automatisch über GitLab CI zu bauen.
Und da es einfach ist, neue Pakete ins AmiNet hochzuladen, wäre sogar Continuous Deployment möglich. Erstelle einfach einen Version-Tag und lass deine CI/CD-Kette den Rest erledigen. 🙂
Insgesamt ist es möglich, diese Retro-Projekte auf modernste Weise zu entwickeln, mit einer modernen IDE, Quellcode-Versionierung, plattformneutraler Entwicklung, Unit-Tests und sogar CI/CD.