Added a test for Length counter timing, and the 4-step / 5-step frame counter behavior.
Updated the unofficial instruction tests to also test for instruction length.
Updated SHA and SHS behavior 1 to print magic numbers.
Cleaned up the clockslides.
Tried to prevent infinite loops due to incorrect DMC DMA timing.
Error codes are erased by PASS.
Sprite evaluation tests now clear the garbage tiles in the overscan area.
DMC DMA + $4016 now also passes with the famicom behavior.
In the specific instance of failure in which you read from controller port 2 too many times with your DMA, you will run an RTS instruction, and error code 4.
After a series of checks to make sure you can even try running this test, make the absolute most insane thing ever happen: An OAM DMA while the Program Counter is at address $4000. This requires a lot of moving parts to go exactly right. PPU open bus, the PPU read buffer, Precise DMC DMA timing, the DMC DMA can update the data bus, and proper open bus emulation, leading to a test that confirms the APU registers can be read by the OAM DMA if the 6502 Address bus is pointing to Page $40.
Added a test for various Address $2004 behavior:
Writes to $2004 update OAM, and increment the OAM address by 1
Reads from $2004 give you a value in OAM, but do not increment the OAM address
Reads from $2004 during PPU cycle 1 to 64 of a visible scanline (with rendering enabled) will always read $FF
Reads from $2004 during PPU cycle 1 to 64 of a visible scanline (with rendering disabled) does a regular read of $2004
Writing to $2004 on a visible scanline increments the OAM address by 4
Writing to $2004 on a visible scanline doesn't write to OAM
By timing the write to address $2003 between dots 241 and 261, by prepping the databus before the write cycle to $2003, and by keeping the test inside OAM row 0, the corruption should no longer occur.
Fixed typos in the comments of the Misaligned OAM Behavior test
I also spent all day trying to make this test more consistent on console by using $2004 to move the PPUOAMAddress instead of $2003, but then I had to deal with OAM Corruption which was gross and I gave up.
Or so I assume.
I stall for 2 more CPU cycles now, and I also changed the writes to $2003 to use mirrors corresponding with the OAM value I wish to write. I.E, instead of using OAM address $80 and $81, I use $20 and $21, writing to $2003 and $2103.
Added tests for if sprite zero is vertically off screen, masked away by the leftmost 8 pixels, a single dot sprite landing in an open 1x1 pixel window (missing the hit), and a test for "precise" Sprite Zero Hit timing. (within a 2 CPU cycle window)
I accidentally broke the SHA and SHS instructions when trying to set X to FF in order to prevent behavior differences from breaking that test. That is now fixed.