Forum: Projekte & Code FPGA Gameboy Color


von FPGA zum Spass (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich würde gerne mein Projekt vorstellen:
Einen Gameboy Color "Emulator" in VHDL.

Die allermeisten Spiele(Gameboy und Gameboy Color) die ich getestet habe 
funktionieren damit. Bei manchen gibt es kleinere Grafik oder 
Soundfehler. Einige größere(4Mbyte Romgröße) Gameboy Color Spiele laufen 
noch nicht. Das sind jedoch hauptsächlich rein japanische, weshalb meine 
Motivation begrenzt ist.

Vielleicht interessiert ja den ein oder anderen wie man sowas machen 
kann.

Es dürfte zwar etwas schwierig sein den mal auszuprobieren, weil es kein 
komplettes Projekt mit VGA/Input/Soundausgabe ist, aber vielleicht hat 
ja jemand trotzdem auch mal Lust sich was zu basteln.

Ein paar Eckdaten (Origina / Kopie)

CPU: ~8500 Transistoren / 5000 Cyclone 4 LEs (nur CPU, Gesamtsystem: 
~10000)
CPU: 8,38 Mhz / 100 Mhz
Ram: 48 Kbyte / 62Kbyte im FPGA + 8 MByte außerhalb(hauptsächlich Rom + 
Saveram)
Farben: 32768 / 32768
Audio: 4 Bit Stereo / 16 Bit Mono
Auflösung: 160x144 / "Pixelperfect" scaling


Eigentlich kann man viel darüber erzählen, allerdings weiß ich nicht wo 
ich anfangen sollte.
Bei Interesse einfach fragen.

von Stephan S. (plonk)


Lesenswert?

Weiß nicht, was ich dazu fragen soll, finde das Projekt dennoch toll!

MfG

von Ehefrau des „Ragionier Fantozzi“ (Gast)


Lesenswert?

FPGA zum Spass schrieb im Beitrag #5917258:
> Eigentlich kann man viel darüber erzählen, allerdings weiß ich nicht wo
> ich anfangen sollte.

Dann fang mal an auf welcher Platform (Board) das Ganze realisiert wurde 
und warum?

von Vincent H. (vinci)


Lesenswert?

Sehr cool! War das ganze ein "ich möcht FPGA basteln/lernen" oder ein 
"ich möcht Emulator basteln/lernen" Projekt?

von Bla (Gast)


Lesenswert?

War das jetzt eher ein Programmier-technisches Projekt (zB. in VHDL 
Variablen und so erstellen) oder hast du auch etwas mit Hardware (zB. 
auf Gatter-Ebene) zu tun gehabt ?

von FPGA zum Spass (Gast)


Lesenswert?

Danke fürs Lob und Interesse!

Ehefrau des „Ragionier Fantozzi“ schrieb:
> Dann fang mal an auf welcher Platform (Board) das Ganze realisiert wurde
> und warum?

Auf dem Terasic DE2-115, mit Cyclone 4.
Ist eigentlich zu groß dafür, aber das Board nutze ich halt sonst auch.

Gründe für das Board:

- vollwertiger VGA Port mit 24Bit bei 1280*1024
- Soundausgang (16 Bit DAC + Klinke)
- Speicher: Großer SDRam(128MByte) und halbwegs großer SRam(2MByte) und 
Flash und SD-Slot


Geht sicher auch auf kleineren/günstigeren Boards. Sinnvoll ist 
Audio/Videoausgabe, mindestens 8 Mbyte Speicher und 
Massenspeichermöglichkeit(z.b. SD-Karte).

Als Controller verwende ich einen Original N64, den bekommt man mit 3 
Pins ganz leicht verbunden auf 3.3V.


Vincent H. schrieb:
> War das ganze ein "ich möcht FPGA basteln/lernen" oder ein
> "ich möcht Emulator basteln/lernen" Projekt?


FPGA Entwicklung mache ich seit einiger Zeit, sonst hätte ich mir das 
auch eher weniger zugetraut.
War eher ein Projekt mal einen Emulator zu machen.
Als Vorprojekt habe ich den Emulator in C# geschrieben, weil es zum 
debuggen doch enorm viel leichter ist.

Bei Interessse kann ich den auch hochladen, wobei der eher hingebastelt 
ist, weil nur Mittel zum Zweck.



Bla schrieb:
> Programmier-technisches Projekt ... oder ... auch etwas mit Hardware

Größtenteils war es doch recht highlevelig, was sicher auch an meiner C# 
Vorlage liegt.
Z.b. mehr Statemachines mit sequentiellen Schritten als parallele 
Abarbeitung.

Ganz kommt man bei so einem Projekt aber nicht von der Gatterebene weg.
Z.b. beim Versuch den Z80 auf 100 Mhz zu takten oder die Spriteengine 
schnell genug ablaufen zu lassen.

----

Was mich bei dem Projekt immer wieder verwundert und aufgeregt hat: wie 
sehr sich Entwickler doch auf ihre Zielhardware verlassen.

Leicht anderes Zeitverhalten im Promillebereich, z.b. ein VSync der nur 
ein bischen zu früh oder zu spät(!) kommt, kann dazu führen das sich das 
komplette Spiel aufhängt.
Sowas kennt man von PC Spielen halt garnicht und rechnet damit am Anfang 
auch nicht.

Es hat aber auch enorme Vorteile:
Dadurch das die Hardware keinerlei Variation überhaupt hat, z.b. jeder 
Speicherzugriff und jede Berechnung ist immer exakt gleich schnell, kann 
man komplette Spielabläufe aufzeichnen mit Programcounter, 
Registerzuständen, Grafik Hpos/Vpos, Timerständen, usw.

Meine Validierung ist genau so gelaufen:
z.b.: Teste ob der Gameboy nach 1Mio Prozessorzyklen exakt den gleichen 
internen Zustand hat wie der Emulator auf dem PC. Wenn nicht: sukzessive 
Approximation um den Takt zu finden, an dem der Unterschied auftaucht.

von Bla (Gast)


Lesenswert?

Ist das ein Labello unter dem Monitor ? Die sollen gesundheitlich 
bedenklich sein ...

Sei froh dass dein FPGA-Board ein fertiges VGA-Modul hat. Es scheint 
nicht so einfach zu sein da ein sauberes Signal an TFT-Monitore zu 
bekommen.

Hast du wirklich einen Z80 emuliert ? Wie funktioniert die Sprite-Engine 
- kannst du das kurz beschreiben ?

von FPGA zum Spass (Gast)


Lesenswert?

Bla schrieb:
> Sei froh dass dein FPGA-Board ein fertiges VGA-Modul hat. Es scheint
> nicht so einfach zu sein da ein sauberes Signal an TFT-Monitore zu
> bekommen

Ja, da ist ein DAC verbaut, der die vollen 24 Bit leistet. Die 
Ansteuerung mit Hsync/Vsync/usw muss man natürlich trotzdem selbst 
machen, aber das ist ja kein Hexenwerk.

Auf dem DE1 was ich vorher genutzt habe ist nur ein Widerstandsnetzwerk, 
das schafft aber auch immerhin 12Bit bei 1280x1024.

Wichtig für den TFT ist nur, dass die Pixelfrequenz dem Standard 
entspricht. Vielleicht ist aber auch mein TFT sehr tolerant.


> Hast du wirklich einen Z80 emuliert ?

Genau genommen nein.
Der Gameboy Prozessor(Sharp LR35902) ist kein reiner Z80.

Der Prozessor ist direkt in VHDL implementiert, d.h. die OPCodes werden 
direkt berechnet als wäre es echte Hardware, d.h. kein Interpreter oder 
Recompiler wie bei einem PC Emulator.

Im Gegensatz zur echten Gameboy CPU jedoch ohne garantierte 
Ausführungszeiten, Speicherzugriffszeiten und sicherlich mit 
unterschiedlichen Mikrocodes.
(Die CPU Befehle sind recht komplex, weshalb sie in Schritte verteilt 
werden).
Das wird aufgefangen durch einen ~12fach höheren Takt, im Vergleich zum 
Gameboy Color.


> Wie funktioniert die Sprite-Engine

In Kürze:
- Der Gameboy hat maximal 40 aktive Sprites, wovon maximal 10 pro Zeile 
gemalt werden können
- Die Priorität ist (beim GBC) einfach aufsteigend.
- Dazu kommt ein Backgroundlayer
- Dazu kommt ein Windowlayer(2ter Background)
- jedes Pixel hat eine von 4 Farben.

Gemalt wird jetzt nach Priorität:
- Sprite 0
oder Sprite 1, wenn Sprite 0 für dieses Pixel inaktiv oder die Farbe 0 
hat
...
oder Sprite 9, wenn Sprite 8 für dieses Pixel inaktiv oder die Farbe 0 
hat

Zusätzlich wird danach noch unterschieden ob das aktuell aktive Sprite 
gemalt wird oder Window oder Background, abhängig von weiteren 
Prioritätsbits und den Farben(Farbe 0 = "Transparent").

Das ganze unterscheidet sich dann auch noch zwischen GB und GBColor, 
wobei ich gestehen muss, das ich diesen Unterschied ignoriert habe und 
nur die GBColor Variante implementiert habe.
a) weil sie einfacher ist in Hardware abzubilden
b) wei die Doppelimplementierung unnötig viele Ressourcen binden würde
c) weil ich mir im PC Emulator angekuckt habe wie groß die Fehler sind 
und sie für minimal halte: ab und zu flackert ein Pixel wenn sich 2 
Sprites überlappen und das mit dem größeren Index sich nach rechts 
bewegt und das mit der kleineren Index nach links.
Zudem vermeiden die meisten nicht-GBC Spiele Sprite Überdeckungen, 
warscheinlich weil das Prioritätshandling dort so umständlich ist.

von Bla (Gast)


Lesenswert?

Du könntest das Projekt auf wenige Bauteile reduzieren: den FPGA, 
R2R-D/A, Musik-Klinke, SD-Kartenadapter, Joystickanschluss. Alles auf 
eine kompakte Platine druff.

Das könnte man allgemein gebrauchen wenn es nicht zu teuer ist.

von Bernd (Gast)


Lesenswert?

Bla schrieb:
> Du könntest das Projekt auf wenige Bauteile reduzieren: den FPGA,
> R2R-D/A, Musik-Klinke, SD-Kartenadapter, Joystickanschluss. Alles auf
> eine kompakte Platine druff.
Ein MiST?
https://github.com/mist-devel/mist-board/wiki

von Chris R. (hownottobeseen)


Lesenswert?

FPGA zum Spass schrieb im Beitrag #5920307:
>> Wie funktioniert die Sprite-Engine
>
> In Kürze:

Auf dem CCC gab es mal einen schönen Talk über den Gameboy. Darunter 
auch, wie die Sprite Engine funktioniert:

https://www.youtube.com/watch?v=HyzD8pNlpwI

von FPGA zum Spass (Gast)


Lesenswert?

Der Talk war einer meiner Beweggründe das Projekt überhaupt in die Hand 
zu nehmen :)


Zum Board:

ja es gibt sowohl MIST als auch MISTer und wer alles fertig haben nimmt 
warscheinlich eher das.
Billiger ist das aber auch kaum.


Für sehr niedriges Bugdet gibts auf ebay auch fertige Chinaboards mit 
VGA/Ram und ausreichend großem FPGA für 40€.
Freie Pins für ein SDCard Pmod + I2S2 Pmod sind da auch noch übrig. 
Damit kommt man auf ~70€.

Ich denke nicht das man mit eigener Platine da drunter kommen kann, 
dafür sind die FPGAs in Einzelstückpreisen einfach zu teuer.

von FPGA zum Spass (Gast)


Lesenswert?

Ein kleines Update, weil ich ungern Fehler von mir stehen lasse und sich 
irgendwann jemand ärgert der es tatsächlich benutzt.

So ging es nämlich mir, weil ich die Funktionsweise einem anderen 
Emulators abgekupfert habe und deshalb einen Fehler drin hatte:


Der Timer hat falsch rum gezählt(runter statt hoch) und den Init Wert 
ignoriert, weil dieser beim runterzählen nicht funktioniert hat.

Jetzt ist es mMn ~99% korrekt. Nicht 100% cyclegenau, aber die 
Geschwindigkeit in Hz stimmt.

Das fixed die Soundausgabe z.b. in Oracle of Ages oder Donkey Kong die 
vorher zu langsam war.


Der Code ist hier zu finden:
https://github.com/RobertPeip/VHDLBoy

von erwinLocker (Gast)


Lesenswert?

Hallo FPGA zum Spass !


>Der Prozessor ist direkt in VHDL implementiert, d.h. die OPCodes werden
>direkt berechnet als wäre es echte Hardware, d.h. kein Interpreter oder
>Recompiler wie bei einem PC Emulator.

Man muss ja dann noch die ganzen anderen Komponenten hinzufügen. Ich 
sehe in deinem Ordner viele VHDL Dateien. D.h. du hast die ganzen 
Komponenten auch hardwaremäßig geschrieben. Woher wusstest du wie man 
die Grafikeinheit oder den Speicher implementiert ? Hast du dich einfach 
an den gegeben Emulatoralgorithmen orientiert ? Könnte man dann auch 
eine Hardwarekomponente mit C# ähnlichem Z80 algoritmus einbinden, ohne 
dass man gleich den Softprozessor selber einbinden muss, oder wäre das 
zu uneffizient ?

>Als Vorprojekt habe ich den Emulator in C# geschrieben, weil es zum
>debuggen doch enorm viel leichter ist.

Falls ich einen GameBoy emuliere, möchte ich auch erst meinen Code in 
C++ schreiben :D
Dann das ganze langsam hardwaremäßig auf meinem FPGA DE0 umsetzen, falls 
es nicht zu schwer ist^^

Muss man da eigentlich ein Bussystem verwenden. Und kann man den NIOS 
auch zuerst verwenden ? xD

Viele Grüße,
erwin Locker

von Robert P. (fpgazumspass) Benutzerseite


Lesenswert?

Hallo Erwin,

erwinLocker schrieb:
> Woher wusstest du wie man
> die Grafikeinheit oder den Speicher implementiert ?

Die Spec gibts z.b. hier:
http://problemkaputt.de/pandocs.htm

Habe vorher in C# probiert wie alles "richtig" aussieht.
Mit einem "known-good" Emulator kann man gegen checken.

Natürlich ist es eigentlich Verschwendung so einen "Wegwerf-Emulator" zu 
schreiben, aber ich halte es für die beste Möglichkeit überhaupt zu 
verstehen was zu tun ist.

Das ich vorher schon selbst eigene Softcores geschrieben habe und damit 
positive wie negative Erfahrungen gesammelt habe hat sicherlich viel 
geholfen. So hat man die spätere Umsetzung schon grob vor Augen.

erwinLocker schrieb:
> Könnte man dann auch
> eine Hardwarekomponente mit C# ähnlichem Z80 algoritmus einbinden, ohne
> dass man gleich den Softprozessor selber einbinden muss, oder wäre das
> zu uneffizient ?

Du würdest dich wundern... der Z80 ist sogar der C# Variante viel 
ähnlicher als einem echten Z80. Warum?
Weil es so einfacher zu beschreiben ist als das Original und weil ich 
für den Turbo Modus eine hohe Taktrate (100 Mhz) haben wollte. Die Z80 
die nach Originaldesign nachbauen schaffen das allesamt nicht, deswegen 
habe ich mich dagegen entschieden den so zu bauen.

erwinLocker schrieb:
> Muss man da eigentlich ein Bussystem verwenden. Und kann man den NIOS
> auch zuerst verwenden ? xD

Du musst das Gameboy Bussystem nachbauen, weil die CPU dort direkt 
zugriff auf 256 Registeradressen(nicht alle genutzt) hat.

Den NIOS sehe ich da nicht als hilfreich. Wenn man C-Code schreiben 
will, dann geht das effizient auf dem PC. Cross compiled/gedebugged sehe 
ich wenig Sinn drinne.

Rein von der Leistung wird es mit dem NIOS auch sehr knapp wenn er alles 
(CPU, Grafik und Sound) machen soll. Und einen Hybrid betrieb mit Teilen 
der Funktionen im FPGA stelle ich mir noch schwieriger vor.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.