The Ideal C64 Game Loop


If you want to write a game on the C64, you will need something that is called a Game Loop. But why? But what is the Ideal C64 Game Loop?

A Game Loop is a loop that basically runs forever. In each Iteration of the loop, player inputs are tested, game logic is calculated and the output (graphic, sound) is generated. The task of the developer is to make the loop as efficient as possible.

Let’s look at how you create a Game Loop and why efficiency is crucial.

Is there an Ideal C64 Game Loop?

From a programmers view, a Game is the alternation between the interaction of the player, the reaction to this interaction and the generation of the output like graphics and sound. From start to finish these task have to be done over and over.

The way that most developers go is by creating some sort of infinite loop. In each Iteration of this endless loop they test a bunch of things. Although the order may be different sometimes, most start by checking the player input. Has the player moved the joystick or pressed any key?

As a consequence to that, some things must be calculated. What is the new position of the Player’s sprite? Did the player hit the target? Should we start a jump animation? And after this, the Game may want to respond. Is the evil Alien in shooting range? Then, the results are shown on the screen and maybe sounds or music are played. At last, the loop starts over.

Does the loop really run forever? Most of the time there will be some sort of game state flag. If this flag changes to a certain state the loop execution and therefore the game ends. The flag could for instance change because the player pressed exit.

Please note that the memory where the label game_state points to is changed by code in the subroutines

Time Critical Code

The loop is good for time consuming things like scrolling the screen or game logic. For time critical things like sound or raster effects may be better to use Interrupts (IRQs).

Quick Introduction to C64 Interrupts

This is a really quick introduction and by no means complete. It is just enough to understand what interrupts are, how they work and why they are useful for game programming on the C64.

The C64 trigger a so-called interrupt routine about every fraction of a second. On NTSC machines this is every 1/60 second and on PAL machines every 1/50 second. In this interrupts the C64 freezes the running program and runs some code. Afterwards it continues the program. This happens so fast that neither the user nor the interrupted program ever notices that they were interrupted.

An example for code running at an interruption is the blinking of the BASIC cursor. Every 20 interrupts the cursor is reversed which generates the blinking effect on the screen. This will happen roughly three times per second.

Interrupts and the Ideal C64 Game Loop

When the interruption strikes, the C64 jumps to the address vector $FFFE | $FFFF where another jump address is stored. Since $FFFE | $FFFF is in ROM we cannot change it. From there, it saves the current registers and then points to the address vector $0314 | $0315. The address stored in this second vector is $EA31. The C64 jumps there, performs the system routine and eventually restores the registers before it comes back to unfreeze the interrupted program.

What you can do as a programmer is to inject the target address of your own subroutine into the vector $0314 | $0315. Then your subroutine will get called every time the interruption strikes. It is important to point to the original $EA31 after your subroutine has finished. In this way the normal sequence of the c64 will not be disturbed.

You can find a detailed description of the CIA registers here. (link opens in new tab)

Now you can have your main Game Loop for the time consuming task. The time critical tasks are now handled by your custom interrupt routine.

A word of Warning: The time you can use in your custom interrupt routine is not infinite. When you take too long your keyboard may not react, your cursor stops blinking, etc. The same things happen if you disable the IRQs completely.

Constant Frame Rate

You can also use the raster position to ensure a constant frame rate. At the beginning of you game loop wait for a certain raster position to occur. This will stabilize the timing of the game.

Then our Game Loop from the first example would be like

Conclusion

While there may be a lot more to say about Game Loops, Interrupts and Raster Effects, this may be enough for now. A lot of these things depend on the game that you are creating. Having a main Game Loop and some sort of Frame Rate stabilization is mandatory. The rest is up to you as a programmer.

Marco Lieblang

Professional Programmer since 2003, passionate Programmer since the mid 90's. Developing in many languages from C/C++ to Java, C#, Python and some more. And I also may know a bit about Assembly Languages and Retro Systems.

Recent Posts