Frage

Wie Emulatoren arbeiten? Wenn ich NES / SNES oder C64-Emulatoren zu sehen, verblüfft es mich.

http://www.tommowalker.co.uk/snemzelda.png

Haben Sie den Prozessor dieser Maschinen zu emulieren durch seine besondere Montageanleitung zu interpretieren? Was geht sonst hinein? Wie werden sie in der Regel entworfen?

Können Sie einen Rat für jemanden geben, interessiert sich für das Schreiben eines Emulators (insbesondere ein Spielsystem)?

War es hilfreich?

Lösung

Emulation ist ein facettenreiches Gebiet. Hier sind die grundlegenden Ideen und funktionelle Komponenten. Ich werde es in Stücke brechen und dann in den Details über Änderungen zu füllen. Viele der Dinge, die ich Wissen über die inneren Abläufe der Prozessoren beschreiben werde erfordert - Montagekenntnisse erforderlich. Wenn ich etwas zu vage auf bestimmte Dinge bin, bitte fragen Sie Fragen, so kann ich auch weiterhin diese Antwort zu verbessern.

Grundidee:

Emulation funktioniert durch das Verhalten des Prozessors und die einzelnen Komponenten arbeiten. Sie bauen jedes einzelne Stück des Systems und dann die Stücke verbinden viel wie Drähte in Hardware zu tun.

Prozessor-Emulation:

Es gibt drei Wege im Umgang mit Prozessor-Emulation:

  • Interpretation
  • Dynamische Neuübersetzung
  • Static Neuübersetzung

Mit all diesen Wegen haben Sie das gleiche Gesamtziel: execute ein Stück Code Prozessorzustand zu ändern und die Interaktion mit ‚Hardware‘. Prozessorzustand ist ein Konglomerat der Prozessor-Register, Interrupt-Handler, etc. für einen gegebenen Prozessor Ziel. Für die 6502, dann würden Sie eine Reihe von 8-Bit-Integer haben repräsentiert Register: A, X, Y, P und S; Sie würden auch ein 16-Bit PC Register haben.

Mit Interpretation, beginnen Sie am IP (Befehlszeiger - auch genannt PC, Programmzähler) und die Anweisung aus dem Speicher gelesen. Ihr Code analysiert diese Anweisung und verwendet diese Informationen Prozessorzustand zu verändern, wie von Ihrem Prozessor spezifiziert. Das Kernproblem bei der Interpretation ist, dass es sehr langsam; jedes Mal, wenn Sie einen bestimmten Befehl verarbeiten, müssen Sie es entschlüsseln und die erforderliche Operation durchführen.

Bei der dynamischen Neuübersetzung iterieren Sie über den Code viel wie Interpretation, aber statt nur Opcodes ausgeführt wird, erstellen Sie eine Liste der Operationen auf. Sobald Sie eine Verzweigungsbefehl erreichen, können Sie diese Liste der Operationen in Maschinencode für die Host-Plattform kompilieren, dann cachen Sie diesen kompilierten Code und ausführen. Dann, wenn Sie eine bestimmte Befehlsgruppe wieder treffen, müssen Sie nur den Code aus dem Cache auszuführen. (Übrigens, die meisten Menschen eigentlich nicht eine Liste von Anweisungen machen, sondern sie zu Maschinencode on the fly kompilieren - das macht es schwieriger zu optimieren, aber das ist aus dem Anwendungsbereich dieser Antwort, es sei denn, genug Leute, die interessiert sind)

Bei der statischen Neukompilierung, tun Sie das gleiche wie in dynamischen Neuübersetzung, aber Sie folgen Zweige. Am Ende haben Sie bauen ein Stück Code, der den gesamten Code in das Programm darstellt, die dann ohne weiteres Zutun ausgeführt werden kann. Dies wäre ein großer Mechanismus, wenn es nicht für die folgenden Probleme sind:

  • Code, der nicht im Programm ist mit (beispielsweise komprimiert, verschlüsselt, erzeugt / modifiziert zur Laufzeit, usw.) zu beginnen, wird nicht neu kompiliert werden, so wird es nicht laufen
  • Es ist erwiesen, dass in einem bestimmten binären den gesamten Code zu finden, mit dem Halting Problem

Diese kombinieren, um statische Neukompilierung vollständig undurchführbar in 99% der Fälle zu machen. Weitere Informationen hat Michael Steil einige große Forschung in statische Neukompilierung getan - das Beste, was ich gesehen habe,

.

Die andere Seite an dem Prozessor-Emulation ist die Art und Weise, in der Sie mit der Hardware interagieren. Das ist wirklich hat zwei Seiten:

  • Prozessor Timing
  • Interrupthandling

Prozessor Timing:

Bestimmte Plattformen - vor allem ältere Konsolen wie der NES, SNES, usw. - benötigen, um Ihren Emulator strenges Timing zu haben, vollständig kompatibel zu sein. Mit dem NES, haben Sie die PPU (Bildpunkt-Verarbeitungseinheit), dass das Put-Pixel in seinen Speicher CPU erfordert in präzisen Augenblick. Wenn Sie Interpretation verwenden, können Sie leicht Zyklen zählen undemulieren geeigneten Zeitpunkt; mit dynamisch / statisch Neuübersetzung, sind die Dinge ein / lot / komplexer.

Interrupt-Handling:

Interrupts wird der primäre Mechanismus, der die CPU mit Hardware kommuniziert. Im Allgemeinen wird die Hardware-Komponenten der CPU sagen, was unterbricht er kümmert sich um. Das ist ziemlich einfach -., Wenn Ihr Code einen bestimmten Interrupt wirft, schauen Sie auf der Interrupt-Handler-Tabelle und rufen Sie den richtigen Rückruf

Hardware-Emulation:

Es gibt zwei Seiten ein gegebene Hardware-Gerät zu emulieren:

  • emulieren die Funktionalität des Geräts
  • emulieren die tatsächlichen Geräteschnittstellen

Nehmen wir den Fall eines Festplatten. Die Funktionalität, die durch die Erstellung des Sicherungsspeichers emuliert wird, Lesen / Schreiben / Format-Routinen usw. Dieser Teil der Regel sehr einfach ist.

Die eigentliche Schnittstelle des Gerätes ist ein wenig komplexer. Dies ist in der Regel eine Kombination aus Memory Mapped Registern (z.B. Teile des Speichers, daß die Vorrichtung für Änderungen Uhren Signalisierung zu tun) und Interrupts. Für eine Festplatte, können Sie eine Memory-Mapped-Bereich, wo Sie lesen Befehle setzen, schreibt, etc, dann diese Daten lesen zurück.

würde ich mehr ins Detail gehen, aber es gibt eine Million Möglichkeiten, wie Sie mit ihm zu gehen. Wenn Sie spezielle Fragen hier haben, sich zu fragen, und ich werde die Info hinzufügen.

Ressourcen:

Ich denke, dass ich ein ziemlich gutes Intro hier gegeben haben, aber es gibt einen ton von zusätzlichen Flächen. Ich bin mehr als glücklich, mit allen möglichen Fragen zu helfen; Ich habe diese sehr vage in den meisten einfach aufgrund der immensen Komplexität.

Obligatorischer Wikipedia Links:

Allgemein Emulation Ressourcen:

  • Zophar - Dies ist, wo ich meinen Start mit Emulation bekam, erste Emulatoren herunterladen und schließlich zu plündern ihre immense Archive der Dokumentation. Dies ist die absolut beste Ressource, die Sie möglicherweise haben.
  • NGEmu . - Nicht viele direkte Ressourcen, aber ihre Foren sind unschlagbar
  • RomHacking.net - Die Dokumente Abschnitt enthält Ressourcen in Bezug auf Maschinenarchitektur für gängige Konsolen

Emulator Projekte verweisen:

  • IronBabel - Dies ist eine Emulationsplattform für .NET, in Nemerle geschrieben und kompiliert den Code zu C # on the fly. Haftungsausschluss:. Das ist mein Projekt, so verzeihen Sie den schamlosen Stecker
  • bsnes -. Ein ehrfürchtiger SNES-Emulator mit dem Ziel des Zyklus perfekter Genauigkeit
  • MAME - Die Arcade-Emulator. Große Referenz.
  • 6502asm.com -. Dies ist ein JavaScript-6502-Emulator mit einem kühlen kleinen Forum
  • dynarec'd 6502asm - Das ist ein kleiner Hack, den ich über einen Tag tat oder zwei . Ich nahm den bestehenden Emulator von 6502asm.com und verändert sie dynamisch den Code JavaScript für massive Geschwindigkeit erhöht sich neu zu kompilieren.

Prozessor Neuübersetzung Referenzen:

  • Die Forschung in statische Neukompilierung erfolgt durch Michael Steil (oben genannten) in dieses Papier und Sie können Quell- und solche hier .

Nachtrag:

Es ist schon mehr als ein Jahrda diese Antwort eingereicht wurde und mit all der Aufmerksamkeit, sie wird immer, ich dachte, es ist Zeit, einige Dinge zu aktualisieren.

Vielleicht ist das Aufregendste, was jetzt in der Emulation ist libcpu , durch die zuvor erwähnte Michael Steil gestartet . Es ist eine Bibliothek sollte eine große Anzahl von CPU-Kernen unterstützen, die LLVM verwenden für Neuübersetzung (statisch und dynamisch!). Es hat ein enormes Potenzial, und ich denke, es wird für die Emulation große Dinge tun.

emu-docs wird auch darauf aufmerksam gemacht worden, die eine große Sammlung von Systemdokumentation beherbergt, die sehr nützlich für die Emulation Zwecke. Ich habe nicht viel Zeit dort verbracht, aber es sieht aus wie sie viele große Ressourcen haben.

Ich bin froh, dieser Beitrag hilfreich gewesen ist, und ich hoffe, ich kann meinen Arsch bekommen und mein Buch über das Thema bis zum Ende des Jahres / Anfang nächsten Jahres beenden.

Andere Tipps

Ein Mann Victor Moya del Barrio genannt schrieb seine Diplomarbeit zu diesem Thema. Viele gute Informationen über 152 Seiten. Sie können die PDF-Download hier .

Wenn Sie nicht wollen, mit registrieren scribd , können Sie für den PDF-Titel Google, "Studie der Techniken für die Emulation Programmierung" . Es gibt ein paar verschiedene Quellen für die PDF.

Emulation mag entmutigend, ist aber eigentlich ganz einfach wie noch zu simulieren.

Jeder Prozessor hat typischerweise eine gut geschriebene Spezifikation, die Staaten, Interaktionen usw.

beschreibt

Wenn Sie überhaupt nicht über die Leistung scheren, dann könnte man leicht die meisten älteren Prozessoren emulieren sehr elegante objektorientierte Programme. Zum Beispiel würde ein X86-Prozessor etwas braucht den Zustand der Register (leicht) zu halten, was den Zustand der Speicher (leicht), und etwas zu halten, dass jedes eingehendes Kommando übernehmen würde und es auf den aktuellen Zustand der Maschine. Wenn Sie wirklich Genauigkeit wollen, würden Sie auch Speicher Übersetzungen, Caching etc. emulieren, aber das ist machbar.

In der Tat, viele Mikrochip und CPU-Hersteller testen Programme gegen einen Emulator des Chips und dann gegen den Chip selbst, die sie herausfinden, hilft, wenn es Probleme in den Spezifikationen des Chips, oder bei der tatsächlichen Umsetzung des Chips in der Hardware. Zum Beispiel ist es möglich, eine Chip-Spezifikation zu schreiben, die in Deadlocks führen würden, und wenn ein Termin in der Hardware auftritt, ist es wichtig zu sehen, ob es in der Beschreibung wiedergegeben werden, da das ein größeres Problem als etwas in der Chip-Implementierung zeigt.

Natürlich Emulatoren für Videospiele sorgen in der Regel über die Leistung, so dass sie, nicht naive Implementierungen verwenden und sie umfassen auch Code, der eine Schnittstelle mit dem Betriebssystem des Host-Systems, zum Beispiel Zeichnung und Ton zu verwenden.

die sehr langsame Leistung von alten Videospielen Unter Berücksichtigung (NES / SNES, etc.), ist Emulation ganz einfach auf modernen Systemen. In der Tat ist es umso erstaunlicher, dass Sie nur einen Satz von jedem SNES-Spiel herunterladen konnte jemals oder einem Atari 2600-Spiel aller Zeiten, dass man bedenkt, wenn diese Systeme populär wäre, würde ein Traum wahr haben freien Zugang zu jeder Patrone.

Ich weiß, dass diese Frage ist ein bisschen alt, aber ich möchte etwas zur Diskussion hinzuzufügen. Die meisten Antworten hier Zentrum um Emulatoren die Maschinenbefehle der Systeme zu interpretieren sie emulieren.

Allerdings gibt es eine sehr bekannte Ausnahme von dieser als "UltraHLE" ( Wikipedia-Artikel ). UltraHLE, einer der bekanntesten Emulatoren jemals geschaffen wird, emuliert kommerzielle 64-Spiele Nintendo (mit anständiger Leistung auf Heimcomputern) zu einem Zeitpunkt, als es allgemein als unmöglich angesehen wurde, dies zu tun. Als Tatsächlich produziert Nintendo noch neue Titel für den Nintendo 64, wenn UltraHLE erstellt wurde!

Zum ersten Mal sah ich Artikel über Emulatoren in Print-Magazinen, wo vor, ich nur sie im Web diskutiert gesehen hatte.

Das Konzept der UltraHLE möglich zu machen, war das unmöglich, durch Emulation C-Bibliothek Anrufe statt Maschinenebene Anrufe.

Etwas lohnt sich, einen Blick auf, Imran Nazar Versuch ist ein Gameboy Emulator in JavaScript.

Nachdem ich meine eigenen Emulator der BBC Microcomputer der 80er Jahre (Typ VBeeb in Google) erstellt, gibt es eine Reihe von Dingen zu wissen.

  • Sie sind nicht die reale Sache als solche Emulation, das eine Nachbildung wäre. Stattdessen sind emuliert Sie Staat . Ein gutes Beispiel ist ein Rechner, hat die reale Sache Tasten, Bildschirm, Fall etc. Aber einen Rechner zu emulieren müssen Sie nur emulieren, ob Tasten sind nach oben oder unten, welche Segmente der LCD sind, usw. Grundsätzlich ist eine Reihe von Zahlen stellvertretend für alle möglichen Kombinationen von Dingen, die in einem Rechner ändern.
  • Sie müssen nur die Schnittstelle des Emulators wie die reale Sache erscheinen und verhalten. Je überzeugender das ist, je näher die Emulation ist. Was hinter den Kulissen können, was Sie wollen sein. Aber für eine einfache einen Emulator zu schreiben, gibt es eine mentale Zuordnung, die zwischen dem realen System geschieht, das heißt Chips, Displays, Tastaturen, Leiterplatten, und die abstrakte Computer-Code.
  • ein Computersystem zu emulieren, ist es am einfachsten es in kleinere Stücke zu brechen und diese Stücke einzeln zu emulieren. Dann Zeichenfolge die ganze Menge zusammen für das fertige Produkt. Ähnlich wie eine Reihe von schwarzen Boxen mit Ein- und Ausgängen, die sich schön verleihen orientierten Programmierung zu widersprechen. Sie können weiterhin diese Stücke aufzuteilen, um das Leben zu erleichtern.

Praktisch gesprochen, sind Sie in der Regel der Suche nach Geschwindigkeit und Genauigkeit der Emulation zu schreiben. Dies liegt daran, Software auf dem Zielsystem wird (kann) langsamer als die Original-Hardware auf dem Quellsystem. Das mag die Wahl der Programmiersprache, Compiler, Zielsystem usw.
einschränken Zusätzlich zu, dass Sie umschreiben, was Sie zu emulieren bereit sind, zum Beispiel seines nicht notwendig, den Spannungszustand der Transistoren in einem Mikroprozessor zu emulieren, aber es ist wahrscheinlich notwendig, den Zustand des Registersatzes des Mikroprozessors zu emulieren.
Im Allgemeinen sind die kleineren den Detaillierungsgrad der Emulation zu sprechen, desto mehr Treue werden Sie zum ursprünglichen System.
Schließlich Informationen für ältere Systeme können unvollständig oder nicht vorhanden sein. So habhaft Erstausrüstung ist von wesentlicher Bedeutung, oder zumindest einen weiteren guten Emulator prizing auseinander, dass jemand anderes geschrieben hat!

Ja, Sie haben die ganze binäre Maschinencode Chaos „von Hand“ zu interpretieren. Nicht nur, dass die meiste Zeit Sie auch einige exotische Hardware simulieren müssen, die keine Entsprechung auf der Zielmaschine hat.

Der einfache Ansatz ist die Anweisungen one-by-one zu interpretieren. Das funktioniert gut, aber es ist langsam. Eine schnellere Methode ist Neuübersetzung - die Quelle Maschinencode zu übersetzen Maschinencode zu zielen. Das ist komplizierter, da die meisten Anweisungen nicht eins-zu-eins abzubilden. Stattdessen werden Sie aufwändige Workarounds, die beinhalten zusätzlichen Code vornehmen müssen. Aber am Ende ist es viel schneller. Die meisten modernen Emulatoren tun.

Wenn Sie einen Emulator entwickeln Sie die Prozessoranordnung interpretieren, dass das System auf (Z80, 8080, PS-CPU, etc.) Arbeitet.

Sie müssen auch alle Peripheriegeräte emulieren, die das System (Video-Ausgang, Controller).

Sie sollten beginnen Emulatoren für die simpe Systeme wie die gute alte Game Boy (dass die Verwendung Schreiben ein Z80-Prozessor, bin ich nicht nicht zu verkennen) OR für C64.

  

Emulator ist sehr schwer zu erstellen, da es viele Hacks sind (wie in ungewöhnlich   Effekte), Timing-Probleme, etc., die Sie simulieren müssen.

Ein Beispiel hierfür finden Sie unter http://queue.acm.org/detail .cfm? id = 1755886 .

Das wird Ihnen auch zeigen, warum Sie ein Multi-GHz-CPU ‚Notwendigkeit‘ eine 1MHz eine für die Emulation.

Überprüfen Sie auch Darek Mihocka Emulators.com für gute Ratschläge auf Befehlsebene Optimierung für JITs und viele andere Leckereien auf den Aufbau von effizienten Emulatoren.

Ich habe noch nie etwas so extravagant getan, wie eine Spielkonsole zu emulieren, aber ich habe einmal einen Kurs, wo die Zuordnung einen Emulator für die Maschine in Andrew Tanenbaums Strukturierte Rechnerorganisation . Das hat Spaß gemacht eine gab mir eine Menge Aha Momente. Vielleicht möchten Sie vor dem Tauchen, das Buch holen in einen echten Emulator zu schreiben.

Tipps von einem realen System oder Ihre eigene Sache zu emulieren? Ich kann sagen, dass Emulatoren arbeiten, indem die gesamte Hardware emulieren. Vielleicht nicht bis auf die Schaltung (als Bits um wie die HW bewegen tun würde. Das Byte zu verschieben ist das Endergebnis das Byte so das Kopieren ist in Ordnung). Emulator sind sehr schwer zu erstellen, da es viele Hacks sind (wie in ungewöhnlichen Effekten), Timing-Probleme, etc., die Sie brauchen, zu simulieren. Wenn ein (Eingang) Stück falsch ist das gesamte System tun nach unten oder bestenfalls einen Bug / Glitch hat.

Die Shared Source Device Emulator bebaubare enthält Quellcode zu einem PocketPC / Smartphone-Emulator (Erfordert Visual Studio läuft unter Windows). Ich arbeitete an V1 und V2 der binären Freigabe.

Es befasst sich viele Emulation Fragen: - effiziente Adressübersetzung von Gast zu Gast physischen virtuellen Host virtueller - JIT-Kompilierung von Gastcode - Simulation von Peripheriegeräten wie Netzwerkadapter, Touchscreen und Audio - UI-Integration, für Host-Tastatur und Maus - Speicher / Wiederherstellen des Staates, für die Simulation von Lebenslauf von Low-Power-Modus

die von @Cody Brocious
bereitgestellt Antwort hinzufügen Im Zusammenhang mit der Virtualisierung in dem Sie ein neues System emuliert (CPU, I / O usw.) zu einer virtuellen Maschine können wir die folgenden Kategorien von Emulatoren sehen.

Interpretation: bochs ist ein Beispiel für Dolmetscher, es ist ein x86-PC-Emulator, dauert es jede Anweisung von Gastsystem übersetzt sie in einem anderen Satz von Befehl (des Host-ISA) die beabsichtigten effect.Yes zu produzieren es ist sehr langsam es cachen nicht alles so jede Anweisung durch den gleichen Zyklus geht.

Dynamische emalator: Qemu ist ein dynamisches Emulator. Es tut on the fly Übersetzung von Gastanweisung Caches auch Ergebnisse.Die bester Teil ist, dass so viele Befehle wie möglich direkt auf dem Host-System führt, so dass Emulation schneller ist. Auch, wie durch Cody erwähnt, teilt sie den Code in Blöcke (1 Einstrom der Ausführung).

Static Emulator: Soweit ich weiß, gibt es keinen statischen Emulator, der in den Bereichen Virtualisierung nützlich sein kann.

Wie würde ich Emulation starten.

1.Get Bücher auf Basis niedriges Niveau Programmierung, Sie werden sie brauchen für das „vortäuschen“ Betriebssystem des Nintendo ... Gameboy ...

2.Get Bücher über Emulation speziell, und vielleicht os Entwicklung. (Sie werden nicht ein Betriebssystem werden zu machen, aber in der Nähe von ihm.

3.Look bei einigen Open-Source-Emulatoren, vor allem diejenigen des Systems Sie einen Emulator für machen wollen.

4.Kopieren Schnipsel des komplexeren Code in Ihre IDE / Compilers. Dadurch sparen Sie lange das Schreiben von Code aus. Dies ist, was ich für os Entwicklung zu tun, verwenden Sie einen Kreis von Linux

Ich schrieb einen Artikel über die Emulation der Chip-8-System in JavaScript .

Es ist ein großartiger Ort, wie das System zu starten, ist nicht sehr kompliziert, aber man noch lernen, wie OP-Codes, der Stapel, Register, usw. zu arbeiten.

Ich werde eine längere Führung bald für das NES schreiben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top