964 Stimmen

Wie funktionieren die Emulatoren und wie werden sie geschrieben?

Wie funktionieren die Emulatoren? Wenn ich NES/SNES- oder C64-Emulatoren sehe, erstaunt mich das.

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

Müssen Sie den Prozessor dieser Maschinen emulieren, indem Sie seine speziellen Assemblerbefehle interpretieren? Was gehört noch dazu? Wie sind sie typischerweise aufgebaut?

Können Sie jemandem, der an der Entwicklung eines Emulators (insbesondere eines Spielsystems) interessiert ist, einen Rat geben?

15 Stimmen

Das Wichtigste, was Sie finden müssen, ist das "Programmiererhandbuch" für dieses System, da es den "Vertrag" zwischen dem HW-Anbieter und den Programmierern beschreibt und Details verbirgt, die nicht relevant sind und sich ändern könnten. Ihre Chancen hängen von der Popularität des Systems ab.

155 Stimmen

Gute Wahl des Spiels.

2 Stimmen

1118voto

Serafina Brocious Punkte 29935

Emulation ist ein facettenreiches Gebiet. Hier sind die grundlegenden Ideen und Funktionskomponenten. Ich werde es in Stücke brechen und dann die Details durch Bearbeitungen ausfüllen. Viele der Dinge, die ich beschreiben werde, erfordern Kenntnisse über das Innenleben von Prozessoren - Assembler-Kenntnisse sind erforderlich. Wenn ich bei bestimmten Dingen etwas zu vage bin, stellen Sie bitte Fragen, damit ich diese Antwort weiter verbessern kann.

Die Grundidee:

Bei der Emulation wird das Verhalten des Prozessors und der einzelnen Komponenten nachgebildet. Sie bauen jedes einzelne Teil des Systems und verbinden die Teile dann ähnlich wie Drähte in der Hardware.

Prozessor-Emulation:

Es gibt drei Möglichkeiten, mit der Prozessoremulation umzugehen:

  • Auslegung
  • Dynamische Neukompilierung
  • Statische Neukompilierung

Bei all diesen Pfaden verfolgen Sie das gleiche Ziel: Sie führen ein Stück Code aus, um den Prozessorstatus zu ändern und mit der "Hardware" zu interagieren. Der Prozessorstatus ist ein Konglomerat aus Prozessorregistern, Interrupt-Handlern usw. für ein bestimmtes Prozessorziel. Für den 6502 gibt es eine Reihe von 8-Bit-Ganzzahlen, die Register darstellen: A , X , Y , P y S ; Sie hätten auch eine 16-Bit PC registrieren.

Beim Dolmetschen beginnt man bei der IP (Befehlszeiger -- auch genannt PC , Programmzähler) und lesen den Befehl aus dem Speicher. Ihr Code analysiert diese Anweisung und verwendet diese Informationen, um den Zustand des Prozessors entsprechend den Vorgaben Ihres Prozessors zu ändern. Das Hauptproblem bei der Interpretation ist, dass sie sehr langsam; jedes Mal, wenn Sie eine bestimmte Anweisung bearbeiten, müssen Sie sie dekodieren und die erforderliche Operation durchführen.

Bei der dynamischen Rekompilierung durchlaufen Sie den Code ähnlich wie bei der Interpretation, aber anstatt nur Opcodes auszuführen, erstellen Sie eine Liste von Operationen. Sobald Sie zu einer Verzweigungsanweisung gelangen, kompilieren Sie diese Liste von Operationen zu Maschinencode für Ihre Host-Plattform, dann speichern Sie diesen kompilierten Code zwischen und führen ihn aus. Wenn Sie dann erneut auf eine bestimmte Befehlsgruppe stoßen, müssen Sie nur noch den Code aus dem Cache ausführen. (Übrigens erstellen die meisten Leute keine Liste von Anweisungen, sondern kompilieren sie spontan zu Maschinencode - das erschwert die Optimierung, aber das würde den Rahmen dieser Antwort sprengen, es sei denn, genügend Leute sind daran interessiert.)

Bei der statischen Neukompilierung tun Sie dasselbe wie bei der dynamischen Neukompilierung, aber Sie folgen den Verzweigungen. Am Ende wird ein Stück Code erstellt, das den gesamten Code des Programms repräsentiert und das dann ohne weitere Eingriffe ausgeführt werden kann. Dies wäre ein großartiger Mechanismus, wenn es nicht die folgenden Probleme gäbe:

  • Code, der nicht von Anfang an im Programm enthalten ist (z. B. komprimiert, verschlüsselt, zur Laufzeit generiert/geändert usw.), wird nicht neu kompiliert und kann daher nicht ausgeführt werden.
  • Es ist erwiesen, dass das Auffinden des gesamten Codes in einer gegebenen Binärdatei gleichbedeutend ist mit der Halteproblem

Diese Kombination macht die statische Neukompilierung in 99 % der Fälle völlig undurchführbar. Für weitere Informationen hat Michael Steil einige großartige Untersuchungen zur statischen Rekompilierung durchgeführt - die besten, die ich gesehen habe.

Die andere Seite der Prozessoremulation ist die Art und Weise, wie Sie mit der Hardware interagieren. Dies hat wirklich zwei Seiten:

  • Prozessor-Timing
  • Behandlung von Unterbrechungen

Prozessor-Taktung:

Bestimmte Plattformen - vor allem ältere Konsolen wie das NES, SNES usw. - verlangen von Ihrem Emulator ein strenges Timing, um vollständig kompatibel zu sein. Beim NES gibt es die PPU (Pixel Processing Unit), die dafür sorgt, dass die CPU die Pixel zu bestimmten Zeitpunkten in den Speicher lädt. Wenn Sie die Interpretation verwenden, können Sie leicht Zyklen zählen und das richtige Timing emulieren; mit dynamischer/statischer Rekompilierung sind die Dinge viel komplexer.

Behandlung von Unterbrechungen:

Interrupts sind der wichtigste Mechanismus, mit dem die CPU mit der Hardware kommuniziert. Im Allgemeinen teilen Ihre Hardwarekomponenten der CPU mit, welche Interrupts für sie von Bedeutung sind. Das ist ziemlich einfach - wenn Ihr Code einen bestimmten Interrupt auslöst, schauen Sie in die Interrupt-Handler-Tabelle und rufen den richtigen Callback auf.

Hardware-Emulation:

Es gibt zwei Seiten der Emulation eines bestimmten Hardwaregeräts:

  • Emulation der Funktionalität des Geräts
  • Emulation der tatsächlichen Geräteschnittstellen

Nehmen wir den Fall einer Festplatte. Die Funktionalität wird durch die Erstellung des Sicherungsspeichers, Lese-/Schreib-/Formatierungsroutinen usw. emuliert. Dieser Teil ist im Allgemeinen sehr einfach.

Die eigentliche Schnittstelle des Geräts ist etwas komplexer. In der Regel handelt es sich um eine Kombination aus speicherabgebildeten Registern (z. B. Teile des Speichers, die das Gerät auf Änderungen zur Signalisierung überwacht) und Interrupts. Bei einem Festplattenlaufwerk können Sie einen speicherzugeordneten Bereich haben, in dem Sie Lese- und Schreibbefehle usw. platzieren und diese Daten dann zurücklesen.

Ich würde mehr ins Detail gehen, aber es gibt eine Million Möglichkeiten, die Sie damit gehen können. Wenn Sie irgendwelche spezifischen Fragen haben, fragen Sie mich, und ich werde die Informationen hinzufügen.

Ressourcen:

Ich denke, ich habe hier eine ziemlich gute Einführung gegeben, aber es gibt eine t von zusätzlichen Bereichen. Ich bin gerne bereit, Ihnen bei Fragen zu helfen; ich habe mich aufgrund der immensen Komplexität in den meisten Punkten sehr vage ausgedrückt.

Obligatorische Wikipedia-Links:

Allgemeine Emulationsressourcen:

  • Zophar -- Hier habe ich meine ersten Erfahrungen mit Emulationen gemacht, indem ich zunächst Emulatoren heruntergeladen und schließlich deren riesige Dokumentationsarchive geplündert habe. Das ist die absolut beste Ressource, die man haben kann.
  • NGEmu -- Nicht viele direkte Ressourcen, aber ihre Foren sind unschlagbar.
  • RomHacking.net -- Der Abschnitt "Dokumente" enthält Ressourcen zur Maschinenarchitektur für gängige Konsolen

Emulator-Projekte zum Nachschlagen:

  • EisenBabel -- Dies ist eine Emulationsplattform für .NET, die in Nemerle geschrieben ist und Code im Handumdrehen nach C# rekompiliert. Haftungsausschluss: Dies ist mein Projekt, also verzeihen Sie die schamlose Werbung.
  • BSnes -- Ein großartiger SNES-Emulator mit dem Ziel der zyklusgenauen Genauigkeit.
  • MAME -- Die Arcade-Emulator. Tolle Referenz.
  • 6502asm.com -- Dies ist ein JavaScript 6502-Emulator mit einem coolen kleinen Forum.
  • dynarec'd 6502asm -- Dies ist ein kleiner Hack, den ich innerhalb von ein oder zwei Tagen gemacht habe. Ich nahm den bestehenden Emulator von 6502asm.com und änderte ihn so, dass er den Code dynamisch in JavaScript neu kompiliert, um die Geschwindigkeit massiv zu erhöhen.

Referenzen für die Neukompilierung des Prozessors:

  • Die von Michael Steil durchgeführten Forschungen zur statischen Rekompilierung (siehe oben) gipfelten in dieses Papier und Sie können Quellen und dergleichen finden aquí .

Nachtrag:

Es ist weit über ein Jahr her, dass diese Antwort eingereicht wurde, und bei all der Aufmerksamkeit, die sie erhalten hat, dachte ich mir, dass es an der Zeit ist, einige Dinge zu aktualisieren.

Die vielleicht aufregendste Sache auf dem Gebiet der Emulation ist im Moment libcpu die von dem bereits erwähnten Michael Steil ins Leben gerufen wurde. Es ist eine Bibliothek, die eine große Anzahl von CPU-Kernen unterstützen soll, die LLVM für die Neukompilierung (statisch und dynamisch!) verwenden. Es hat ein riesiges Potenzial, und ich denke, es wird große Dinge für die Emulation tun.

emu-docs wurde ich auch auf eine große Sammlung von Systemdokumentation aufmerksam gemacht, die für Emulationszwecke sehr nützlich ist. Ich habe noch nicht viel Zeit dort verbracht, aber es sieht so aus, als hätten sie eine Menge großartiger Ressourcen.

Ich freue mich, dass dieser Beitrag hilfreich war, und ich hoffe, dass ich meinen Arsch hochbekomme und mein Buch zu diesem Thema bis Ende des Jahres/Anfang nächsten Jahres fertigstellen kann.

37 Stimmen

Dies ist bereits eine epische Antwort, die sich anbahnt. Wenn Sie mich auf irgendwelche Ressourcen als auch am Ende der es wäre zu schätzen wissen. Ich bin auf möglicherweise die SNES oder NES-System zu emulieren und machen es mein Semester-Projekt.

8 Stimmen

Gewiss. Ich werde eine schöne Liste von Ressourcen zusammenstellen. Wenn ihr irgendwelche speziellen Wünsche habt, werde ich mein Bestes tun, um sie zu erfüllen.

0 Stimmen

In Bezug auf Anfragen, Ressourcen, die sich direkt auf die Theorie/Design von Emulatoren beziehen, und spezifischere Ressourcen, die sich auf Snes/Nes-Systeme beziehen. Aufgrund der Geschwindigkeit der modernen Systeme würden Sie sagen, dass das Schreiben eines brauchbaren Snes-Emulators mit Interpretation möglich ist?

126voto

mdm Punkte 5439

Ein gewisser Victor Moya del Barrio hat seine Doktorarbeit über dieses Thema geschrieben. Auf 152 Seiten gibt es viele gute Informationen. Sie können das PDF herunterladen aquí .

Wenn Sie sich nicht registrieren möchten scribd können Sie nach dem PDF-Titel googeln, "Studie über die Techniken der Emulationsprogrammierung" . Es gibt verschiedene Quellen für die PDF-Datei.

43voto

Uri Punkte 86472

Die Emulation mag abschreckend wirken, ist aber eigentlich viel einfacher als die Simulation.

Jeder Prozessor hat in der Regel eine gut geschriebene Spezifikation, die Zustände, Interaktionen usw. beschreibt.

Wenn Ihnen die Leistung völlig gleichgültig ist, können Sie die meisten älteren Prozessoren mit sehr eleganten objektorientierten Programmen leicht emulieren. Ein X86-Prozessor bräuchte zum Beispiel etwas, das

Viele Mikrochip- und CPU-Hersteller testen ihre Programme zunächst mit einem Emulator des Chips und dann mit dem Chip selbst, um herauszufinden, ob es Probleme mit den Spezifikationen des Chips oder mit der tatsächlichen Implementierung des Chips in der Hardware gibt. Es ist zum Beispiel möglich, eine Chipspezifikation zu schreiben, die zu Deadlocks führt, und wenn ein Deadlock in der Hardware auftritt, ist es wichtig zu sehen, ob er in der Spezifikation reproduziert werden kann, da dies auf ein größeres Problem hinweist als etwas in der Chip-Implementierung.

Natürlich sind Emulatoren für Videospiele in der Regel auf Leistung bedacht, so dass sie keine naiven Implementierungen verwenden, und sie enthalten auch Code, der eine Schnittstelle zum Betriebssystem des Wirtssystems bildet, um z. B. Zeichnungen und Sound zu verwenden.

In Anbetracht der sehr langsamen Leistung alter Videospiele (NES/SNES usw.) ist die Emulation auf modernen Systemen recht einfach. Es ist sogar noch erstaunlicher, dass man einfach ein Set aller SNES-Spiele oder Atari 2600-Spiele herunterladen kann, wenn man bedenkt, dass es zur Zeit der Popularität dieser Systeme ein wahrgewordener Traum gewesen wäre, freien Zugang zu allen Kassetten zu haben

1 Stimmen

Was sind die Unterschiede zwischen Emulation und Simulation?

2 Stimmen

@Wei: Im Allgemeinen soll sich ein Emulator "äußerlich" wie das System verhalten, das er emuliert, aber es gibt keinen Hinweis darauf, dass er auf ähnliche Weise implementiert sein muss. Ein Simulator wird so implementiert, dass er das simulierte System nachahmt und sich demzufolge auch so verhält.

0 Stimmen

Wenn Sie "Simulator" sehen, denken Sie, dass es ähnlich ist, während ein Emulator "emuliert".

29voto

Vivian River Punkte 29806

Ich weiß, dass diese Frage schon etwas älter ist, aber ich möchte gerne etwas zur Diskussion beitragen. Die meisten Antworten hier drehen sich um Emulatoren, die die Maschinenbefehle der Systeme interpretieren, die sie emulieren.

Es gibt jedoch eine sehr bekannte Ausnahme davon, die "UltraHLE" ( WIKIpedia-Artikel ). UltraHLE, einer der berühmtesten Emulatoren aller Zeiten, emulierte kommerzielle Nintendo 64-Spiele (mit anständiger Leistung auf Heimcomputern) zu einer Zeit, als es allgemein als unmöglich galt, dies zu tun. Tatsächlich produzierte Nintendo immer noch neue Titel für das Nintendo 64, als UltraHLE entwickelt wurde!

Zum ersten Mal sah ich Artikel über Emulatoren in gedruckten Magazinen, wo ich sie zuvor nur im Internet gesehen hatte.

Das Konzept von UltraHLE bestand darin, das Unmögliche möglich zu machen, indem C-Bibliotheksaufrufe anstelle von Aufrufen auf Maschinenebene emuliert wurden.

22voto

Julio Punkte 5908

Einen Blick wert ist der Versuch von Imran Nazar, ein Buch zu schreiben Gameboy Emulator in JavaScript.

1 Stimmen

Wie erhalten wir die Roh-Opcode-Anweisungen für das Gameboy-Spiel?

0 Stimmen

Es gibt eine Reihe von Geräten, die auf dem "grauen Markt" angeboten werden. Sie werden sie in keinem größeren Geschäft in den Industrieländern finden. Diese Geräte sind in der Lage, die Anweisungen von der Spielkassette in Dateien zu kopieren, die gewöhnlich "ROMs" genannt werden. Googeln Sie "Gameboy Roms", aber achten Sie auf unsichere Links und Angriffsseiten!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X