Praktikum Grundlagen von Hardwaresystemen Sommersemester 2007 Versuch 6: Computergrafik und Sprites 28. Juni 2007 Fachbereich 12: Informatik und Mathematik Institut für Informatik Professur für Technische Informatik Prof. Dr. K. Waldschmidt Johann Wolfgang Goethe-Universität Frankfurt am Main
Inhaltsverzeichnis 1 Einleitung 2 2 Grundlagen 3 2.1 Was ist ein Sprite?................................. 3 2.2 Funktionsweise eines Sprites............................ 3 2.2.1 Bestimmung der Koordinaten bei der Bewegung des Sprites über den Bildschirm................................. 4 2.3 Sprite-Implementierung im Praktikumssystem.................. 5 3 Anmerkungen und Tipps 6 4 Vorbereitungsteil 7 5 Praktikumsaufgaben 8 1
Kapitel 1 Einleitung In diesem Abschlussversuch des Praktikums werden wir uns weiter mit der Grafik beschäftigen. Dieses Mal wird eine der zahlreichen Grafiktechniken, die Sprite-Grafik, betrachtet. Im Grundlagenteil wird das Konzept Sprite und seine Funktionsweise erläutert. Es werden folgende Aufgaben implementiert: ˆ Erstellen der Spritegrafik mit Hilfe von Assembler ˆ Abfrage der Taster und Reaktion auf Zustandsänderung ˆ Bewegung des Sprites in vier verschiedenen Richtungen mit Hilfe der vier Tastern der FPGA-Platine 2
Kapitel 2 Grundlagen 2.1 Was ist ein Sprite? Ein Sprite ist ein zweidimensionales Grafikobjekt. Bei einem Sprite handelt es sich um einen kleinen rechteckigen Speicherbereich, der als Bildschirmausschnitt den Bildschirminhalt partiell verdeckt oder sich mit ihm mischt. Ein Sprite wird von der Grafikhardware über das Hintergrundbild bzw. den restlichen Inhalt der Bildschirmanzeige eingeblendet. Die Positionierung wird dabei komplett von der Grafikhardware erledigt. Die aktuelle Position des Sprites wird in einem Registersatz gehalten, so dass eine Änderung der Registereinträge zu einer Bewegung des Sprites führt. Als Beispiel kann ein Mauszeiger betrachtet werden, der heutzutage von den meisten Grafikkarten als Hardware-Sprite zur Verfügung gestellt wird. In vergangenen Zeiten waren Sprites vor allem in Videospielen und Homecomputern verbreitet. Der C64 beispielsweise verdankt einen Großteil seiner Grafikfähigkeiten der Unterstützung von Sprites. 2.2 Funktionsweise eines Sprites Das Sprite wird von der Grafikhardware an der gewünschten Position im Bild eingefügt. Weil dadurch das restliche Bild im Grafikspeicher nicht beeinflusst wird, muss dieses nicht immer wieder neu dorthin kopiert werden. Durch diese Entlastung des Hauptprozessors sind Sprites sehr schnell und gleichzeitig einfach zu programmieren, erfordern allerdings zusätzliche Hardwareressourcen. Die Daten für die Sprite-Grafik werden dabei entweder direkt in Registern der Grafikhardware vorgehalten oder in speziellen RAM-Bereichen, auf die diese Hardware genügend schnellen Zugriff hat. Zur Bewegung eines Sprites reicht es aus, lediglich dessen i und j Koordinate zu ändern. Die aktuelle Position (i, j) des Sprites wird in einem Register gehalten, so dass eine Änderung des Registereintrags (i+1, j+1) zu einer Bewegung des Sprites führt. In den drei Abbildungen 2.1, 2.2, 2.3 sehen Sie, wie die Bewegung realisiert wird. 3
KAPITEL 2. GRUNDLAGEN 4 Abbildung 2.1: Graphische Darstellung eines Sprites auf der Position (i, j) Abbildung 2.2: Graphische Darstellung eines Sprites auf der Position (i, j+1) Abbildung 2.3: Graphische Darstellung eines Sprites auf der Position (i+1, j+1) 2.2.1 Bestimmung der Koordinaten bei der Bewegung des Sprites über den Bildschirm Die komplizierte Berechnung der Adresse im Grafikspeicher und das Umkopieren des Inhalts entfällt, was ebenfalls den Hauptprozessor entlastet. Der Grafikprozessor fügt selbständig an der vorgegebenen Koordinate das Sprite beim Aufbau des nächsten Bildes im Vordergrund ein. Auch animierte Sprites sind möglich.
KAPITEL 2. GRUNDLAGEN 5 2.3 Sprite-Implementierung im Praktikumssystem Das VGA-Modul des Praktikumsprozessorsystems unterstützt genau ein Sprite mit 8x8 Pixeln. Jedes Pixel des Sprites kann entweder weiß oder durchsichtig sein, abhängig vom zugehörigen Bitwert. Ist das entsprechende Bit gesetzt, ist das Pixel des Sprites weiß, ansonsten durchsichtig. Jede der acht Zeilen des Sprites wird in einem 8-Bit-Register gespeichert, die an den Adressen 0xFFF0-0xFFF7 liegen. Die Position des Sprites wird in zwei weiteren Registern an den Adressen 0xFFF8 und 0xFFF9 gespeichert. Die Positionsregister sind jeweils 8 Bit breit. Da die Grafik jedoch nur 160x100 Pixel bietet, sind nicht alle möglichen Spritepositionen auch sichtbar.
Kapitel 3 Anmerkungen und Tipps ˆ In einer Aufgabe werden Sie ein Assemblerprogramm schreiben, um das Sprite auf dem Bildschirm ausgeben zu können. Um den Inhalt des Sprites zu definieren, sollten Sie den Bitvektor für jede Zeile hexadezimal kodieren und die Zahl als Immediate in ein Register laden. Der Registerinhalt kann dann an die entsprechende Speicherstelle geschrieben werden. Für einen Vektor sieht es dann so aus: MOVI R2, 0xC3 ; Hexadezimalekodierung des e r s t e n Vektors ST R2, R3 ; R3 e n t h a e l t Adresse der e r s t e n S p r i t e z e i l e ˆ In dem Zyklus, in dem ein Sprung ausgeführt wird, zeigt der Program-Counter auf den Befehl nach dem Sprung. Das muss bei der Offsetberechnung berücksichtigt werden. Außerdem wird der Befehl direkt nach einer Sprunganweisung immer ausgeführt, unabhängig davon, ob der Sprung genommen wird oder nicht. ˆ Bei der Aufgabenbearbeitung gehen Sie davon aus, dass das Sprite nur um ein Pixel pro Druck auf einen Taster verschoben wird. 6
Kapitel 4 Vorbereitungsteil Mit den folgenen Aufgaben werden Sie die Assembler-Programme vorbereiten, die Sie im Praktikum fertig implementieren und testen werden. Es ist nicht notwendig, allerdings hilfreich, den Assembler-Code schon komplett zu erstellen. Erstellen Sie für alle zu schreibenden Programme Ablaufpläne. Aufgabe 1. Aufgabe 2. Aufgabe 3. Aufgabe 4. Aufgabe 5. Überlegen Sie sich, wie Ihr Sprite aussehen soll. Ihre Sprite besteht aus 8 Vektoren, die jeweils 8 Bit breit sind. Ihnen steht somit ein 8x8 Feld zur Verfügung. Füllen Sie das Feld mit Einsen und Nullen, entsprechend dem Aussehen Ihres Sprites. Wenn im Vektor eine 0 vorkommt, dann ist diese Stelle durchsichtig, sonst weiß. Bereiten Sie ein Assemblerprogramm vor, dass das Sprite auf einer beliebigen Stelle des Bildschirms ausgibt. Dazu müssen sie das Sprite wie in Aufgabe 1 gezeichnet zeilenweise als Konstante in Register laden und an die entsprechende Spritespeicherstelle schreiben. Relativ zur Taktfrequenz des Prozessors ist die Zeit für das Drücken eines Tasters sehr lang. Bereiten Sie ein Assembler-Programm vor, das in Register R1 zählt, wie oft BTN0 gedrückt wurde. Die Anzahl soll auf der 7-Segment-Anzeige ausgegeben werden. Pro Druck auf BTN0 soll R1 nur genau einmal um eins inkrementiert werden. Die Anzeige soll beim Niederdrücken aktualisiert werden. Sie brauchen nicht zu berücksichtigen, dass mehr als ein Taster, bzw. andere Taster gedrückt werden. Beschreiben Sie eine mögliche Vorgehensweise für die Implementierung der Bewegung Ihres Sprites in eine beliebigen Richtung auf dem Bildschirm mit Hilfe einer der vier Taster der FPGA-Platine. Sie brauchen nicht zu berücksichtigen, dass mehr als ein Taster, bzw. andere Taster gedrückt werden. Wie könnte ein Assemblerprogramm aussehen, das das Sprite mit Hilfe der vier Taster auf der FPGA-Platine in vier Richtungen bewegt. Je ein Taster soll dabei das Sprite nach links, rechts, oben bzw. unten bewegen? Sie brauchen nicht zu berücksichtigen, dass mehr als ein Taster gleichzeitig gedrückt wird. 7
Kapitel 5 Praktikumsaufgaben Für die folgenden Aufgaben entpacken Sie die ZIP-Datei für Versuch 6 von der Praktikumswebseite und erstellen ein neues Projekt mit allen darin enthaltenen VHDL-Dateien, sowie mit den Dateien irom.bmm und irom.mem. Hinweis: Sämtliche erstellten Assembler-Programme müssen im Protokoll kommentiert werden. Geben Sie zu jedem Programm an, welche Register es für welche Daten nutzt. Aufgabe 1. Aufgabe 2. Aufgabe 3. Aufgabe 4. Stellen Sie Ihr Assemblerprogramm zum Zeichnen eines Sprites fertig und übersetzten Sie es. Fügen Sie das Ergebnis in die irom.mem -Datei ein und aktualisieren Sie Ihr Projekt. Testen Sie das Programm mit der FPGA-Platine. Stellen Sie Ihr Assemblerprogramm zum Zählen der Tasterdrücke fertig. Testen Sie das Programm mit der FPGA-Platine. Stellen Sie Ihr Assemblerprogramm zum Bewegen des Sprites in eine Richtung fertig. Testen Sie das Programm mit der FPGA-Platine. Stellen Sie Ihr Assemblerprogramm zum Bewegen des Sprites in alle vier Richtungen fertig. Testen Sie das Programm mit der FPGA-Platine. 8