Tonight, I created a test ROM that allows for selection with the joypad of different PPU_ADDRESS values for the split, and which utilizes blargg's PPU/NMI synchronization code to target specific dots. I'll post it here when I nail down the timings by testing on real hardware; unfortunately, my Everdrive is still in the mail, so I'm currently relying on others for my hardware testing, which is a significant bottleneck.
Code: Select all
$0100 (8) never glitched $0120 (9) -> $0100 $0140 (A) -> $0100 $0160 (B) -> $0100 $0180 (C) -> $0100 $01A0 (D) -> $0100 $01C0 (E) -> $0100 $01E0 (F) -> $0100 $0200 (G) -> $0000 $0220 (H) -> $0000 $0240 (I) -> $0000 $0260 (J) -> $0000 $0280 (K) -> $0000 $02A0 (L) -> $0000 $02C0 (M) -> $0000 $02E0 (N) -> $0000 $0300 (O) -> $0100 $0320 (P) -> $0100 $0340 (Q) -> $0100 $0360 (R) -> $0100 $0380 (S) -> $0100 $03A0 (T) -> $0100
I took the liberty to make the text static and moved the triangles somewhere closer to the middle of the screen also.
Could probably do that, but I don't see what that would do? But then again, I'm rusty at NES stuff haha.modify the test rom to occur in the middle of the scanline for example?
Did you have something in mind? I tried placing a square on the second nametable so you can see it moving up/down 1 pixel and shake.It would also help to have more geometry so $2006 can be set to different values and see the effects.
According to my emulator read out, the glitches that would result from the ppu scroll tests would be happening because of the v -> t operation at cycle 257. The previous tests were testing glitches at the increments at 256. In fact, split_scroll_delay amazingly misses 256, hitting 255, 257, and 258 instead.
So, it looks like something is probably happening there too.
Actually, I tried varying power up timing and it turns out that this effects what cycles the glitches hit at. So while it's not impossible that some glitches might be happening on 257, it seems less likely now (since the original tests hit 257 sometimes as well and nothing happened on them.) I think we just need a more comprehensive test for this.
Also curiously, split_scroll_normal is hitting what would be h increments at various points in the scanline, but if it is expereincing any conflicts, we aren't testing them so far.
I'll try to go over this a bit more over the weekend when i have more time.
@fred: yeah as libnariq says, we likely need some cases where $2006 is latching things that would be effecting h at midscaline points. the present tests do not accomplish this (since they are writing things with 0 for those.) It would help if the shapes on a scanline were noticably different, so we can see any glitchiness very clearly.
EDIT: also thanks again Eugene.S for the frame by frame videos.
All of my tests was recorded on Famicom AV, it have:I didn't notice any times where one value glitched in a different way. I had to refer to the Twitch clip for G because I didn't see it glitch in this video.
RP2A03H - "rev H" CPU
RP2C02H-0 - "rev H" PPU
This ROM uses blargg's PPU/NMI synchronization code to target pairs of neighboring dots, and allows nearly all of the split parameters to be customized with the joypad so it can occur anywhere onscreen and split to any target location. Up/down adjust the split by 113 CPU cycles and left/right adjust by 1. Select changes the nametable for the pre-split region. A/B adjust the value written to PPU_ADDRESS by $20, and start increments it. All of the code paths should be appropriately timed so they won't affect the location of the split. If timings are the same on console, this should start up around scanline 63, dots 252 and 253.
- (7.25 KiB) Downloaded 445 times
hopefully the v2 test will give final confirmation on this. (On my emulator though it powers up to scanline 64 cycle 255/256)
Then we just need to see if any similar effects happen for h.
Alyosha_TAS wrote:I went over the frame by frame for scroll delay v1 test, and yeah it looks like the glitch is properly characterized by doing the v increment but then '&' the result with the latched value. My emulator gets exact results by doing this. This also still gives correct results for the original 2 tests.
I think that the bus conflicts should only be in the "V" bits (0x7BE0) on dot 256, and should only be in the "H" bits (0x041F) in the middle of the scanline. The other bits look like they should be correctly copied from T to V.Alyosha_TAS wrote:Also curiously, split_scroll_normal is hitting what would be h increments at various points in the scanline, but if it is expereincing any conflicts, we aren't testing them so far.
Yeah that definitely would make the most sense. Would you expect $2005 to behave similarly? That seems like the next obvious choice to test.lidnariq wrote:I think that the bus conflicts should only be in the "V" bits (0x7BE0) on dot 256, and should only be in the "H" bits (0x041F) in the middle of the scanline. The other bits look like they should be correctly copied from T to V.
Let me think this through:Alyosha_TAS wrote:Yeah that definitely would make the most sense. Would you expect $2005 to behave similarly?
The conflict comes specifically from the copy_vramaddr_Qscroll signal being true at the same time as the inc_vramaddr_Qscroll signal.
inc_vramaddr_hscroll is true on dots 328, 336, and 0,8,16,...248, 256
copy_vramaddr_hscroll is true on dot 257 or on the second write to $2006
inc_vramaddr_vscroll is true on dot 256.
copy_vramaddr_vscroll is true during part of the pre-render scanline, or on the second write to $2006
So, I don't see an obvious way to tickle this on anything but the second write to $2006.
Now, separately ... in the NES, M2 is true for 1 7/8 pixels (7.5 XCy), and the exact amount of overlap of the M2 cycle during dot 256 should have analog effects. The hazard should only happen during pclk1=the second half of each pixel (2 XCy), so ... I'd be idly curious how the four different 2A03-vs-2C02 phases work out. No idea how to set up that test, though.
edit: per this thread, note that ulfalizer's graph needs the CPU cycles to be shifted one by half crystal cycle, there should be three race-y cases:
M2 falls 1 XCy after dot 255 and pclk1 (overlap of 1 XCy ; alignment A)
M2 rises 1.5 XCy after dot 255 and pclk1 (overlap of 0.5 XCy ; alignment B)
M2 rises 0.5 XCy after dot 255 and pclk1 (overlap of 1.5 XCy ; also alignment A)
The remaining two alignments should always have dot 255 and pclk1 happen without an edge of M2 during
edit2: The more I look into this in Visual2C02, the more I'm confused by the "write to $2000 on dot 255" glitch.
* Writes to PPU registers always happen during multiple pixels
* There is no alignment of CPU and PPU such that pclk1 is only true once while M2 is true
* Krzysiobal has found that the data bus is not actually valid when M2 rises
* Blargg found that only two of the four CPU-PPU phases cause it
* CPU writes invalid data (upper byte of address, per capacitance) to PPU register $2000 on dot 257, and this bad value shoots through straight from _db0 to _vramaddr_t10 to _vramaddr_v10 because of timing. Which exact two phases cause this result is unclear ...
* On dot 258, the write is still happening, the data is now valid, and the PPU loads the correct value into T, meaning that it will be copied correctly to V on subsequent scanlines.
If this interpretation is correct, then writing to the PPU register mirror at $2100 should cause the glitchy single scanline to instead source from the right nametable.