Blargg's new instruction tests

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Blargg's new instruction tests
by on (#62504)
I seem to be going backwards as Blargg goes forwards...nice!

With the new instruction test ROMs that were released recently I strangely get failures *only* on the first instruction tested on each of the singles ROMs. From the results it would seem my LDA instruction is CRAP for all variants, which I'm fairly certain is not the case. Also, my BCC, ROL A, JSR, RTS, RTI appear to be crap. But every other instruction tested passes...

I'm fairly confident my P register is being set correctly because:

1. If I remove the "stuck" bit *all* instructions fail, not just the first one.
2. If I modify the B flag behavior *all* instructions fail.
3. BCC fails which doesn't modify P at all; other relative variants do not fail.

Here, again, I completely pass an earlier version of Blargg's instruction tests; I also completely pass nestress.nes' CPU section and nestest.nes for both normal and undocumented.

There are a few undocumented instructions which I don't pass:

ARR #n
ATX #n
AXS #n
SYA abs,X
SXA abs,Y

I don't think these could impact the failure.

I'm really scratching my head over what sort of condition could cause me to get failure only on the first opcode tested of each singles test ROM! If I change something globally affecting like the behavior of the P register I get slews of other failures.

It's not like it could be a register-value-at-reset problem either because there's lots of execution time prior to the first test where the registers are modified from their reset condition. Also, each test appears to set up P, A, X, Y, SP, and the instruction's operand prior to the test.

Certainly I think I can rule out A, X, and Y problems...as LDA/X/Y will stomp on whatever might have been there that might have been wrong (and should also correct wrong P), or TAX, TAY will do the same for X and Y.

That really only leaves the possibility that it is something on the stack that is wrong for the first instruction tested but gets overwritten with the right value?

I also just tried out of pure stupid unreasoning reversing the PUSH/POP operation (ie. PUSH = decrement SP *then* put byte at SP instead of put byte at SP *then* decrement SP) but that wreaked all sorts of havoc including a KIL instruction execution. That slightly baffles me...seems it should have just offset the stack by one byte not caused execution problems (the PUSH/POP should have remained consistent but just use one byte lower on the actual stack). The test ROMs must be doing some SP tricks...

Scratching head in Minneapolis...

by on (#62549)
We finally solved the problem; the emulated APU was incorrectly generating an IRQ/not clearing the flag even though $4017 had been written with $40. The next version of the tests will write $C0, and write $00 to $4010, and read from $4015, just to be sure it's generating no IRQs during the tests. The reason these didn't occur before is that the new tests check several bytes around the current stack pointer, for all instructions, in case one erroneously writes to the stack. So this erroneous IRQ was doing that, and causing failure of the first instruction.

Reminds me of a similar failure in a previous version, where someone's NES emulator implemented the decimal mode of the 6502. Since then the CPU tests have cleared the decimal flag whenever it might have been set, so that this bug will only cause failure of ADC/SBC, rather than every instruction :)
Re: Blargg's new instruction tests
by on (#62551)
NESICIDE wrote:
I seem to be going backwards as Blargg goes forwards...nice!


Well thanks very very much to Blargg for his help today. It turns out I was not releasing APU frame IRQs on a write of $40 to $4017. This was messing up my stack and failing the CRC comparison.