Hallo zusammen,
ich möchte gerne einen Game Boy Emulator mit einem AVR Mikrocontroller
realisieren. Den Programmiertechnischen Teil habe ich im Griff da ich
bereits seit vielen Jahren programmiere. Um die Komplexität abzuschätzen
habe ich bereits in den letzten 2 Wochen zusammen mit einem Kumpel einen
Game Boy Emulator für den PC programmiert und dieser läuft bereits fast
fehlerfrei. Ich brauche daher ein paar Denkanstöße zur Hardware, da ich
erst seit ein paar Monaten mich mit Mikrocontrollern beschäftige. Bisher
habe ich die meisten AVR Tutorials auf eurer Seite durchgearbeitet und
ein wenig selbst mit Infrarotempfängern und IR-LEDs gespielt.
Also zur Hardware des Game Boys. Das Display hat eine Auflösung von
160x144 und kann 4 Graustufen darstellen. Bisher habe ich da noch kein
passendes Display gefunden das man nehmen kann. Bin hier für jeden
Vorschlag dankbar. Bitte aber mit Auflösungen über 160x144, da ich
ungern etwas vom Bild abschneiden möchte.
Die CPU des Game Boys hat 1MHz also hätte ich je nach Mikrocontroller 16
oder 20 Instructions zur Verfügung, um eine Game Boy Instruction zu
verarbeiten. Dazu kommt noch das viele Game Boy Instructions länger als
ein Cycle dauern. Dies sind vor allem die Instructions die nicht nur
Operationen auf den Registern auführen sondern auch auf den RAM
zugreifen. Generell sehe ich es also als machbar an nur die CPU auf
einem Mikrocontroller zu emulieren. Leider kommt noch der LCD Controller
hinzu aber dazu später.
Leider hat der Game Boy relativ viel RAM zur Verfügung. Insgesamt sind
wir bei etwas über 16KB und dann kommt eventuell noch externer RAM von
bis zu 32KB auf den Spielen hinzu. Unter den normalen AVRs scheint der
ATmega1284 mit 16KB RAM schon das höchste der Gefühle zu sein. Daher
frage ich mich ob man irgendwie externe RAM Bausteine nutzen kann um auf
die benötigte Speichergröße zu kommen. Weiteres Speicherproblem sind die
ROMs die wohl bis zu 2MB groß sein können. Auch hier wäre ein externer
Flash oder EEPROM Baustein sicherlich sinnvoll. Auch hier bin ich für
alle Vorschläge offen.
Zum Schluss noch zum LCD Controller. Da ein Mikrocontroller mit dem
Emulieren der Game Boy CPU vermutlich bereits ausgereizt ist dachte ich
daran ob man für den LCD Controller nicht einen zweiten Mikrocontroller
nimmt. Damit könnte man auch das RAM Problem teilweise lösen, da 8KB von
den oben gennanten 16KB auf den VRAM des LCD Controllers entfallen.
Allerdings stellt sich dann die Frage wie man die Controller
untereinander kommunizieren lässt. Es sollte möglich sein in ca. 20
Cycles ein Byte zwischen den Controllern zu übertragen. Im echten Game
Boy sind CPU und LCD Controller scheinbar auch zwei getrennte Einheiten,
da es einige Flags gibt die angeben ob der VRAM grade vom LCD Controller
genutzt wird. Solange kann die CPU nicht auf diesen zugreifen. Ich habe
mich hier auch noch gefragt ob man bei externen RAM Bausteinen das ganze
so aufbauen kann, dass beide Controller auf den gleichen Baustein
zugreifen können.
So das war jetzt erstmal was mir zur Hardware einfällt. Falls ihr
Bauteile vorschlagt so sollten diese am besten als DIL Variante
existieren und Mikrocontroller mit dem STK500 programmierbar sein.
Wenn ich mich nicht irre, verwendet der Gameboy einen Klon des Z80.
Anderswo in diesem Forum gibt es einen AVR-basierten CP/M-Emulator - das
ist ein Betriebssystem, das wiederum auf einem Z80 läuft ...
Beitrag "CP/M auf ATmega88"
Ob allerdings eine Echtzeit-Emulation möglich wird, da habe ich (bzw.
mein Bauch) leichte Zweifel.
Hej,
wenn es nicht umbedingt ein AVR sein muss, dann könntet ihr z.B. dieses
STM-Board nehmen:
http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090
Kostet 20 € und hat fast alles drauf (Controller, Debugger, LCD, 64MBit
RAM) was ihr braucht. Fehlen eigentlich nur noch Tasten und Audio.
Wenn ihr aber auf eine ordentliche Herausforderung aus seit, dann
solltet ihr beim AVR bleiben. :) Halt uns auf dem laufenden mit dem
Projekt, würde mich interessieren, ob das klappt!
Ich bilde mir ein, bereits vor zwei Jahren oder mehr hier im Forum den
Link zu einem funktionierenden GB-Emulator gefunden zu haben. Dieser
beruhte auf einen ATmega64, ob noch RAM oder ein zweiter uC verbaut
wurde weiß ich grad nicht.
Da gabs auf jeden Fall ein Youtube Video...
Eigentlich wollte ich das ganze schon gerne auf dem AVR machen. Die
einzelne Hardware selbst zusammenlöten und dann alles Schritt für
Schritt in Betrieb nehmen finde ich sehr interessant. Ob das ganze
anschließend in Echtzeit läuft ist dann noch eine andere Frage. Wenn
nicht wäre es auch nicht so schlimm solange überhaupt irgendwas
passiert.
Audio soll am Anfang auch erstmal weggelassen werden. Es geht also "nur"
um das Emulieren der CPU und des LCD Controllers erstmal. Den Artikel
zum CP/M-Emulator hab ich mir mal angeschaut aber war nur teilweise
informativ. Das schien alles irgendwie aus Teilen zusammengebaut die
gerade da waren. Welche RAM und Speicherbausteine sollte man am besten
nehmen wenn man mehr braucht als der Mikrocontroller zur Verfügung hat?
Meinst du eventuell dieses (http://www.youtube.com/watch?v=SaoxAr0_mec)
Video? Das ist jetzt natürlich ein AVR32 und Game Boy Color Emulator.
Ich würde gerne nur den Game Boy Classic emulieren und das auf einem
8-Bit AVR.
Ok, wenn ihr beim AVR bleiben wollt um alles von vorne bis hinten selber
durchziehen ist das natürlich auch gut. Es gibt da ja eine ganze Menge,
was man lernen kann.
Einige größere AVRs haben externe Speicherbusse. Diese wären gut
geeignet, da sie nicht sehr viel langsamer sind als der interne Speicher
(im Vergleich mit SPI-Speicher z.B.). Allerdings gibt es diese AVRs
AFAIK nur als SMD, genauso wie die Speicher-Bausteine. Das bietet dann
auch gleich die Möglichkeit zu lernen wie man eine Platine layoutet.
sebi707 schrieb:> Meinst du eventuell dieses (Youtube-Video "Atmel-AVR32 uc3 Gameboy> Emulator")> Video? Das ist jetzt natürlich ein AVR32 und Game Boy Color Emulator.> Ich würde gerne nur den Game Boy Classic emulieren und das auf einem> 8-Bit AVR.
Ne, also das war schon ein normaler AVR bzw. Classic-Emulator.
Ich habs nur noch dunkel im Kopf, glaub aber dass da sogar zwei ATmega64
drauf waren...
Atmega169 unterstützt bis 64kb externes SRAM. Ich würde allerdings eher
zu einem xmega a1 raten. Dann kann gleich das gesamte Rom in den
externen SD-RAM.
Ein Gameboy hat einen Z80 der bei ca. 4.2 MHz läuft. Ich bezweifle, dass
ein AVR es sicher packt, den in Echtzeit zu emulieren. Und Grafik, Sound
und ein paar weitere Sachen kommen noch dazu! Der Gameboy hat außerdem
insgesamt 16 KB SRAM; manche Module bringen Zusatz-RAM mit.
Ich glaube ein kleiner 8-Bit AVR ist hier fehl am Platze, das ist
wirklich eine Anwendung, wo du einen ARM verwenden solltest. Die gibt es
billig mit mehr als genug Ressourcen für deine Anwendung.
Die 4MHz sind zwar auch richtig je nachdem ob man Clock-Cycles oder
Machine-Cycles betrachtet. 4 Clock-Cycles entsprechen einer
Machine-Cycle. Deshalb findet man je nach Quelle, dass der Gameboy nur
1MHz hat. Bei einem AVR mit 16MHz hätte ich also wie oben schon gesagt
16 Instructions um eine Game Boy Instruction zu emulieren. Das klingt
für mich noch halbwegs machbar vor allem auch weil viele Instruction
auch noch mehrere Machine-Cycles dauern.
lex schrieb:> Ne, also das war schon ein normaler AVR bzw. Classic-Emulator.> Ich habs nur noch dunkel im Kopf, glaub aber dass da sogar zwei ATmega64> drauf waren...
Wenn du das noch wieder finden würdest wäre das sehr hilfreich.
Bzw: Es würde mich auch reizen deinen Emulator zu portieren- ich gab
gerade einen passendes Entwicklungsboard. Wenn du den code hochlädst
schaue ich das mir mal an.
sebi707 schrieb:> Bei einem AVR mit 16MHz hätte ich also wie oben schon gesagt> 16 Instructions um eine Game Boy Instruction zu emulieren.
Naja, auch beim AVR brauchen viele Instruktionen mehr als 1 Taktzyklus,
insbesondere wenn du Branches hast (und mind. 1 Branch/Jump hast du pro
emulierter Instruktion). Du musst für die Emulation a) den Opcode laden
b) den Opcode dekodieren c) die Operation ausführen d) ggf. das Ergebnis
zurückschreiben e) ggf. Seiteneffekte handhaben (Statusregister usw.).
16 Taktzyklen sind da sehr wenig Zeit!
> Das klingt> für mich noch halbwegs machbar vor allem auch weil viele Instruction> auch noch mehrere Machine-Cycles dauern.
Selbst wenn, Grafik und Sound sind sehr aufwändig zu emulieren. Du musst
ja z.B. nicht nur die Grafikdaten an das Display rausschieben, der
Gameboy hat auch Sprites und anderes Zeug zur Beschleunigung von
Animationen und Scrolling. Und Sound: 4 Kanäle mit ADSR-Envelope,
verschiedenen Wellenformen usw. Achso: anderes "Kleinvieh" wie Timer
hast du da auch noch, was emuliert werden will...
Ich sehe da kein Land mit einem AVR. Vielleicht mit drei Stück: einer
für CPU & Co, der zweite für Grafik und der dritte für Sound? Dann hast
du aber wiederum ein Problem mit der Kommunikation zwischen den 3
Mikrocontrollern.
So hier mal der Source Code des bisherigen Emulators. Ist momentan aber
eher Resourcen fressend programmiert da wir erstmal etwas
funktionierendes haben wollten. Der Code ist in C++ und mit relativ
neuen Features von C++11 daher brauchst du einen aktuellen Compiler. Das
Rendering ist bisher auch noch nicht vollständig, da noch das
Window-Rendering fehlt und bin mir auch nicht sicher ob ich schon alle
Flags für Sprite-Rendering richtig unterstütze. Außerdem gibt es einen
Bug z.B. bei Tetris wo man keine Punkte beim abbauen von Lines erhält.
Im übrigen geht es mir nicht darum Hardware auszusuchen wo der Emulator
auf jeden Fall funktioniert sondern Hardware wo man sich schon etwas
anstrengen muss und nicht Resourcen verschenken kann wie sonstwas.
Ansonsten könnte ich jetzt bei der PC Version bleiben oder eine Android
Version basteln aber das ist nicht mein Ziel.
In Assembler ist sehr wohl möglich. Schau dir mal die uzebox an bevor du
den avr so degradierst. Den oppcode in 16 Zyklen auszuführen ist kein
Problem:
Code laden 3
Dekodieren 2 (Sprungtabelle)
Ausführen
Zurückspringen 2
Also bleibt genug für die Ausführung. Die restlichen Takte werden für
sound und display genutzt.
Die Datenübertragung von einem AVR zum anderem würde ich über ein 8Bit
Latch machen, Daten ans Latch anlege ein bishen geklingel und man kann
den Port wieder anderweitig nutzen der 2te AVR holt es sich dann vom
Latch ab wenn er Zeit hat.
sebi707 schrieb:> Im übrigen geht es mir nicht darum Hardware auszusuchen wo der Emulator> auf jeden Fall funktioniert sondern Hardware wo man sich schon etwas> anstrengen muss und nicht Resourcen verschenken kann wie sonstwas.
Andererseits ist es auch nicht sinnvoll, etwas anzugehen, das
aussichtslos ist.
Mit einem bastlertauglichen DIP-ATMega wird das nix. Zu langsam, zu
wenig RAM, und so weiter. Wenn's AVR sein soll, dann lieber mindestens
der fetteste XMEGA, den du kriegen kannst. Das ist immer noch
Herausforderung genug. :)
ajo schrieb:> In Assembler ist sehr wohl möglich. Schau dir mal die uzebox an bevor du> den avr so degradierst. Den oppcode in 16 Zyklen auszuführen ist kein> Problem:> Code laden 3> Dekodieren 2 (Sprungtabelle)> Ausführen> Zurückspringen 2
Statt "Zurückspringen" "Code laden".
ajo schrieb:> In Assembler ist sehr wohl möglich. Schau dir mal die uzebox an> bevor du> den avr so degradierst. Den oppcode in 16 Zyklen auszuführen ist kein> Problem:> Code laden 3> Dekodieren 2 (Sprungtabelle)> Ausführen> Zurückspringen 2>
Was ist mit:
* Statusregister aktualisieren? (trifft auf die meisten Opcodes zu)
* PC inkrementieren?
Das ist jetzt doch etwas zu trivialisiert.
Bei den Opcodes die mehr als 4 Takte brauchen sieht es etwas entspannter
aus, aber die schnellen Opcodes kann man ja nicht ignorieren oder
einfach langsamer laufen lassen.
> Also bleibt genug für die Ausführung. Die restlichen Takte werden für> sound und display genutzt.
Wenn du tatsächlich ein paar "freie" Takte zwischen Instruktionen hast,
kannst du die aber nur sehr schwer sinnvoll nutzen.
Stimmt dafür benötigt die Sprungtabelle 2 Takte mehr (ijmp+rjmp). Auf
einem Xmega64A1 mit sdram müsste es eigentlich gut machbar sein.
Möglichweise ist da sogar eine GameboyColor Emulation möglich.
greg schrieb:> * Statusregister aktualisieren? (trifft auf die meisten Opcodes zu)> * PC inkrementieren?
Der PC ist ein Pointerregister im Avr das beim Lesezugriff inkrementiert
werden kann. Die Statusregister gibt es beim Avr auch. In weit man die
wiederverwenden kann müsste man prüfen.
greg schrieb:> Wenn du tatsächlich ein paar "freie" Takte zwischen Instruktionen hast,> kannst du die aber nur sehr schwer sinnvoll nutzen.
Man könnte die Ausführung im Timer-Interrupt machen:
Dort führt man eine gewisse Anzahl von Befehlen aus und zwar ohne auf
die Einhaltung der richtigen Geschwindigkeit zu achten. Allerdings zählt
man mit, wie lang die Befehle hätten dauern müssen. Mit dem CTC-Modus
wird dann der nächste Interrupt ausgeführt wenn diese Zeit verstrichen
ist.
ajo schrieb:> Auf> einem Xmega64A1 mit sdram müsste es eigentlich gut machbar sein.> Möglichweise ist da sogar eine GameboyColor Emulation möglich.
Externer RAM ist aber deutlich langsamer als interner RAM, insbesondere
wenn man SDRAM verwendet. Mindestens den RAM des Gameboy sollte man IMHO
für die Emulation in den internen SRAM stecken. Und dann braucht man
eigentlich gleich den fettesten XMEGA mit 32 KB SRAM.
Der Xmega muss doch nur maximal 2 Byte schreiben/lesen pro µs. Einen
Befehl zum Ausführen und einen Ramzugriff. Das sind 32 Takte/Byte, da
das EBI mit 64Mhz getaktet wird. Außerdem hat er DMA, was den Emulator
nochmal entlasten könnte.
Also wenn ich einen größeren ATxmega nutzen will müsste ich erstmal
gucken wie ich damit arbeiten kann. Selbst Platinen ätzen kommt in
meiner Einzimmerwohnung eher nicht infrage und herstellen lassen kostet
Geld. Außerdem kann man die scheinbar nicht mit dem STK500
programmieren. Was genau macht den ATxmega denn so viel geeigneter? Der
ATxmega64A1 hat 32MHz was ja immerhin das doppelte von den 16MHz der
normalen ATmega ist. Allerdings brauch ich dann wohl immer noch einen
zweiten Controller für Grafik sachen, da mir sonst nicht der große
Vorteil gegenüber zwei ATmega mit 16MHz klar wird. Sound möchte ich im
übrigen erstmal ignorieren und nicht ausgeben.
greg schrieb:> Toll, aber überhaupt nicht vergleichbar mit dem aktuellen Problem.
Es war als Anregung gedacht, sicherlich nicht 1:1 zu verwenden, doch die
DRAM Ansteuerung und der Z80 Simulator dürfen gerne verwendet werden.
sebi707 schrieb:> Also wenn ich einen größeren ATxmega nutzen will müsste ich> erstmal> gucken wie ich damit arbeiten kann. Selbst Platinen ätzen kommt in> meiner Einzimmerwohnung eher nicht infrage und herstellen lassen kostet> Geld. Außerdem kann man die scheinbar nicht mit dem STK500> programmieren.
Du kannst einfach ein paar billige Adapterplatinen bei eBay kaufen und
den XMEGA darauf löten, dann hast du wieder DIP.
> Was genau macht den ATxmega denn so viel geeigneter? Der> ATxmega64A1 hat 32MHz was ja immerhin das doppelte von den 16MHz der> normalen ATmega ist. Allerdings brauch ich dann wohl immer noch einen> zweiten Controller für Grafik sachen, da mir sonst nicht der große> Vorteil gegenüber zwei ATmega mit 16MHz klar wird.
Das External Bus Interface (EBI) kann für LCD und/oder SRAM/DRAM genutzt
werden, DMA kann Datenschiebereien beschleunigen, ein paar neue und
nützliche Instruktionen.
Hallo alle!
Ich meine einen AVR (auch XMega) Gameboy Emulator schon frueher einmal
gesehen zu haben. - Ich bin aber nicht sicher.
greg schrieb:> Du kannst einfach ein paar billige Adapterplatinen bei eBay kaufen und> den XMEGA darauf löten, dann hast du wieder DIP.
sebi707, ich habe noch einige ATxmega128A3 TQFP64 Adapter (mit Chip)
rumliegen.
Gerne sponsore ich deinem Projekt ein paar davon.
(Du benoetigst aber einen JTAG oder PDI faehigen Programmer - z.B.
AVRISP MKII)
Wenn du interressiert bist Schreib mir einfach eine PN (und wie viele du
benoetigen wuerdest).
Ich bin ersteinmal paar Tage weg, aber naechste Woche sollte ich wieder
da sein.
MfG Stephan
Joe G. schrieb:> Skeptiker schrieb:>> Das glaube ich nicht. Z. B. die Geschwindigkeit dürfte lausig sein.>> Kannst du näheres dazu schreiben?>> Lausig ist eine Frage des Bezugspunktes.> Beitrag "Re: CP/M auf ATmega88"
Was sagt die Tabelle aus? Dass das CP/M auf dem Z80-Emulator des
ATMega88 mit DRAM so schnell läuft, wie auf einer Z80-CPU mit ca. 3 MHz?
Mit welchem Takt wird der ATMega88 betrieben?
Skeptiker schrieb:> Dass das CP/M auf dem Z80-Emulator des> ATMega88 mit DRAM so schnell läuft, wie auf einer Z80-CPU mit ca. 3 MHz?
Ja
Skeptiker schrieb:> Mit welchem Takt wird der ATMega88 betrieben?
20 MHz
Wie werden die MHz beim Z80 denn gezählt? Sind das 3MHz Clock-Cycles
oder Machine-Cycles?
Angenommen ich würde jetzt so einen ATxmega nehmen. Dann brauche ich je
nach Modell trotzdem noch externen RAM und externen Speicher für die
ROMs sowieso. Was würde man da für Bauteile nehmen?
Joe G. schrieb:> Skeptiker schrieb:>> Dass das CP/M auf dem Z80-Emulator des>> ATMega88 mit DRAM so schnell läuft, wie auf einer Z80-CPU mit ca. 3 MHz?> Ja>> Skeptiker schrieb:>> Mit welchem Takt wird der ATMega88 betrieben?> 20 MHz
Da der Thread nicht gerade kurz ist, habe ich nur ein wenig quer
gelesen. Es sieht so aus, dass die eff. Geschwindigkeit des
Z80-Emulators eher bei max. 2 MHz liegt.
Kannst du mir die Quellen verraten, bei denen du genauere Informationen
über die Register des Prozessors bekommen hast? Die meisten Dokumente
beschreiben nur grob die Funktion der einzelnen Module...
Das letzte hatte ich schon gefunden, aber das geht dann nicht weit genug
in die Tiefe. Die beiden anderen sehen sehr gut aus. Danke!
sebi707 schrieb:> Funktion der Sound-Register
xD genau das hab ich mir gerade auch angeschaut. Ich hab PortAudio in
dein Projekt eingebunden und bin gerade dabei ein paar Tests zu machen.
Falls du da irgendwas herausfindest wäre ich da auf jeden Fall daran
interessiert. Nicht wegen der Ausgabe der Sounds sondern weil ich
vermute, dass der Bug in Tetris eventuell an der nicht vorhandenen
Emulation der Sound Register liegt. Klingt zwar etwas weit her geholt
aber ich bin mir relativ sicher, dass alle CPU Instructions richtig
implementiert sind (dank Test ROMs) und auch der Timer richtig
funktioniert. Ich könnte mir jedenfalls schon vorstellen, dass beim
abbauen der Lines ein Sound/Sweep gestartet wird und dann aufs Ende
davon gewartet wird.
Channel2 müsste inzwischen vollständig implementiert sein (aber das ist
auch der einfachste). Das Tetris-Problem könnte aber wirklich mit den
Flags zusammenhängen. Wenn der Sound-Length-Wert eines Kanals sein
Maximum erreicht wird dieser ausgeschalten.
In deiner Grafikengine sind noch Bugs. Manchmal flackert nur der
Bildschirm, manchmal wird der Bildschirm auch von ganzen Mapstücken
überlagert, die gar nicht dahin gehören.
Schick mir doch mal eine Email: lkgerr at gmail.com