PPU rendering?

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

User avatar
Zepper
Formerly Fx3
Posts: 3214
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

PPU rendering?

Post by Zepper » Sun Aug 30, 2020 7:49 pm

I was checking PPU writes to $2001 using the game Super Mario Bros 3. Looking at bits $18 (background/sprites enabled), I see that SMB3 never writes to $2001 while the scanline is in the pre-render line + visible field (I number lines as 20-260).
I see emulators putting a check in $2001 like... rendering is enabled if $2001 bits $18 are non-zero, and the scanline is in the visible field.

What am I missing here? Did i misunderstand the meaning of is-rendering state?

Drag
Posts: 1322
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: PPU rendering?

Post by Drag » Sun Aug 30, 2020 8:12 pm

I think "rendering" refers to the PPU making its usual memory fetches in order to draw tiles and sprites to the screen. If both sprites and BG are disabled, the PPU will stop making memory fetches (and thus, will not be "rendering" anymore), but it still generates video (a blank* screen), the sync pulses, and keeps track of vblank.

If you write to $2001 to turn either sprites, BG, or both back on outside of vblank, the PPU will start rendering once again (as in, it will start making its memory fetches again), but the picture will start partway down the screen. That might be why you're seeing emulators check for this on writes to $2001.


------
* by "blank" screen, I actually mean a screen filled with either the current BG color, or if $2006 is pointing to an address in $3F00-3FFF, the PPU will output the color in that particular palette entry.

User avatar
Zepper
Formerly Fx3
Posts: 3214
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: PPU rendering?

Post by Zepper » Mon Aug 31, 2020 2:18 pm

Yes, of course. I meant a boolean way looking at writes to $2001. I was away from this project, but I'm back. Interesting about SMB3 disabling the screen various times, then re-enabling it, but never during the visible field period.

lidnariq
Posts: 9655
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: PPU rendering?

Post by lidnariq » Mon Aug 31, 2020 2:31 pm

Internal to the PPU, there's a piece of metal that is literally "are we in the active field and rendering is enabled" (Visual2C02 calls it "in_visible_frame_and_rendering"). I assume there are subtle glitches that happen if you don't implement the logic the same way.

User avatar
Zepper
Formerly Fx3
Posts: 3214
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: PPU rendering?

Post by Zepper » Mon Aug 31, 2020 2:37 pm

lidnariq wrote:
Mon Aug 31, 2020 2:31 pm
Internal to the PPU, there's a piece of metal that is literally "are we in the active field and rendering is enabled" (Visual2C02 calls it "in_visible_frame_and_rendering"). I assume there are subtle glitches that happen if you don't implement the logic the same way.
So, let me rephrase my question.
Are writes to $2001 allowed during rendering?
Because SMB3 would always let in_visible_frame_and_rendering as FALSE.
Last edited by Zepper on Mon Aug 31, 2020 2:38 pm, edited 1 time in total.

User avatar
Bregalad
Posts: 7951
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Re: PPU rendering?

Post by Bregalad » Mon Aug 31, 2020 2:37 pm

Yes.
Useless, lumbering half-wits don't scare us.

lidnariq
Posts: 9655
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: PPU rendering?

Post by lidnariq » Mon Aug 31, 2020 2:45 pm

Zepper wrote:
Mon Aug 31, 2020 2:37 pm
So, let me rephrase my question.
Are writes to $2001 allowed during rendering?
Yes?
Because SMB3 would always let in_visible_frame_and_rendering as FALSE.
No? Almost everything in the NES happens continuously. This signal isn't latched on a write to $2001: it's generated much later on.

Drag
Posts: 1322
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: PPU rendering?

Post by Drag » Mon Aug 31, 2020 3:48 pm

Writing to $2001 is allowed mid-frame, otherwise it'd be impossible to perform a mid-frame palette update (StarTropics). There are probably better examples, but Krusty's Fun House uses $2001 to add a margin around the status bar.

User avatar
tokumaru
Posts: 11858
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: PPU rendering?

Post by tokumaru » Mon Aug 31, 2020 3:55 pm

What exactly is it that SMB3 is doing that you find weird? In your first post you just said that "SMB3 never writes to $2001 while the scanline is in the pre-render line + visible field", which isn't a problem at all. It can enable rendering at any point during vblank, before the pre-render scanline.

User avatar
Zepper
Formerly Fx3
Posts: 3214
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: PPU rendering?

Post by Zepper » Mon Aug 31, 2020 5:46 pm

tokumaru wrote:
Mon Aug 31, 2020 3:55 pm
What exactly is it that SMB3 is doing that you find weird? In your first post you just said that "SMB3 never writes to $2001 while the scanline is in the pre-render line + visible field", which isn't a problem at all. It can enable rendering at any point during vblank, before the pre-render scanline.
I'm talking about the boolean state of in_visible_frame_and_rendering on writes to $2001.
In the game SMB3, it never writes during the visible area (pre-render + scanlines), making in_visible_frame_and_rendering always FALSE. It writes $00, then $1e various times. Later, lidnariq said that such state changes "much later". Mesen author says 1 PPU cycle of latency.

User avatar
tokumaru
Posts: 11858
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: PPU rendering?

Post by tokumaru » Mon Aug 31, 2020 5:56 pm

I don't understand why you're expecting $2001 to be written during the active area. In most cases you're not supposed to write to $2001 mid-screen, most games will do it during vblank. The logic of in_visible_frame_and_rendering is not calculated at the time the register is written, it's continuously calculated using the values most recently written to the register. The exact moment the register is written doesn't matter.

User avatar
Zepper
Formerly Fx3
Posts: 3214
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: PPU rendering?

Post by Zepper » Mon Aug 31, 2020 6:05 pm

tokumaru wrote:
Mon Aug 31, 2020 5:56 pm
I don't understand why you're expecting $2001 to be written during the active area.
Either you're out of context, or you don't read emulator sources.
Every emulator (Mesen, Nintendulator) DO this check on $2001 writes.

User avatar
tokumaru
Posts: 11858
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: PPU rendering?

Post by tokumaru » Mon Aug 31, 2020 6:11 pm

I don't read emulator sources, but I have been programming for the NES long enough to know how the PPU works, and programs are not supposed to, and much less required to, enable/disable rendering mid-screen.

The rendering bits in $2001 do NOT have to be turned on during the visible part of the frame for the PPU to start rendering. If emulators are checking this on $2001 writes, then they must be doing it elsewhere too.

User avatar
Quietust
Posts: 1596
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: PPU rendering?

Post by Quietust » Mon Aug 31, 2020 6:21 pm

Zepper wrote:
Mon Aug 31, 2020 6:05 pm
tokumaru wrote:
Mon Aug 31, 2020 5:56 pm
I don't understand why you're expecting $2001 to be written during the active area.
Either you're out of context, or you don't read emulator sources.
Every emulator (Mesen, Nintendulator) DO this check on $2001 writes.
The reason they do it is for reasons of efficiency - rather than checking if ((Reg2001 & 0x18) && (Scanline < 240)) before every single PPU cycle, they cache the result of that expression in a variable, updating it whenever any of the inputs change (i.e. whenever the scanline number changes or whenever the CPU writes to $2001).

Within the actual PPU hardware, re-evaluating that expression every cycle doesn't actually cost anything, so there's no need to cache it, but actually emulating the PPU at that level is infeasible on today's microprocessors (to get an idea of what it's like, take a look at Visual 2C02).
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.

User avatar
Zepper
Formerly Fx3
Posts: 3214
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: PPU rendering?

Post by Zepper » Mon Aug 31, 2020 6:26 pm

I suggest you to avoid breaking up the discussion this way.
tokumaru wrote:
Mon Aug 31, 2020 6:11 pm
I don't read emulator sources, but I have been programming for the NES long enough to know how the PPU works, and programs are not supposed to, and much less required to, enable/disable rendering mid-screen.
I'm working on this emulator since 1998 (and perhaps a bit before on my 33.6k dialup modem).
The rendering bits in $2001 do NOT have to be turned on during the visible part of the frame for the PPU to start rendering. If emulators are checking this on $2001 writes, then they must be doing it elsewhere too.
I'm not talking from (6502 ASM) software perspective.
Quietust wrote:
Mon Aug 31, 2020 6:21 pm
The reason they do it is for reasons of efficiency - rather than checking if ((Reg2001 & 0x18) && (Scanline < 240)) before every single PPU cycle, they cache the result of that expression in a variable, updating it whenever any of the inputs change (i.e. whenever the scanline number changes or whenever the CPU writes to $2001).

Within the actual PPU hardware, re-evaluating that expression every cycle doesn't actually cost anything, so there's no need to cache it, but actually emulating the PPU at that level is infeasible on today's microprocessors (to get an idea of what it's like, take a look at Visual 2C02).
Thanks, Q.

Post Reply