When SPRDATA reads are working correctly, they give you the contents of OAM at whatever SPRADDR is set to. When they're not, some/many/most addresses give you OAM at a different address. I haven't tested writing thoroughly, but I'm pretty sure that SPRDATA writes and SPRDMA work reliably all the time, explaining why this crazy behavior wouldn't have been a problem, as SPRDATA reads are rarely/never used.
I wrote a test program to determine what OAM byte is actually read for each address. It tries them from $00-$FF, with 16 per row. So when working correctly, we'd expect it to begin
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
...
But let's say it's all correct as above, except that reading from address $04 really reads from $48:
00 01 02 03 48 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
...
Since it's difficult to easily see the incorrect entry, the test program prints -- for correct entries, so for the second example above, it prints
-- -- -- -- 48 -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
...
So, here are the three insane mappings I get, randomly chosen at reset, but unchanging until I reset/power again:
Code: Select all
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
18 19 1A 1B 1C 1D 1E 1F -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
-- -- -- -- -- -- -- -- 20 21 22 23 24 25 26 27
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
20 21 22 23 24 25 26 27 20 21 22 23 24 25 26 27
-- 21 22 23 24 25 26 27 -- 21 22 23 24 25 26 27
-- 21 22 23 24 25 26 27 -- 21 22 23 24 25 26 27
-- -- -- -- -- -- -- -- 20 21 22 23 24 25 26 27
-- 21 22 23 24 25 26 27 -- 21 22 23 24 25 26 27
-- 21 22 23 24 25 26 27 -- 29 2A 23 2C 25 26 27
-- 21 22 23 24 25 26 27 -- 39 0A 23 2C 25 26 27
-- -- -- -- -- -- -- -- -- 61 62 63 64 65 66 67
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- --
-- -- 82 -- -- -- 26 A7 -- -- -- -- -- 8D 0E AF
-- -- -- -- -- 25 26 27 -- A1 A2 A3 A4 25 26 27
-- A1 A2 A3 A4 25 26 27 -- -- -- -- -- -- AE AF
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
I'll probably be working more on this tomorrow, hopefully making the test program standalone so others can see how their NES behaves (I imagine each will be slightly different). Any thoughts on it?