Eccentric pedantic "monochrome" glitch

Discuss hardware-related topics, such as development cartridges, CopyNES, PowerPak, EPROMs, or whatever.

Moderator: Moderators

lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Eccentric pedantic "monochrome" glitch

Post by lidnariq »

In this post, I observed that it should be possible to get the wrong value of pal_mono stuck inside the palette hardware on certain CPU-PPU phases. And... lo and behold, I have a test ROM that shows it, by writing #0 to $2101 repeatedly:
exposure: 1/60th second
exposure: 1/60th second
Now, what's specifically interesting about this is: no matter how many times I reset or power cycle the NES, I only ever see black, or this specific shade of blue. So we might finally have a robust way of detecting at least one CPU-PPU subpixel phase. (So please other people help verify!)

This specific timing is: M2 goes high before the data bus has been driven, so pal_mono temporarily gets the value from open bus. Because the output of pal_mono isn't gated, the palette lookup initially zeroes the lower four bits of the result from the palette RAM, and then an edge between pixels captures this wrong value for that one pixel.
Attachments
catcmono.7z
nes, bin, asm inside
(763 Bytes) Downloaded 174 times
Fiskbit
Posts: 890
Joined: Sat Nov 18, 2017 9:15 pm

Re: Eccentric pedantic "monochrome" glitch

Post by Fiskbit »

Wonderful, thanks for this test!

You say shade of blue, but these should be white dots, right?

Kitrinx identified that greyscale, emphasis 2, slave mode, and NMI enable are all implemented in this same way. I think this might explain the issue with Hi-Def NES and NESRGB mentioned here and seen here where writes to $2000 can corrupt the EXT data output for a dot. If $20 is being seen as the write value for a dot, that would kick the PPU out of slave mode and cause this. If this is indeed fixed in the rev H PPU as mentioned on that page, perhaps the other bits are, too?

Would this also mean that writes to $2000 when NMI would trigger could prevent NMI by briefly disabling it?
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Eccentric pedantic "monochrome" glitch

Post by tepples »

NES pixels are two-thirds of a color subcarrier period wide. A white dot that small will carry a small amount of color fringe depending on its relationship to the color burst phase.
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Re: Eccentric pedantic "monochrome" glitch

Post by lidnariq »

Fiskbit wrote: Fri Sep 18, 2020 7:05 am Kitrinx identified that greyscale, emphasis 2, slave mode, and NMI enable are all implemented in this same way. I think this might explain the issue with Hi-Def NES and NESRGB mentioned here and seen here where writes to $2000 can corrupt the EXT data output for a dot. If $20 is being seen as the write value for a dot, that would kick the PPU out of slave mode and cause this.
Naively, if I were writing an implementation of NESRGB, I'd replace the data bus as soon as I knew what address it was. I wouldn't wait for the actual contents of the data bus before deciding to replace it. So ... I don't think that's what's going on here?

I did try to write the same test to get the "sparkle" I mentioned on emph2 to show up, but I didn't see it. But I might not have actually gotten my NES to boot my ROM :p
You say shade of blue, but these should be white dots, right?
As tepples says.

Because the CPU clock and the colorburst clock are forever linked after boot, the color should be fixed. But rainwarrior separately identified that at least on his NES, he's seen all six different colorburst-to-pixel clock phases. I have no idea how that works such that you'd get a 50ns difference in release from reset for different subsystems inside the PPU, but I can't argue with his results.

Now that I've had a chance to sleep, I think that this test should capture two different subpixel alignments, because the data bus is driven roughly 100ns after M2 rises.
If this is indeed fixed in the rev H PPU as mentioned on that page, perhaps the other bits are, too?
Don't see why not. Slightly more clever metal layout should have left enough space for these bits to be implemented correctly.

They even have the synchronized copies of these signals already generated. The subsequent logic just connects to the output of the latch instead of these synchronized copies.

slave_mode → 6245
pal_mono → 6243
emph2 → 6239

That said, enable_nmi is a little weird: there's no space for the gate to synchronize it. There's a bend in /write_2000_reg right over top that means there's no space for the polysilicon to make the transmission gate.
Would this also mean that writes to $2000 when NMI would trigger could prevent NMI by briefly disabling it?
Delay NMI or cause reentry, not prevent it. Only reads from $2002, or scanline 20, clear the S-R latch.
Fiskbit
Posts: 890
Joined: Sat Nov 18, 2017 9:15 pm

Re: Eccentric pedantic "monochrome" glitch

Post by Fiskbit »

I believe I've confirmed the emph2 case with the attached test ROM on a rev G frontloader. I manually hacked this one together in a hex editor from your binary, so no source for this. It writes #$81 to $2101 rapidly. On affected alignments, this will trigger white dots.
Attachments
emph2_sparkle_test.nes
(32.02 KiB) Downloaded 158 times
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Re: Eccentric pedantic "monochrome" glitch

Post by lidnariq »

... That's almost exactly the same test that I wrote but I never saw the white dots from emph2 being temporarily disabled.

...ohhhh...
if my first "catcmono" test always produces blue-tinted dots, then the sparkle will always happen at the wrong moment relative to colorburst phase... somehow I have to get a different CPU-to-colorburst alignment to get that to show up.
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Re: Eccentric pedantic "monochrome" glitch

Post by lidnariq »

I've written a variation on the test that tries to tickle both the "catch the monochrome bit for one pixel" and the "blue emphasis is entirely asynchronous" at the same time.

I've tested it with PPU /RESET tied to CPU /RESET, and with PPU /RESET floating.

The code uses the CPU to draw this parallelogram:
pgram.png
pgram.png (159 Bytes) Viewed 8027 times
Legend:
Red: places where we try to glitch pal_mono on for one pixel
Yellow-green: places where we turn pal_mono on
Seagreen: places where we try to glitch pal_mono off for one pixel
Purple: places where we turn pal_mono off
At all four of the above, we also try to temporarily disable blue emphasis. Previous estimates for 2A03 bus timing have this at around 100ns, or about half a pixel, or roughly the same width as a SNES 512px pixel.
Blue: places where pal_mono remains on

I've gotten a bunch of different results depending on exact phases.

Results with PPU /RESET floating:
pal_mono glitch dots can be any color - here it's yellow but I have seen red, green, blue-or-cyan, and magenta also:
IMG_3061_crop.JPG
emph2 sparkle is often visible:
IMG_3057_crop.JPG
How often should emph2 sparkle be visible? Well, the relevant node inside the 2C02 (195, "chroma_ring3") is high for 3MCy and low for 3MCy. The open bus value should be driven for roughly 2MCy, but the relative phase is unknown. So we should see multiple different levels of severity of the emph2 sparkle depending on exact phase between the two, including factors like "how many ns does it take for the signal to get out of the 2A03 and into the 2C02". But I'd expect sparkle visible in 2/3 or 5/6 of the possible phase differences.

With PPU /RESET tied to CPU /RESET:
pal_mono is almost always blue (or cyan?)
emph2 sparkle is never visible:
darker because I added an ND filter after noticing the other pictures were overexposed
darker because I added an ND filter after noticing the other pictures were overexposed
Bewilderingly: the 2A03's internal clock divider is not reset by asserting the CPU's /RESET, but the 2C02's colorburst sequencer is. So how on earth was I not getting differing chroma-to-CPU phases when the PPU should have had its phase changed every time I pressed the reset button?
Attachments
blueemp2.7z
source, binary, nes file included
(972 Bytes) Downloaded 161 times
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Re: Eccentric pedantic "monochrome" glitch

Post by lidnariq »

lidnariq wrote: Fri Sep 18, 2020 11:43 am Now that I've had a chance to sleep, I think that this test should capture two different subpixel alignments, because the data bus is driven roughly 100ns after M2 rises.
I've since taken my oscilloscope and checked the original test, and I think it's only ever capturing one subpixel alignment.

No matter how many times I power cycle my NES, I only ever see the dot due to a glitched value of pal_mono at this position (from roughly the 90ns before R/W rises to roughly 50ns after).

From my previous measurement, this should be roughly 330ns, or 1.75 pixels, after the /PPUCE for the write is asserted. Looking in visual2c02 I see a direct explanation for 1.5 of them, so ... that last 1/4 pixel must be the requisite phase alignment.
Attachments
mIMG_3078.png
mIMG_3078.png (4.48 KiB) Viewed 7973 times
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Re: Eccentric pedantic "monochrome" glitch

Post by lidnariq »

I spent a few minutes looking at siliconpr0n's decapped 2C04, and found that all of these asynchronous behaviors are there, too:

emph2 (blue) -
https://siliconpr0n.org/map/nintendo/rp ... y=2707&z=6
pal_mono
https://siliconpr0n.org/map/nintendo/rp ... y=2655&z=6

slave_mode exists at all
https://siliconpr0n.org/map/nintendo/rp ... y=2669&z=6
but is cut off from any further hardware:
https://siliconpr0n.org/map/nintendo/rp ... y=2668&z=6

Palette reads don't exist, so the logic implementing pal_mono is a little simpler:
https://siliconpr0n.org/map/nintendo/rp ... y=3049&z=6
compare visual2c02 node 10679

The 2A03letterless has a longer M2 duty cycle, so the duration during which a bad value of emph2 or pal_mono can leak out should be longer, and it should be easier to tickle these various glitches on Vs. Systems or older Famicoms.

(Also: does anyone have a 2A03letterless and can test what the actual duty cycle of M2 is? It's not 3/4.)



I've measured the actual amount of time that /PPUCE goes low before the NES drives the data bus—80ns, or about 1.7 master clock cycles.
top: /PPUCE, bottom: CPU D7
top: /PPUCE, bottom: CPU D7
mIMG_3248.png (8.85 KiB) Viewed 7817 times
For reasons I'm not clear (does emphasis change the supply voltage to the video DAC?), it takes a comparatively huge amount of time for emph2 to percolate through the 2C02, somewhere around 100-120ns:
mIMG_3247.png
This latter test was done by overriding the PPU's master clock with a 7MHz source so that we can see the effect of emphasis without having to manually step through all the different video phases.

I've also got a set of photos of all six CPU-to-colorburst alignments, but it'll take me a little while to stitch them into something suitable for presentation.
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Re: Eccentric pedantic "monochrome" glitch

Post by lidnariq »

And with this post, I think I've finished exploring the ideas.

To coax this effect out, I used blue emphasis on top of solid color #$08. Together, this works out to a color that should just be black in the US (7 IRE), and any moment that emphasis is turned off should be very conspicuous.

Here's the photos of the six (2A03-vs-2C02) alignments between CPU phase and colorburst phase. Four of the six phases are really unambiguously different; the last two (top left and top center) are pretty hard to tell apart. The darker phases are underexposed (and fixed after the fact) because I put the oscilloscope in the same exposure as the TV.

Unfortunately, colorburst phase is almost entirely decoupled from pixel clock phase, so this is basically useless from a diagnostic point of view.

All of the emph2 tests require the NES's normal open bus behavior; it won't work with a PowerPak and may not work on any NoaCs. I did test an earlier version of this with the UA6528 (date code 9114) that zoinknoise sent me, and got similar (but slightly darker) results. (The earlier "catcmono" test should work on a PowerPak: there it should glitch D0 high before the CPU drives the pin low, the same as we fake by writing to $2101)

In the attached picture, the six TV photos correspond to the oscilloscope photo that's immediately above or below them. The TV photos are relatively tight crops of only 50ish scanlines. The oscilloscope traces are always CPU D7 (on top) and PPU pin 21 (on bottom)
Attachments
blueemp3.7z
(837 Bytes) Downloaded 147 times
cpu-vs-colorburst-phase-appearances.jpg
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 568
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: Eccentric pedantic "monochrome" glitch

Post by Jarhmander »

lidnariq wrote: Wed Sep 30, 2020 3:59 pm(Also: does anyone have a 2A03letterless and can test what the actual duty cycle of M2 is? It's not 3/4.)
Long ago, I took that measure and yes, it's ¾. Not the best measurements in the world, but it can clearly be seen.
((λ (x) (x x)) (λ (x) (x x)))
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Re: Eccentric pedantic "monochrome" glitch

Post by lidnariq »

Looks to me like it's actually 17/24.

The reason I say it can't be simply 3/4 is because the decapped letterless 2A03 shows the same "two twisted-ring counters ORed together" that the the decapped 2A03G (look around node 13923) does, so the duty cycle has to be (some odd number)÷24

Nonetheless, thanks for reminding me of that old post! It predated my making the page where I've tried to compile all of this.
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 568
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: Eccentric pedantic "monochrome" glitch

Post by Jarhmander »

Huh? How it can be 17/24? I count 6 falling edges when M2 falls. And M2 changes *only* on falling edges of the master clock... For the duty cycle to be 17/24, M2 would have to change state on a raising and falling edges, wouldn't it?

And sadly, I can't decipher die photographs (yet?), so I can't see what you are mentioning.

But, glad to help nonetheless!
((λ (x) (x x)) (λ (x) (x x)))
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Re: Eccentric pedantic "monochrome" glitch

Post by lidnariq »

Jarhmander wrote: Thu Oct 01, 2020 6:32 pm Huh? How it can be 17/24? I count 6 falling edges when M2 falls. And M2 changes *only* on falling edges of the master clock... For the duty cycle to be 17/24, M2 would have to change state on a raising and falling edges, wouldn't it?
... No, you're right. Drat.
And sadly, I can't decipher die photographs (yet?), so I can't see what you are mentioning.
I thought I'd stack up the 2A03 and 2A03G input dividers for a visual comparison, and ... now I see that the 2A03's input divider is significantly smaller.
2a03-vs-2a03g-input-divider-comparison.jpg
It still has the same OR gate that combines φ0 with some other phase, but that'd be necessary even for 3/4 duty.
User avatar
Quietust
Posts: 1918
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Eccentric pedantic "monochrome" glitch

Post by Quietust »

I just spent a bit of time tracing layer images for the clock divider - when I get a chance tomorrow, I'll vectorize them and throw them into ChipSim (like I did with that other "mystery logic" on the revisionless 2A03) so we can clearly see what's going on.

Edit: it's done, and a quick round of simulating yielded the following timings:

Code: Select all

1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 - Master CLK in
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 - CPU CLK In
0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 - M2 Output Modifier
This confirms that the duty cycle is, indeed, 17/24.
Jarhmander wrote: Thu Oct 01, 2020 6:32 pm Huh? How it can be 17/24? I count 6 falling edges when M2 falls. And M2 changes *only* on falling edges of the master clock... For the duty cycle to be 17/24, M2 would have to change state on a raising and falling edges, wouldn't it?
And that's exactly what it does, and the same is true of the RP2A03G (which has a 15/24 duty cycle) - the 6502's clock input changes on rising input clock edges, but the "early-M2" logic triggers on falling input clock edges.
lidnariq wrote: Thu Oct 01, 2020 7:34 pm I thought I'd stack up the 2A03 and 2A03G input dividers for a visual comparison, and ... now I see that the 2A03's input divider is significantly smaller.
The 2A03G's clock divider is larger because it contains unused circuitry from the 2A07's /16 divider.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
Post Reply