robert / gameboy-doctor Goto Github PK
View Code? Open in Web Editor NEWDebug and fix your gameboy emulator
Home Page: https://robertheaton.com/gameboy-doctor/
License: MIT License
Debug and fix your gameboy emulator
Home Page: https://robertheaton.com/gameboy-doctor/
License: MIT License
first of all, thank you so much for this life saver. It really saved me probably days of debugging.
But there is one thing I can't understand. I'm passing all the blargg tests at this point but the 02-interrupts one doesn't get approved by your script. I get the following:
Mismatch in CPU state at line 151346:
MINE: A:04 F:C--- B:01 C:00 D:C7 E:BA H:90 L:00 SP:DFFD PC:C2C0 PCMEM:05,C2,B9,C1
YOURS: A:04 F:C--- B:01 C:00 D:C7 E:BA H:90 L:00 SP:DFFB PC:0050 PCMEM:3C,C9,00,00
However blargg tests print "passed". What can be the issue here? May it be because the rom itself has changed since your last upload?
07-jr,jp,call,ret,rst.gb has 3C C9 00 00 00 00 00 00
repeated 6 times at offset 0000
. The ROM used has 31 FE FF AF
.
============== ERROR ==============
Mismatch in CPU state at line 254074:
MINE: A:12 F:---- B:12 C:00 D:DE E:FB H:C6 L:3D SP:DF7C PC:0000 PCMEM:31,FE,FF,AF
YOURS: A:12 F:---- B:12 C:00 D:DE E:FB H:C6 L:3D SP:DF7C PC:0000 PCMEM:3C,C9,00,00
Our values for PC are the same, but the memory at the location of PC is different. Perhaps you told me to check the wrong ROM type or number?
Hi,
Thanks for this wonderful project! It's great to get some earlier validation rather than having to wait for implementing the LCD.
In my first attempt (using 06-ld r,r.gb
) I was disheartened that my log failed on 2nd line. Then I noticed that the log timings were different.
Reference log:
A:01 F:B0 B:00 C:13 D:00 E:D8 H:01 L:4D SP:FFFE PC:0100 PCMEM:00,C3,13,02
A:01 F:B0 B:00 C:13 D:00 E:D8 H:01 L:4D SP:FFFE PC:0101 PCMEM:C3,13,02,CE
A:01 F:B0 B:00 C:13 D:00 E:D8 H:01 L:4D SP:FFFE PC:0213 PCMEM:21,00,40,C3
A:01 F:B0 B:00 C:13 D:00 E:D8 H:40 L:00 SP:FFFE PC:0216 PCMEM:C3,00,02,00
A:01 F:B0 B:00 C:13 D:00 E:D8 H:40 L:00 SP:FFFE PC:0200 PCMEM:47,11,00,C0
...
My log (observe the PC
values to see the pattern):
A:01 F:B0 B:00 C:13 D:00 E:D8 H:01 L:4D SP:FFFE PC:0100 PCMEM:00,C3,13,02
A:01 F:B0 B:00 C:13 D:00 E:D8 H:01 L:4D SP:FFFE PC:0101 PCMEM:C3,13,02,CE
A:01 F:B0 B:00 C:13 D:00 E:D8 H:01 L:4D SP:FFFE PC:0102 PCMEM:13,02,CE,ED
A:01 F:B0 B:00 C:13 D:00 E:D8 H:01 L:4D SP:FFFE PC:0103 PCMEM:02,CE,ED,66
A:01 F:B0 B:00 C:13 D:00 E:D8 H:01 L:4D SP:FFFE PC:0104 PCMEM:CE,ED,66,66
A:01 F:B0 B:00 C:13 D:00 E:D8 H:01 L:4D SP:FFFE PC:0213 PCMEM:21,00,40,C3
A:01 F:B0 B:00 C:13 D:00 E:D8 H:01 L:4D SP:FFFE PC:0214 PCMEM:00,40,C3,00
A:01 F:B0 B:00 C:13 D:00 E:D8 H:01 L:00 SP:FFFE PC:0215 PCMEM:40,C3,00,02
A:01 F:B0 B:00 C:13 D:00 E:D8 H:40 L:00 SP:FFFE PC:0216 PCMEM:C3,00,02,00
A:01 F:B0 B:00 C:13 D:00 E:D8 H:40 L:00 SP:FFFE PC:0217 PCMEM:00,02,00,00
A:01 F:B0 B:00 C:13 D:00 E:D8 H:40 L:00 SP:FFFE PC:0218 PCMEM:02,00,00,00
A:01 F:B0 B:00 C:13 D:00 E:D8 H:40 L:00 SP:FFFE PC:0219 PCMEM:00,00,00,00
I figured out that the reference log is showing one line per operation whereas I was outputting one line per cpu cycle.
I'm still only part way through my game boy emulator journey and this is my first emulator so I'm probably misunderstanding several things, but this seems like a missed opportunity. i.e. if we take one of the first operations executed in this test rom: JP a16
/ JP nn
/ 0xC3
, the timings I can find for it ATM are:
CPU cycle 1: fetch operation
CPU cycle 2: read 16 bit operand lower
CPU cycle 2: read 16 bit operand upper
CPU cycle 3: internal delay
Having one log entry per cpu cycle would be able to catch emulators that don't match these timings, whereas one log entry per operation allows any combination or merging of cycles 2-4.
I have a couple of thoughts on why it mightn't be desirable to do one entry per cpu cycle:
I'd be interested to hear people's thoughts on this.
See screenshot above that this log just tells the user that the PREFIX CB instruction occurred, not which specific prefix instruction. While I was debugging my emulator, I felt like if the specific prefix instruction had been included, it would save me a lot of time.
I'm looking to add this in a PR when I find the time.
Below is the error produced:
$ ./gameboy-doctor 10-bit\ ops.log cpu_instrs 10
============== ERROR ==============
Mismatch in CPU state at line 44715:
MINE: A:1B F:C-NZ B:00 C:FF D:CF E:21 H:CF L:35 SP:DFFB PC:CF35 PCMEM:E1,C9,F5,E0
YOURS: A:1B F:C-NZ B:00 C:FF D:CF E:21 H:CF L:35 SP:DFFB PC:C9E1 PCMEM:B8,92,A7,75
The CPU state before this (at line 44714) was:
A:1B F:D0 B:00 C:FF D:CF E:21 H:CF L:35 SP:DFFB PC:C0C6 PCMEM:E9,F5,18,03
The last operation executed (in between lines 44714 and 44715) was:
0xE9 JP HL
Perhaps the problem is with this opcode, or with your interrupt handling?
Looking at the highlighted value, PC:C9E1, it seems the emulator used to make the log misinterprets opcode 0xE9 . The instruction for it is JP [HL]
, meaning "set PC to memory values HL and HL + 1"
The Blargg test rom copies the second memory bank into WRAM, meaning we can find the intended value in the test rom it self at offset 0x4F35.
And indeed it's 0xC9E1. I would suggest redoing all the log files, as this tool is too useful to be left in limbo.
I'm attempting to integrate this into my automated testing for my emulator, but the script does not produce a different error code when it finds an error, making it more difficult to detect errors automatically.
$ ./gameboy-doctor cpu_state.log cpu_instrs 1
============== ERROR ==============
Mismatch in CPU state at line 16509:
MINE: A:86 F:---- B:FB C:1F D:D0 E:00 H:C7 L:B1 SP:DFF3 PC:C367 PCMEM:FE,90,20,F5
YOURS: A:90 F:---- B:FB C:1F D:D0 E:00 H:C7 L:B1 SP:DFF3 PC:C367 PCMEM:FE,90,20,F5
The CPU state before this (at line 16508) was:
A:FF F:00 B:FB C:1F D:D0 E:00 H:C7 L:B1 SP:DFF3 PC:C365 PCMEM:F0,44,FE,90
The last operation executed (in between lines 16508 and 16509) was:
0xF0 LDH A (a8)
Perhaps the problem is with this opcode, or with your interrupt handling?
The CPU instruction executed is F0 44
= LDH A, (0x44)
which should be loading the LY register into A. The docs say to hardcode LY to return 0x90
always but it seems the internal log ("mine") was not generated this way.
This causes the script to fail as it's looking only for 1.log. Renaming it to 1.log fixes the error.
Hey!
I'm stuck with cpu_instrs 11. I think I've found a bug in the log files.
After executing 0x34 INC (HL) the value is not incremented. (Ignore flags)
============== ERROR ==============
Mismatch in CPU state at line 2602508:
MINE: A:00 F:-H-- B:DE C:F4 D:DE E:F5 H:DE L:F6 SP:DFF1 PC:DEF9 PCMEM:00,00,C3,CD
YOURS: A:00 F:---- B:DE C:F4 D:DE E:F5 H:DE L:F7 SP:DFF1 PC:DEF9 PCMEM:00,00,C3,CD
The CPU state before this (at line 2602507) was:
A:00 F:---- B:DE C:F4 D:DE E:F5 H:DE L:F6 SP:DFF1 PC:DEF8 PCMEM:34,00,00,C3
The last operation executed (in between lines 2602507 and 2602508) was:
0x34 INC (HL)
Perhaps the problem is with this opcode, or with your interrupt handling?
In cpu_instrs 2 I got a mismatch at line 151347:
MINE: A:04 F:C--- B:01 C:00 D:C7 E:BA H:90 L:00 SP:9000 PC:0051 PCMEM:2E,0F,18,F3
But when I look into the binary of the ROM, I got:
0x0051 C9
0x0052 00
0x0053 00
0x0054 00
So I think there is an error because your values must be "PCMEM:C9,00,00,00".
I downloaded the .gb file from https://github.com/retrio/gb-test-roms/blob/master/cpu_instrs/individual/08-misc%20instrs.gb and on line 208109 it says there is a POP AF instruction but I'm seeing that there is instead a NOP at that position instead.
Is the test file for blargg cpu_instr 8 out of date?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.