VGA-PacMan

So, nach dem die Überraschung geglückt ist, kann ich diesen Blogpost nun auch veröffentlichen 🙂

VGA PacMac!

Bei uns am Institut gibt ein Projekt, dass wir immer gerne mit Erstsemestern, Praktikanten usw. machen: Die PacMan-Platine. Das ist eine Platine mit einem ATmega168, auf dem die AVGA Software läuft, mit der er ein VGA-Signal generieren kann (und Sound!). Der Code, der aus dem AVR ein VGA (oder PAL/NTSC) Signal rauszaubert ist ziemlich genial, und dazu gibt es eine wunderbare API mit der man sehr einfach Spiele schreiben kann. Wir lassen dann immer ein einfaches Pong implementieren und zeigen am Ende noch ein komplettes PacMan-Spiel, dass allerdings vom AVGA-Autor stammt.

Nun hat der Kollege, der das Projekt maßgeblich betreut hat, seine Promotion abgeschlossen. Auf seinen traditionellen Doktorhut sollte nun natürlich auch die PacMan-Platine, am besten mit kleinem Monitor und Gamepad, so dass man direkt am Hut spielen kann. Und damit hatten wir uns eine Aufgabe gestellt!

Ein passender Monitor mit VGA-Eingang war relativ schnell gefunden, und der lief sogar von einer 9V-Batterie. Und dann gingen die Probleme los. Grundsätzlich kann die AVGA-Bilbiothek VGA- oder (RGB-)PAL-Signale erzeugen. Wegen der hohen Zeilenfrequenz von 31kHz ist bei VGA aber nur eine sehr geringe Auflösung drin, bei PAL hat man doppelt so viel Zeit pro Pixel (15kHz), und erreicht so die doppelte Auflösung. Die PacMan-Implementierung unterstützt daher nur PAL, weil die hohe Auflösung nötig ist. Unser Monitor kann aber nur VGA 🙁 Allerdings gibt es einen Nachfolger von AVGA, RetroViz, für den es ein VGA-PacMan gibt. Das klang ja schon mal gut.

Leider sind die Hardware-Anforderungen von RetroViz ein bisschen anders als bei AVGA:

  • Es wird als Eingabe nur eine PS/2-Tastatur unterstützt (über die UART-Schnittstelle angeschlossen)
  • Die Ausgabe der Videodaten erfolgt auf PD0-3, nicht PD4-7
  • Es wird ein 32MHz-Takt benötigt
  • Es wird ein ATmega32p benötigt

Also mussten wir ein bisschen umbauen 🙂 Fangen wir mit den einfachen Sachen an: Der ATmega168 lässt sich einfach durch einen ATmega328p ersetzen, die sind pinkompatibel. Die Eingabe lässt sich relativ einfach im Code auf unser parallel angeschlossenes Gamepad umbauen. Und dann gingen die Probleme los.

Zunächst die Pinbelegung: Die Platine sah vor, dass PD4-7 das Video-Signal enthalten, jetzt kommt es aber ja aus PD0-3. Nichts, was man nicht mit ein bisschen Draht lösen könnte :). So haben wir die alten Pins einfach umgebogen und die neuen Pins mit alten verbunden. An PD0-3 hingen zum Glück nur ein paar LEDs, die wir nicht unbedingt brauchten.

Rückseite der Platine mit Verkabelung. Unten rechts ist der Oszillator zu sehen.

Nun der Takt: Offiziell läuft der ATmega nur mit maximal 20MHz. Ein bisschen mehr ist ja aber eigentlich immer drin :), daher lief er jetzt auch schon mit 25MHz. Ich bin also naiv zu Conrad gegangen, und habe einen 32MHz Quarz gekauft. Komischerweise funktionierte damit allerdings nichts. Praktischerweise haben wir ja am Institut jede Menge cooles Equipment, unter anderem Oszilloskope. Hier zeigte sich dann, dass das VGA-Signal nur mit 20fps statt 60fps ausgegeben wurde, und scheinbar der Quarz auch nur mit 10MHz schwang. Nun wurde ich von einem Kollegen aufgeklärt: Quarze ab rund 30MHz sind „Obertonquarze“. Diese haben nominell nur ein drittel der angeben Frequenz und sind dafür gedacht, im dritten Oberton betrieben zu werden. Leider funktioniert das mit dem AVR nicht, dessen Treiber betriebt einen Quarz immer im Grundton. Das erklärte zumindest, warum nichts funktionierte 🙂

Leider gibt es keine 32MHz-Grundton-Quarze, so dass wir auf einen integrierten Oszillator ausweichen mussten, der ein Rechtecksignal ausgibt. Der AVR muss entsprechen auf „Ext. Clock“ eingestellt werden. Erste Tests mit einem Frequenzgenerator zeigten dann, dass mit 32MHz das VGA-Signal tatsächlich wie gewünscht aussah, und tada: Der Monitor zeigte ein Bild!

Leider zeigte sich ein anderes Problem: Die 32MHz waren wohl ein bisschen viel für die arme CPU, so traten immer wieder interessante Bildstörungen auf, weil wohl der RAM-Inhalt beschädigt wurde. Ein Test mit dem Frequenzgenerator zeigte dann, dass 27MHz die optimale Frequenz sind: Die CPU läuft stabil, und das Timing des VGA-Signals ist gerade noch so im Rahmen, dass der Monitor funktioniert. Schlussendlich gab es dann nur einen 30MHz Oszillator, aber auch damit läuft alles stabil.

Leider zeigte das Bild starke vertikale Streifen. Mit rumspielen an den Monitoreinstellungen ließen sich die reduzieren, optimal war es aber immer noch nicht. Hier hatte mein Kollege wieder die richtige Idee: Das VGA-Signal ist analog, und die Masseverteilung auf der Platine ist nicht gerade optimal. Vielleicht sind die Streifen einfach nur Störungen, die der AVR in die Masseleitung einstrahlt? Wir haben also mal 100nF an die Versorgungspins gelötet, und siehe da: Die Streifen waren weg. Diese Dingen sind also doch nicht überflüssig 🙂

Leider gab es noch eine andere Art von Streifen: Im Spiel traten immer mal wieder wirre horizontale Streifen auf, allerdings nicht immer. Uns viel dann auf, das sie immer dann auftreten, wenn Sound abgespielt werden sollte. Und siehe da: Leider wird auch der Sound auf PD3 ausgegeben, und damit in das Videosignal gemischt 🙂 Da hat der Autor von RetroViz irgendwie nicht aufgepasst. Praktischerweise ist RetroViz relativ gut konfigurierbar, sodass sich der Sound auf PB3 umrouten ließ. Da das der Pin A und nicht B des Timers ist, musste man ein bisschen Code umbauen und konnte einen schlauen Trick nicht mehr benutzen, schlussendlich waren damit aber die Streifen weg und der Ton wieder da (mit Hilfe eines kleinen weiteren Stücks Drahts, um den neuen Pin zu verbinden 🙂 )

Oberseite der Platine, es sind (fast) keine Modifikationen zu erkennen.

Schlussendlich war damit das Kunststück vollbracht: Auf der alten PacMan-Platine läuft eine VGA-Version von PacMan, mit dem originalen Controller, und ohne von oben sichtbare Modifikationen! Noch mal vielen Dank an meinen Kollegen für die vielen guten Tipps und die Unterstützung, und Danke an unseren FWJler für das GamePad mit Spezialkabel! Ein bisschen Elektronik-Gebastel mal wieder hat Spaß gemacht 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.