Basilisk II, ein beliebter Emulator für 68k Macintosh-Systeme, ermöglicht es Anwendern, historische Mac-Betriebssysteme auf modernen Rechnern auszuführen. Trotz seiner Popularität plagte Basilisk II viele Windows-Nutzer über Jahre hinweg mit einem hartnäckigen Fehler: dem sogenannten „Black Screen“-Bug. Dieses Problem äußerte sich darin, dass nach dem Start des Emulators nur ein schwarzer Bildschirm angezeigt wurde und das emulierte Mac-System nicht hochfuhr. Die Ursache war mysteriös, da die Fehlfunktion nur sporadisch auftrat, meist bei neueren Windows-Versionen wie Vista oder Windows 7, während Windows XP, Mac OS X und Linux davon kaum betroffen waren. Die zufällige Natur des Fehlers machte die Fehlersuche komplex und frustrierend, sowohl für Anwender als auch für Entwickler.
Viele Vermutungen wurden angestellt: Bluetooth-Dienste, unterschiedliche Kompatibilitätsmodi, Administrator-Rechte oder das Vorladen von Festplatten-Images. Doch keine der Theorien führte zu einer verlässlichen Lösung. Bis 2013 nahm ich mir selbst vor, tief in den Code von Basilisk II einzusteigen und das Problem an der Wurzel zu packen. Dank des Open-Source-Charakters des Emulators stand mir der vollständige Quellcode zur Analyse zur Verfügung, was bei vielen kommerziellen Emulatoren nicht der Fall ist. Die erste Herausforderung war die Reproduzierbarkeit des Fehlers.
In verschiedenen virtuellen Maschinen konnte ich nachvollziehen, dass Windows 2000 und XP Basilisk II problemlos ausführten, wohingegen Vista und Windows 7 meist mit dem schwarzen Bildschirm endeten. Der Emulator selbst zeigte ein weiteres nerviges Verhalten: Der Schließen-Button funktionierte in diesem Zustand nicht, wodurch ein sauberer Shutdown unmöglich war und man auf den Task-Manager angewiesen war, um die Anwendung zu beenden. Ich begann mit umfangreichen Debug-Ausgaben, um zu verstehen, was intern bei Erfolg und Misserfolg bei der Videoanzeige unterschied. Dabei konzentrierte ich mich auf die Video-Komponenten des Emulators und stellte fest, dass in beiden Fällen die Redraw-Funktion scheinbar regelmäßig aufgerufen wurde. Allerdings wurde der Bildschirminhalt in der Fehlerkonstellation nie als „dirty“ markiert, d.
h., es gab keinen Auslöser für eine Neuzeichnung des Fensters. Diese Erkenntnis lenkte den Fokus auf die Frage, warum der Inhalt nicht als zu aktualisieren erkannt wurde. Bei der Rückverfolgung stiess ich auf eine entscheidende Funktion namens VideoDriverControl, die in der Windows-Version bei Fehlstarts überhaupt nicht aufgerufen wurde. Diese Funktion ist besonders, weil sie über einen ungewöhnlichen Mechanismus aufgerufen wird: Der Emulator nutzt eigens definierte, eigentlich ungültige 68000 CPU-Instruktionen als Kommunikationskanal zwischen dem emulierten System und dem Host.
Bei erfolgreichem Start wurde der spezifische Opcode 0x7119 ausgeführt, der im Emulator als Auslöser für die Initialisierung des Videosystems dient. Bei schwarzen Bildschirmen fehlte dieser Aufruf jedoch. Daraus erwuchs die Erkenntnis, dass der Fehler weniger am Host oder Betriebssystem lag, sondern am emulierten System selbst. Doch wie konnte das sein, wenn ich doch gar keine Boot-Diskette mit geladen hatte? Wie konnte der Emulator-Treiber überhaupt ausgeführt werden? Die Antwort lag in einer Eigenheit von Basilisk II: Das System modifiziert den geladenen Mac-ROM-Code, um inkompatible oder problematische Bestandteile zu umgehen und eigene Treiber und Mechanismen direkt in den ROM einzubauen. Über sogenannte DeclROMs werden im emulierten ROM Treiber für Video und Netzwerk eingefügt.
Genauer gesagt wird durch die Funktion InstallSlotROM ein spezieller ROM-Abschnitt angehängt, der von der Slot Manager-Komponente des Mac-Betriebssystems erkannt und geladen wird. Beim Vergleich von erfolgreichen und fehlgeschlagenen Starts zeigte sich, dass diese Installation immer stattfand, jedoch der Treiber innerhalb des emulierten Systems nur geladen wurde, wenn die Speicheradressen passend lagen. Das führte zu einer weiteren Entdeckung: Der Host-Speicherort des emulierten ROMs unterschied sich in den Erfolgs- und Fehlerfällen erheblich. Während bei Erfolg der ROM-Adressbereich höher im Speicher lag als der des Arbeitsspeichers, war dies im Fehlerfall teilweise umgekehrt. Der Grund lag in der Art, wie Basilisk II den Speicher unter Windows allokierte.
Der Windows-Port rief für RAM und ROM je eigene VirtualAlloc-Aufrufe auf, was zu unvorhersehbaren Speicheradressen führte, während die Unix-Version beide Bereiche zusammen in einem einzigen Block reservierte. Windows veränderte im Laufe der Zeit sein Speicherverwaltungssystem, besonders ab Vista, so dass die zweite Speicherreservierung gelegentlich an niedrigere Adressen als die erste fiel. Dieses unvorhersehbare Verhalten führte dazu, dass der virtuelle Adressraum des emulierten Macs für den ROM-Bereich so ungünstig lag, dass der Slot Manager den Treiber nicht laden konnte. Aus Sicht des emulierten Systems sah das so aus, als befände sich der ROM an einer Adresse, die besonderen Regeln unterlag und für Deklarations-ROMs nicht gültig war. Die Lösung bestand darin, den Speicher-Allocationsmechanismus des Windows-Ports an den Unix-Code anzupassen, also RAM und ROM gemeinsam zu reservieren, um sicherzustellen, dass der ROM immer über dem RAM liegt und so die virtuellen Adressen des emulierten Systems korrekt und erwartbar sind.
Das Kombinieren der Speicherreservierungen beseitigte den Black Screen Fehler sofort und zuverlässig. Um die Theorie weiter zu bestätigen, modifizierte ich den Linux-Port so, dass der ROM unterhalb des RAM reserviert wurde. Auch dort trat der gleiche Fehler reproduzierbar auf. Das bestätigte, dass die Speicherplatzierung entscheidend ist. Interessant ist, dass dieses Problem im Unix-Code zuvor schon 2005 behoben wurde, aber der Fix nie in der Windows-Version Einzug gehalten hatte.
Meine Änderung wurde danach über einen Pull Request in 2013 akzeptiert, und der Fehler trat in den Folgeversionen nicht mehr auf. Zusammengefasst zeigt dieser Bugfix, wie bei Emulatoren die Interaktion von Host-Betriebssystem-Verhalten und der Emulationslogik überraschende Effekte haben kann. Nicht die neueren Windows-Versionen waren per se schuld, sondern der geänderte Speicherallokations-Algorithmus führte zu unerwarteten Adresslagen in der hybriden Speicherstruktur des Emulators. Die systemnahe Emulation des Macs übersetzte diese in einen Zustand, in dem die interne Slot Manager-Komponente die benötigten Treiber nicht laden konnte. Dadurch blieb der Bildschirm schwarz.
Solche Probleme lassen sich nicht immer durch simple Nutzer-Workarounds umgehen, sondern erfordern fundiertes Verständnis und Analyse der Emulationsarchitektur und der Betriebssystemeigenschaften. Aus Entwicklersicht ist die Falle hier auch ein Beispiel dafür, wie vermeintlich einfache Annahmen über Speicherbelegung subtile Fehlerquellen bergen können. Für Nutzer bedeutet das, dass ältere Software durchaus Gründe haben kann, warum sie auf neuen Windows-Versionen Probleme macht, obwohl der Code selbst unverändert bleibt. Der Fix für Basilisk II ist ein Erfolg gegen ein langjähriges Ärgernis und zeigt die Bedeutung von offenem Quellcode und Community-Engagement. Heute läuft Basilisk II zuverlässig auf Windows-Systemen, was es Retro-Computing-Enthusiasten und Interessierten leichter macht, klassische Mac-Systeme zu erleben.
Gleichzeitig erinnert diese Geschichte Entwickler und Nutzer daran, geduldig und neugierig zu bleiben, um solche komplexen Probleme zu verstehen und zu lösen. Die Erfahrung zeigt auch, dass gründliches Debugging, der Vergleich von Erfolg- und Misserfolgsszenarien sowie die Analyse der tiefen Systemarchitektur entscheidend sind, um auch hartnäckige Bugs zu eliminieren. Für mich persönlich war die Behebung des Basilisk II Black Screen Bugs ein wichtiger Schritt auf meinem Entwicklerweg, der viel geduldige Detektivarbeit und Lernbereitschaft erforderte und mich heute noch motiviert, beim Umgang mit alten und neuen Softwaresystemen nie aufzuhören, Fragen zu stellen und tiefer zu graben.