PPU and vblanking

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
User avatar
essial
Posts: 72
Joined: Thu Dec 03, 2009 8:20 am

PPU and vblanking

Post by essial » Thu Dec 03, 2009 7:44 pm

Does the PPU render output in sync with the CRT? I'll admit I don't know jack didly about how CRTs and NTSC signals work. I'm working on re-writing my PPU logic and trying to figure out if I need to only render at the end of an entire frame, or just render to the screen as needed. From what I understand the NES always runs at 60fps (in NTSC timing mode), and it may be that the PPU outputs exactly in-sync with the scanline (that would make the most sense), but the issue here is that the computer monitor may be rendering at 75hz or more. So do I just render as fast and as often as possible (like after each scanline) or what? I know simply displaying the frame at the end of a full frame render "would work", but I want to make this as accurate as possible.

User avatar
MottZilla
Posts: 2835
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla » Thu Dec 03, 2009 8:02 pm

You need to emulate the PPU as if it were drawing the picture in realtime. You can choose how best to do this yourself. Typically people will wait until a whole scanline has been rendered and then they will update the PPU to draw that line to a cache of some sort. This means you have stored the appearance of this line for later use. When the final scanline is drawn is generally when you want to update the Computer monitor with the completed frame. How you sync your emulation to ensure that it runs at a rate of 60hz is up to you. Many emulators sync on sound playback. Others sync on VSync of the computer monitor which requires 60hz mode on the monitor which can only be certain if you use full screen.

Again to be clear, you don't need to draw anything to the computer screen while the NES PPU is rendering each line, but you DO need to be drawing to a cache somewhere or otherwise remembering the state of the screen at certain points so that when it is time to render the frame to the computer screen you can do so accurately.

User avatar
essial
Posts: 72
Joined: Thu Dec 03, 2009 8:20 am

Post by essial » Thu Dec 03, 2009 8:16 pm

Yeah of course I render to an off-screen buffer (what you are referring to). I have to do that anyway since I use the NTSC library to finally render it to the screen.

Here's a better phrased question that will answer the same question:
If I had a rom that did nothing but flip between white and black on the screen each frame, would the TV instantly change from white to black, back to white, or would it go from top to bottom (as I expect)? If so, then it sounds like I will need to render in a separate thread, which simply tries to redraw (at most) once a scanline. On most computers I'm sure it may have to render several scanlines at once to catch up (since it would technically have to render at around 270fps to do it at 100%) but even at 20% it will not drop frames. Perhaps I could have it as a setting (per-scanline or per-frame rendering) or something.

Vsyncing the emulator with the monitor doesn't make sense unless you are also vsyncing the video output.

User avatar
MottZilla
Posts: 2835
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla » Thu Dec 03, 2009 9:08 pm

I don't understand what you are confused about. How to draw the picture to the User (the computer's emulator output the person using it sees) or how to draw the emulated output (data that is used to later draw the picture for the user to see).

My emulator works like this. Every PPU Cycle I draw a pixel to my screen buffer. When the entire screen buffer is drawn, I redraw the PC screen so the user sees the new frame. At this time I also syncronize the speed of emulation to maintain approx 60hz.

I have no idea what you mean by vsyncing the emulator with the monitor and then the video output. I will be as clear as possible.

Run CPU 1 Cycle. Run PPU 3 Cycles. Repeat process until screen has been drawn in buffer. When screen is drawn in buffer, syncronize and redraw the PC screen with the data from the buffer. Repeat.

You will need to draw 60 frames every second for NTSC. Not 270.

User avatar
essial
Posts: 72
Joined: Thu Dec 03, 2009 8:20 am

Post by essial » Thu Dec 03, 2009 9:23 pm

I know; I was referring to rendering the entire screen (that is, send the entire current video buffer to the NTSC filtering library, and outputting the result on the screen) at the end of each scanline render in the PPU, instead of at vblank. That's where I get the the 270 (although I really meant 240).

User avatar
MottZilla
Posts: 2835
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla » Thu Dec 03, 2009 9:53 pm

I would recommend not sending any scanlines to the NTSC filter library until the whole 240 are done. You aren't going to be redrawing just part of the screen as you go, only when a full frame is complete.

User avatar
essial
Posts: 72
Joined: Thu Dec 03, 2009 8:20 am

Post by essial » Thu Dec 03, 2009 9:56 pm

That's what I wanted to know -- if there were any situations where a game/rom would count on the screen not being completely drawn. I just wanted to make sure I covered all of the angles.

User avatar
Disch
Posts: 1849
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch » Thu Dec 03, 2009 10:55 pm

Not as far as I know.

I don't think the human eye would be capable of discerning that anyway.

Post Reply