This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Questions about the Slowdown Effect

Questions about the Slowdown Effect
by on (#163771)
Quote:
Normally, the NES will perform at a steady framerate of 60 frames per second (fps) in ~1.79 MHz CPUs and 50 fps in ~1.66 MHz CPUs to match its respective NTSC and PAL format standards. However, when the game ROM’s PRG becomes too much for the CPU to process it can either cause glitches and/or crash. To prevent any calculations from spilling over into the CPU's processing of the next frame, the NES CPU has been pre-programmed to reduce the framerate (?) and cause slowdown.


When the NES slows down, is there a set rate the CPU slows down to? Is this slowdown measured in MHz? Does it affect the framerate (e.g. lowering it from 60 fps to 40 fps) or is does the slowdown exist independently from the game's framerate? Is it possible to alter the framerate or slowdown effect manually? I'd like to know to see if I can take advantage of it for game design (like for slow-mo!).
Re: Questions about the Slowdown Effect
by on (#163773)
The CPU doesn't slow down at all. It's just that the game has exceeded the complexity of what can be done in a single frame, and those calculations need an additional frame to complete.

Where is that quote from anyway? Someone has a severe misunderstanding of what's going on.
Re: Questions about the Slowdown Effect
by on (#163774)
I found a few similar quotes about EMULATORS slowing to fewer frames per second.
Re: Questions about the Slowdown Effect
by on (#163775)
Yeah, the hardware has nothing to do with this. Slowdowns are purely a software thing that happens when the program can't finish processing the game logic in time, so it continues to do it on the next frame, effectively delaying the game by one frame. If this happens consistently across several frames, the perceived frame rate will be 30fps (NTSC).
Re: Questions about the Slowdown Effect
by on (#163780)
If you have NMI code that spills out of vblank and has to be executed before the RTI (Not graphic updates, but things like music engine updates), spilling into the next frame, won't you eventually need a roll-over frame to catch up and therefore have slowdown too?
Re: Questions about the Slowdown Effect
by on (#163784)
Sogona wrote:
If you have NMI code that spills out of vblank and has to be executed before the RTI (Not graphic updates, but things like music engine updates), spilling into the next frame, won't you eventually need a roll-over frame to catch up and therefore have slowdown too?

Not necessarily, only if it spills too much and doesn't leave enough time for the game logic.
Re: Questions about the Slowdown Effect
by on (#163786)
Dwedit wrote:
The CPU doesn't slow down at all. It's just that the game has exceeded the complexity of what can be done in a single frame, and those calculations need an additional frame to complete.

Where is that quote from anyway? Someone has a severe misunderstanding of what's going on.

This quote was written by me, a person who actually has a severe misunderstanding of what's going on, in a Google doc and it was based off of things I read from across the internet. It was either out-of-date, I misread it, or it was vague. I probably have a lot of things written down incorrectly there, but that's why I'm asking here to get some...

PEER REVIEW


...in order to make sure I get things right.

If you want to look at all the things I have written down (probably incorrectly), here's the link. Anything dealing with ASM was copied straight from tutorials because HOO BOY that's a little complicated for me at the moment and I want to understand the hardware before I get into the software.

tokumaru wrote:
Yeah, the hardware has nothing to do with this. Slowdowns are purely a software thing that happens when the program can't finish processing the game logic in time, so it continues to do it on the next frame, effectively delaying the game by one frame. If this happens consistently across several frames, the perceived frame rate will be 30fps (NTSC).

So the program code is intentionally written so that the slowdown effect occurs then; it's not a matter of the CPU performing slowly, it's a matter of needing to slow down the PRG by 50% in order to let the CPU perform what it needs to. So what exactly is being slowed down then? Is there some kind of feed that goes from the ROM PRG into the CPU that is being slowed down (like intentionally adding cholesterol to a vein to restrict blood flow), or is the PRG literally programmed to be slow when there are too many sprites on-screen and then bump back up to regular speed when there isn't? My bet is on the latter.
Re: Questions about the Slowdown Effect
by on (#163788)
Quote:
So what exactly is being slowed down then?


The frame rate.

From the user's perspective, 60 fps seems like 'normal speed', when the CPU has too much to do (too many sprites on screen for the logic to handle, it spills into the next frame)...the user sees only 30 fps, which looks like half speed.

It's like someone just hit the SLOW MOTION button.
Re: Questions about the Slowdown Effect
by on (#163789)
AlexE wrote:
So what exactly is being slowed down then? Is there some kind of feed that goes from the ROM PRG into the CPU that is being slowed down (like intentionally adding cholesterol to a vein to restrict blood flow)

Running a game is a matter of drawing a picture every 1/60 of a second based on user input. To be able to draw that picture properly, there are a lot of things you have to calculate first... the player object has to move based on input and game world physics, every other object has to be update according to their own sets of rules and interactions with the game world, new background data must be prepared when the camera scrolls... it's a lot to do, and sometimes the program just can't meet the deadline. The time to display a new picture comes but the data necessary to draw it isn't ready yet, so nothing is drawn and the previous picture repeats. The program gets a deadline extension, another 1/60 of a second to finish the picture. If you need a deadline extension for every picture, you're effectively generating half as many pictures as you should in a given interval.

What slows down is the rate at which the program is able to deliver new pictures to the PPU, because each picture is taking too long to compute.

Quote:
or is the PRG literally programmed to be slow when there are too many sprites on-screen and then bump back up to regular speed when there isn't? My bet is on the latter.

On the contrary! Some programs are made to reduce the processing load when too much stuff is happening, in hopes that this will avoid slowdowns. Tasks that are normally done every frame might start to be done every other frame instead, things like that.
Re: Questions about the Slowdown Effect
by on (#163792)
Vertical blank on the NES happens steadily, 60.10 times per second, regardless of what the CPU is doing.* This means that each frame, the CPU has 29,780 cycles to calculate what goes in the next frame. If this calculation takes longer than 29,780 cycles, a frame will be displayed twice.

At normal speed, a game works like this:
Code:
While level not over:
    Read controller
    Move sprites
    Calculate new camera position
    Calculate changes to background and palette
    Draw sprites to display list
    Wait for vertical blank

    # Vertical blank occurs now, and the NMI handler
    # notices that a new display list is ready.
    Send display list to OAM
    Send palette changes
    Send background changes to VRAM
    Set scroll position
    Update audio


Slowdown looks like this:
Code:
While level not over:
    Read controller
    Move sprites
    Calculate new camera position

    # Vertical blank occurs now, but the NMI handler skips updating
    # video memory because the main thread hasn't marked the
    # display list as finished and ready for copying. So the NMI
    # handler skips everything but the music.
    Update audio

    # Now back to the main thread
    Calculate changes to background and palette
    Draw sprites to display list
    Wait for vertical blank

    # Vertical blank occurs now, and the NMI handler
    # notices that a new display list is ready.
    Send display list to OAM
    Send palette changes
    Send background changes to VRAM
    Set scroll position
    Update audio

Thus the same game loop suddenly starts taking two vblanks, thus running at 30.05 Hz.


* Yeah, skipped dot, but that's a rounding error.
Re: Questions about the Slowdown Effect
by on (#164623)
Games for old consoles generally use the vertical blank (vblank) as a timer. The game executes a frame's worth of game logic and prepares the frame for rendering, then waits for vblank. This wait keeps the game in sync with the TV's rendering and also ensures that the game always runs at a consistent, steady pace. For NTSC, each frame is about 16.6 ms. Let's suppose your game handles a frame in only 10 ms; you spend 6.6 ms waiting for vblank before you begin the next frame. Suppose your next frame runs much faster, only 6 ms; now you spend 10.6 ms waiting. If you didn't do that, the gameplay would speed up too. So both your 10 ms frame and your 6 ms frame will be padded out to 16.6 ms.

Now let's say more things start happening and the game does too many calculations, so one of its frames ends up taking 17 ms, which is too long. You missed your vertical blank during the frame, so your wait for vblank ends up waiting for the next one. Your 17 ms frame gets padded out to 33.2 ms. In this case we say the game is running at 30 FPS, because the game is acting as though a frame is 33.2 ms instead of 16.6 ms.

The NES hardware itself neither knows nor cares that this is going on; the CPU is still running at full speed and the NES's video chip still outputs at 60 fps -- but the screen isn't actually changing at 60 fps, because it only changes as fast as the game updates it.

All this stuff is still relevant to modern consoles and PCs, by the way. The only reason we almost never see slowdown in modern games is either the game always runs fast enough or the game has logic to compensate for variable frame rates, which normally wasn't done in the 8- and 16-bit eras.