CPU-Emulation und sperren, die eine bestimmte Taktfrequenz
Wenn Sie hatten, Lesen Sie meine anderen Frage, wissen Sie, ich habe dieses Wochenende zusammen eine 6502-CPU emulator als Programmier-übung.
Den CPU-emulator ist weitgehend abgeschlossen, und scheint zu sein, ziemlich genau aus meiner begrenzten testen, aber es läuft unglaublich schnell, und ich will Gas nach unten auf das tatsächliche Taktrate der Maschine.
Meiner aktuellen test-Schleife ist dieses:
//Just loop infinitely.
while (1 == 1)
{
CPU.ClockCyclesBeforeNext--;
if (CPU.ClockCyclesBeforeNext <= 0)
{
//Find out how many clock cycles this instruction will take
CPU.ClockCyclesBeforeNext = CPU.OpcodeMapper.Map[CPU.Memory[CPU.PC]].CpuCycles;
//Run the instruction
CPU.ExecuteInstruction(CPU.Memory[CPU.PC]);
//Debugging Info
CPU.DumpDebug();
Console.WriteLine(CPU.OpcodeMapper.Map[CPU.Memory[CPU.PC]].ArgumentLength);
//Move to next instruction
CPU.PC += 1 + CPU.OpcodeMapper.Map[CPU.Memory[CPU.PC]].ArgumentLength;
}
}
Wie Sie sagen können, jeder Befehl dauert eine bestimmte Zeit abgeschlossen, so dass ich das nicht ausführen des nächsten Befehls, bis ich die count-down-CPU-Zyklus-Uhr. Dies liefert das richtige timing zwischen opcodes, seine nur, dass die ganze Sache läuft viel zu schnell.
Der Ziel-CPU-Geschwindigkeit ist 1.79 mhz, aber ich würde gerne welche Lösung auch immer um-die-Uhr-Ausgabe zu halten, die Geschwindigkeit, mit 1.79 mhz auch, wie ich hinzufügen, Komplexität, so dass ich nicht haben, um Sie einzustellen.
Irgendwelche Ideen?
InformationsquelleAutor FlySwat | 2008-09-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Schrieb ich einen Z80-emulator vor vielen Jahren, und zu tun, Zyklus genaue Ausführung, ich teilte die Taktfrequenz in eine Anzahl von kleinen Blöcken und hatte den Kern führen, dass viele clock-Zyklen. In meinem Fall, ich Band es um die frame-rate des Spiels war ich zur Nachahmung zu empfehlen. Jeder opcode wusste, wie viele Zyklen es dauerte ausführen und den Kern halten würde opcodes ausgeführt, bis die angegebene Anzahl von Zyklen hingerichtet worden. Ich hatte eine äußere Schleife laufen, die die cpu-core, und führen Sie andere Teile der emulierten system und dann schlafen Sie, bis die start-Zeit der nächsten iteration.
BEARBEITEN: Hinzufügen Beispiel der run loop.
Hoffe, das hilft.
InformationsquelleAutor Jason Fritcher
Werfen Sie einen Blick auf die ursprüngliche quicktime-Dokumentation für die inspiration.
Es wurde vor langer Zeit geschrieben, wenn die Anzeige von video bedeutete nur tauschen Standbilder auf dem genug hohen Geschwindigkeit, aber die Apple-Leute beschlossen, Sie benötigt eine Vollzeit-management-framework. Das design auf den ersten Blick overengineered, aber lassen Sie es, Sie beschäftigen sich mit sehr unterschiedlichen Anforderungen an Geschwindigkeit und halten Sie Sie fest synchronisiert.
du hast Glück gehabt, dass der 6502 hat deterministische Zeit-Verhalten, die genaue Zeit jede Anweisung braucht, ist gut dokumentiert; aber es ist nicht konstant. einige Befehle benötigen 2 Zyklen, die 3 anderen. Nur, wie frames in QuickTime ein video nicht "frames pro Sekunde" parameter jedes Bild erzählt, wie lange Sie es will, werden im Bildschirm.
Da moderne CPU ' s sind also nicht-deterministisch, und multitasking-Betriebssystem ist, können sogar einfrieren für ein paar Millisekunden (virtueller Speicher!), halten Sie eine Registerkarte, wenn Sie sind hinter dem Zeitplan, oder wenn Sie können, nehmen Sie sich ein paar Mikrosekunden nap.
InformationsquelleAutor Javier
Als jfk sagt, der häufigste Weg, dies zu tun ist, binden Sie die cpu-Geschwindigkeit auf der vertikalen refresh des (emulierten) video-Ausgang.
Wählen Sie eine Anzahl der Zyklen, die zum ausführen von pro video-frame. Dies wird oft in der Maschine-spezifisch, aber Sie kann es berechnen, indem Sie so etwas wie :
Dann bekommst du auch tun, ein Schlaf, bis die video-update ist der hit, an diesem Punkt beginnen Sie den nächsten n Zyklen der CPU-emulation.
Wenn Sie die Emulation etwas bestimmtes dann brauchen Sie nur, um sich die fps-rate und Prozessor-Geschwindigkeit zu bekommen, das ungefähr richtig.
EDIT: Wenn Sie keine externe timing-Anforderungen, dann ist es normal für einen emulator, um nur so schnell laufen, wie Sie kann. Das ist manchmal erwünscht und manchmal nicht 🙂
InformationsquelleAutor David Gardner
Ich würde das clock-Zyklen zu berechnen, die Zeit und Sie schlafen, wird der Unterschied in der Zeit. Natürlich, um dies zu tun, benötigen Sie einen high-resolution-Uhr. Sie Art und Weise Sie es tun, geht spike die CPU in der Spinnerei Schleifen.
InformationsquelleAutor Lou Franco
Ja, wie gesagt, die meisten der Zeit, die Sie nicht brauchen, ein CPU-emulator zum emulieren von Anweisungen mit der gleichen Geschwindigkeit von der realen Sache. Was user wahrnehmen, ist die Ausgabe der Berechnung (D. H. audio-und video-Ausgänge), so dass Sie nur brauchen, um in sync mit solchen Ausgängen, das bedeutet nicht, müssen Sie unbedingt eine genaue CPU-emulation Geschwindigkeit.
In anderen Worten, wenn die frame-rate der video-Eingang ist, sagen wir mal, 50 Hz, dann lass den CPU-emulator laufen, so schnell wie möglich zu ziehen, der Bildschirm aber sicher sein, um die Ausgabe der Bildschirm-frames in der korrekten rate (50Hz). Aus einer externen Sicht auf Ihre emulator emuliert in der richtigen Geschwindigkeit.
Versuchen zu Zyklus genauer sogar die in der Ausführung Zeit ist ein nicht-Sinn auf einem multi-tasking-Betriebssystem wie Windows oder Linux, weil der emulator Anweisung Zeit (typisch 1 für vintage-80er Jahre-CPUs) und den scheduling-Zeitfenster der modernen OS vergleichbar sind.
Versuchen, um die Ausgabe etwas bei einem 50Hz-rate ist eine viel einfachere Aufgabe, die Sie tun können, sehr gut auf jedem modernen Rechner
InformationsquelleAutor Gianluca Ghettini
Andere option ist verfügbar, wenn die audio-emulation implementiert ist, und wenn die audio-Ausgabe ist gebunden an die system/CPU-Takt. Insbesondere weiß ich, dass dies der Fall mit den 8-bit-Apple ][ Computer.
In der Regel wird der Klang in Puffer mit einer festen Größe (mit fester Zeit), so dass die Funktion (Generierung von Daten etc.) dieser Puffer kann gebunden werden, um CPU-Durchsatz durch Synchronisationsfunktionen.
InformationsquelleAutor Nick Westgate
Ich bin in den Prozess der Herstellung etwas ein wenig mehr Allgemeinen use-case-basierten, wie die Fähigkeit zur Konvertierung Zeit, um eine geschätzte Menge von Anweisungen und Umgekehrt.
Projekt-homepage ist @ http://net7mma.codeplex.com
Der code beginnt so: (ich glaube)
Sobald Sie haben eine Art von Laien-Uhr-Implementierung Voraus, um so etwas wie eine
Timer
Dann können Sie wirklich replizieren einige Logik mit so etwas wie
Endlich, etwas auf die semi-nützlich z.B. einen Bus und dann vielleicht noch einen virtuellen Bildschirm zum aussenden von Daten auf den bus...
Hier ist, wie ich getestet habe die
StopWatch
InformationsquelleAutor Jay