Ich möchte zuerst meine Frage vorbringen, indem ich zuerst sage, dass ich ein ziemlich erfahrener Programmierer bin, vor allem, weil Java ihn seit 8 Jahren benutzt.Z80 DAA-Implementierung und Blarggs Test-ROM-Ausgaben
Ich beschloss, in einem Versuch, mein Verständnis von Hardware-Betrieb und Betriebssystem Themen zu verbessern, einen einfachen Gameboy-Emulator zu programmieren. Nachdem ich die Kernfunktionalität in nur wenigen Tagen programmiert hatte, testete ich den Emulator, um festzustellen, dass nichts auf dem Bildschirm gezeichnet wurde. Nachdem ich nacheinander mehrere hundert Opcodes in meinem Emulator durchgespielt und mit den im BGB-Emulator gefundenen Werten verglichen hatte, erkannte ich, dass die fraglichen Kacheln und Sprites in den Speicher geladen wurden, nur nicht gezeichnet. Daraus ging hervor, dass das Problem in einer oder mehreren meiner Opcode-Implementierungen liegen muss, was dazu führt, dass das Programm irgendwann ein falsches Verhalten zeigt. Aus diesem Grund habe ich mich entschieden, Blarggs CPU-Test-ROMs (http://gbdev.gg8.se/files/roms/blargg-gb-tests/) zu verwenden, um mir dabei zu helfen, das Problem zu identifizieren. Um jedoch das erste Test-ROM ausgeführt wird, gibt die folgende Fehlermeldung:
01-special
36E1FE30
DAA
Failed #6
ich die DAA Operation mehrmals überprüft und es scheint richtig zu mir umgesetzt werden. Der angegebene Fehlercode ("36E1FE30") ist absolut nicht hilfreich, da ich nicht finden kann, was das bedeutet. Für mich bedeutet dies, dass entweder DAA falsch implementiert ist und ich meinen Fehler nicht sehen kann oder eine der Operationen, die verwendet werden, um die Richtigkeit von DAA zu validieren, ist falsch. Wenn ich einen der anderen Tests ausgeführt erscheinen sie in einer Schleife auf unbestimmte Zeit
03-op sp,hl
03-op sp,hl
03-op sp,hl
03-op sp,hl
Als Referenz meine DAA-Implementierung auf Github ist (https://github.com/qkmaxware/GBemu/blob/master/src/gameboy/cpu/Opcodes.java) oder unten wie folgt zu sehen:
Op DAA = new Op(0x27, "DAA", map,() -> {
int a = reg.a();
if(!reg.subtract()){
if(reg.halfcarry() || (a & 0xF) > 9)
a += 0x06;
if(reg.carry() || a > 0x9F)
a += 0x60;
}else{
if(reg.halfcarry())
a = (a - 0x6) & 0xFF;
if(reg.carry())
a = (a - 0x60) & 0xFF;
}
reg.a(a);
reg.zero(isZero(a));
reg.carry((a & 0x100) == 0x100);
reg.halfcarry(false);
clock.m(1);
clock.t(4);
});
Wo solche Anrufe als reg.a() bedeutet gelesen aus dem Register a, reg.a (Wert) bedeutet Schreiben in Register a (Maske auf 8 oder 16 Bits abhängig vom Register). In ähnlicher Weise können die Flags Z, N, H, C erhalten oder mit den Null-, Subtrahier-, Halbcarry- und Übertragsfunktionen des "reg" -Objekts gesetzt/zurückgesetzt werden.
Also meine Frage ist dreifach, habe ich die DAA-Operation falsch implementiert, so dass es Blargg Tests fehlschlägt, weiß jemand, was der Fehlercode ich habe, oder hat jemand irgendwelche Ideen, wie ich meine Suche nach dem falschen konzentrieren kann Betrieb.
Wow, danke für die tollen Informationen über die Test-ROMs und den Link zu den MAME-Opcode-Implementierungen. Die Opcode-Implementierungen sind so viel besser zu lesen als einige der anderen Open-Source-Projekte. – Hals
@Hals: Hast du jemals herausgefunden, was das Problem in deinem eigenen Code war, oder hast du es einfach weggeworfen und stattdessen MAME's benutzt? – usr2564301
@ usr256430: 1 Am Ende habe ich eine Kombination aus der MAME-Version und anderen Versionen von anderen Emulatoren auf GitHub verwendet, anstatt meiner eigenen. – Hals