31.03.2012, 00:31

VGA-Pong via GPIO auf einem 8051

Pong Screenshot

Cypress FX2-Emulator v0.2.1 (GPL) & Spiel (GPL): emu-0.2.1.tar.bz2 (39 KB)

   break exec at 
  -c     3x8-bit max. color value
  -d          increase debug info
  -f          fullscreen mode
  -g   gamma correction [1.0]
  -i     load .ihx program file
  -n   iff not zero, disables graphic and executes up to this cycle nr
  -s    specify instruction rate in kHz [12000]
  -h          print this help message]]>

README:

 VGA-Kanal --|--|____|-\
  |    330R     165R     165R     165R     165R    U_VGA          |   75R   |
-----                                                             |       -----
 ---                                                              |        ---

Damit lässt sich ausgehend von einer Ausgangsspannung von 3,3V des FX2 und dem
definierten Eingangswiderstand eines VGA-Monitors von 75Ω eine Spannung zwischen
0V (entspricht IOB[4:0] = 0) und rund 1V (bei IOB[4:0] = 31) erzeugen, wie sich
unter Zuhilfenahme des bestimmten Ausgangswiderstandes des R2R-Netzwerks von R
(hier 165Ω) ausrechnen lässt:

   U_VGA = IOB[4:0] / 2^5 * 3,3V * 75Ω / (165Ω + 75Ω)

VESA scheint für VGA eine Peak-to-Peak-Spannung von 0,7V auf den
Farbeingangskanälen zu spezifizieren, wobei sich modernere Monitore ein
Signallevel von maximal 0,7V wünschen, wohingegen es bei älteren Monitoren, die
noch ein sogenanntes Sync-on-Green-Feature beinhalten, 0,3V bis 1V ist (damit
die Synchronisations-Informationen in 0V bis 0,3V liegen können). Sync-on-Green
unterstützt Pong auch, jedoch muss es dafür mit einem gesetztem Makro neu
kompiliert werden (siehe vga/Makefile, setze CFLAGS = -DSYNC_ON_GREEN). Der
Emulator ist bisher bloß auf digitale Werte aus dem Intervall [0,21] ausgelegt,
was 0V bis 0,7V entspricht. Für Sync-on-Green müsste ein Zwischenschritt vor
periph_update_vga eingefügt werden.

Es empfehlen sich für obigen Digital-to-Analog-Converter Metallfilmwiderstände,
die eine höhere Genauigkeit (nur bis zu 1% Abweichung) als die verbreiteteren
Kohleschicht-Widerstände aufweisen, denn vor allem Abweichungen bei den
Widerständen für die höherwertigen Bits können die Gesamtgenauigkeit des R2R-
Netzwerks empfindlich stören.


Beschreibung des Emulators
~~~~~~~~~~~~~~~~~~~~~~~~~~

Eine detaillierte Beschreibung des Emulators gibt es an dieser Stelle noch
nicht. Der Code ist (wie so oft) die Dokumentation.

- emuliert nötige Register und FX2-spezifische Features (mit einem 'cy'
  enthaltenden Kommentar markiert im Code):
  - Data-Pointer
  - zwei Auto-Pointer (cy)
  - verringerte Delay-Cycles für Instruktionen MOVX a, @dptr; MOVX @dptr, a (cy)
  - 64KB von-Neumann Speicher (cy) (ebenfalls für schnelleres MOVX nötig)
- emuliert alle nötigen Instruktionen (DA -- decimal adjust [4] bspw. nicht)
  inklusive deren Instruktionszyklenlänge (cy) (wichtig für VGA-Timings)
- benutzt SDL zur Darstellung des Bildes / Input-Event-Verarbeitung
- setzt >= Pentium-M mit rund 1 GHz zum flüssigen Spielen voraus (obwohl
  schon leicht optimiert), da Pong wegen der VGA-Timings rund 170000
  Instruktionszyklen pro Frame benötigt

Ich habe versucht, den Emulator in verschiedene "Ebenen" einzuteilen:
- die Kern-Ausführungseinheit (Funktion exec() und struct cy_cpu)
- die Board- bzw. CPU-Inkarnationsspezifika (exec_done(), struct platform und
  Callbacks für special-function-registers (SFRs) und external RAM und Code
  memory (XDATA und XCODE))
- die Anwendungsdetails und Behandlung der Outputs der emulierten CPU (struct
  periphals und die Zeichen-Routinen ab den Funktionen periph_update_vga() und
  periph_update_led())

Diese Einteilung wurde vorgenommen, um logisch nicht zusammengehörige Teile zu
separieren, diese damit austauschbar und einzeln anpassbar zu machen, ohne viele
Details der anderen Ebenen zu kennen. Durch diese recht grobe Trennung lassen
sich größere Ebenen-spezifische Optimierungen erreichen ohne den Überblick zu
verlieren.

Eine Beschreibung des Speicherlayouts und allgemein dieses Chips findet sich im
Technical Reference Manual zum FX2 [3] sowie auch in einer Seminararbeit [5]
von mir. Im TRM, Kapitel 12 und bei [6] können die Instruktionen, die der 8051
versteht, sowie die SFRs nachgeschlagen werden.

Der FX2 implementiert die Instruktionen mit teils verschiedener Ausführungszeit
vom originalen 8051 oder auch Konkurrenzprodukten (wie bspw. Dallas DS80C320),
weshalb das beigelegte Pong und auch der Emulator (vorerst) als speziell für den
FX2 gebaut zu verstehen sind.


Autor des Emulators und dieses Pong-Spiels ist Franz Brauße.



[1] http://www.ztex.de/usb-1/usb-1.0.e.html
[2] http://sdcc.sf.net/
[3] http://www.cypress.com/?docID=27095
[4] http://linux.die.net/man/1/gtf
[5] http://karlchenofhell.org/uni/uc.pdf
[6] http://www.keil.com/support/man/docs/is51/is51_instructions.htm
[7] http://libsdl.org/]]>