Weird Behavior From One of Blargg's CPU Tests

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.
sir_archibald
Posts: 5
Joined: Sat Sep 06, 2025 10:45 am

Weird Behavior From One of Blargg's CPU Tests

Post by sir_archibald »

Hello. I've been busy writing an NES emulator. I think I'm finally at a point where I've completed the 6502, so I'm in the process of testing it using a test suite provided by the wiki -- instr_test-v5.

Rather than running all fifteen tests at once (I'm excluding 01-basics.nes since that doesn't appear to be a part of the test suite), I'm running each test separately starting with 02-implied.nes.

When I initially loaded in this ROM, all of my tested instructions failed to produce the correct checksum and the test failed as a consequence. I tried doing side-by-side comparisons of my CPU's state with my debugging output and the debugger provided by FCEUX, but everything appeared to be correct.

It wasn't until I made a small modification to a function that handles the JMP instruction that 02-implied.nes passed. That modification was pushing the program counter to the stack. (For context, this function originally handled the JSR instruction before I wrote a separate function for it.)

That's obviously not what JMP is supposed to do, but without that behavior, the test won't pass. The same is also true for 12-jmp_jsr.nes.

Does anyone have any idea what could be going on here?
Fiskbit
Site Admin
Posts: 1382
Joined: Sat Nov 18, 2017 9:15 pm

Re: Weird Behavior From One of Blargg's CPU Tests

Post by Fiskbit »

JMP just changes PC, so if you have to push the return address to the stack, I'd guess you're still handling JSR with the JMP code even though you split JSR off into a separate function.

It sounds like you're very early in testing your CPU implementation, so you might benefit from some different approaches. A lot of people start by running nestest, which can be run either with a menu or in a headless mode that just runs tests. The headless mode normally requires ignoring the reset vector, but I've created a modified version of the test (attached below) that runs headless automatically (and stops at the end with the $02 STP/KIL/HLT illegal instruction rather than crashing like the test normally does...). People verify that the test passed by logging CPU state every instruction and comparing against a known-good log. Any differences indicate a problem. Note that the ability to log execution will probably be useful for you in the future, too, as you try to debug problems in games and compare against the behavior in accurate emulators such as Mesen. I also wouldn't recommend FCEUX as a reference because it is simply not accurate by today's standards.

Another approach is to use 6502 JSON unit tests. This requires instrumenting your emulator to run these tests. This seems to be very popular in other communities (particularly EmuDev) and sounds like a pretty good way to test today. I still have some skepticism around these test suites because they are randomly-generated tests (so they're not guaranteed to hit all of the interesting cases) and aren't verified directly against real hardware, but the 6502 suite has gotten a lot use and should be pretty comprehensive and correct at this point.
You do not have the required permissions to view the files attached to this post.
sir_archibald
Posts: 5
Joined: Sat Sep 06, 2025 10:45 am

Re: Weird Behavior From One of Blargg's CPU Tests

Post by sir_archibald »

Fiskbit wrote: Sun Sep 21, 2025 12:47 pm JMP just changes PC, so if you have to push the return address to the stack, I'd guess you're still handling JSR with the JMP code even though you split JSR off into a separate function.

It sounds like you're very early in testing your CPU implementation, so you might benefit from some different approaches. A lot of people start by running nestest, which can be run either with a menu or in a headless mode that just runs tests. The headless mode normally requires ignoring the reset vector, but I've created a modified version of the test (attached below) that runs headless automatically (and stops at the end with the $02 STP/KIL/HLT illegal instruction rather than crashing like the test normally does...). People verify that the test passed by logging CPU state every instruction and comparing against a known-good log. Any differences indicate a problem. Note that the ability to log execution will probably be useful for you in the future, too, as you try to debug problems in games and compare against the behavior in accurate emulators such as Mesen. I also wouldn't recommend FCEUX as a reference because it is simply not accurate by today's standards.

Another approach is to use 6502 JSON unit tests. This requires instrumenting your emulator to run these tests. This seems to be very popular in other communities (particularly EmuDev) and sounds like a pretty good way to test today. I still have some skepticism around these test suites because they are randomly-generated tests (so they're not guaranteed to hit all of the interesting cases) and aren't verified directly against real hardware, but the 6502 suite has gotten a lot use and should be pretty comprehensive and correct at this point.
Thanks. For nestest.nes is there a less cumbersome way than directly comparing output to a log, or is that just something I have to deal with?
Fiskbit
Site Admin
Posts: 1382
Joined: Sat Nov 18, 2017 9:15 pm

Re: Weird Behavior From One of Blargg's CPU Tests

Post by Fiskbit »

If you output in the exact same format as the log you're comparing against, then you can just diff the logs and look at the first difference.