Dustlayer

Retro means old but cool.

I grew up with the Commodore C64 but was never able to master the machine. I was young, I wanted to play the latest games and let other people do the pioneer work on exploring this incredible hardware. Today I have better skills to catch up on what it takes to code the C64. I will share what I learn along the way. Enjoy the trip to the past!

VIC-II for Beginners Part 3 - Beyond the Screen: Rasters and Cycles

Screen Dimensions from a Raster Beam perspective

When we talk about the screen we must first clarify what the screen actually is. When you turn on your C64 you have an (officially) accessible resolution of 320x200 surrounded by a light blue colored border. This is the same for PAL and NTSC machines. However, if we talk about the number of lines the raster beam needs to generate per each screen redraw it is not just 200  but in fact 262 lines for NTSC models and 312 lines on a PAL C64. I will use metrics based on a PAL system for the following explanation.

With analog television you need to take the time the raster beam needs to go from the last line it drawed to the first line into account. This is called Vertical blank or VBLANK. The same applies horizontally, that is after finishing drawing the last pixel to the right, the raster beam needs to start over in the next line on the very left. This is called horizontal blank or HBLANK. Taking VBlank and HBlank into account the Raster beam has to travel 504 pixels horizontally and 312 lines vertically for one full screen refresh on a PAL C64. The actual travelling the raster beam does to get from the last line to the top or from the last pixel on the right back the left is called Screen Blanking.  Since timing is very crucial when working on the Commodore C64, we need to know that our screen refresh includes more than just the visible area. 

Rasters & Cycles on the Screen  - image taken from the C64 presentation by Michael Steil. Thanks!

So we care about how much time a raster beam needs to reach a specific position on the screen or how much time it takes to draw one byte of information. For this we need to learn some other common expressions.

There is Raster Time which is the duration it takes for the VIC-II to put one byte of graphic data on the screen. Raster Time is measured in CPU cycles.  CPU cycles are basically the smallest unit of currency on the Commodore C64. At some point all you care about is to optimize your code to save CPU cycles per screen refresh. There is also the expression Raster Line which applies to a full line of the screen and not just a single byte. 

The Raster Time to put one byte of data on the screen is exactly 1 Cycle. As far as the Raster Beam is concerned a full horizontal line has 504 pixels which we can divide by 8 to get the time required for a Raster Line - it is 63 Cycles. To complete the math, since we have 312 lines of distance from top to the bottom of the screen, the amount of Cycles needed to draw once over the full screen is 312 lines * 63 Cycles = 19656 Cycles.  The 6510 CPU in a PAL C64 is clocked with 985248 Hz. If we divide this number by the CPU Cycles we calculated for one screen refresh we are at 50.125 which equals ~50HZ for the final refresh rate. That sounds just about right for the PAL standard. The calculation does not consider the time we need for the screen blanking though. 

The Black Sheep of Raster Lines - The Bad Line

Now with this information we would assume that we have 63 Cycles of computation time to do something cool on each line on the screen. However, there is one additional catch with timing and to understand we need to take a look at the close partnership between the CPU 6510 and the VIC-II chip.

The CPU and the VIC-II both share the same data bus which they access both once per cycle. Since they can not access the bus at the same moment they agree to take turns within a cycle. One cycle is therefor divided in two phases, a low and a high phase. The VIC-II accesses the data bus in low phase and the CPU in high phase. However, it turns out that the VIC-II sometimes needs a few more cycles for a raster line than it got reserved from its share in the low phase windows. This for example occurs when it needs to retrieve color information, or when it starts fetching characters. It also happens when the VIC-II has to deal with Sprites on the screen.

For example displaying a character takes an additional 40 cycles as the VIC-II needs that extra time to check the destination of  a character pointer for retrieving the actual data. The additional cycles are usually needed every 8 lines because standard characters are 8 lines high and the VIC-II needs to fetch the location of the to be drawn character on every first line of the 8x8 character matrix.

So what the VIC-II actually does to get hold of those required additional cycles is to block the CPU for about 40 cycles. The raster line where this stunning of the CPU happens is called a Bad Line because we have now less cycles left for computation in our actual assembler code - the VIC-II just stole it from us! Instead of 63 cycles of CPU time we only have 20something cycles on every Bad Line. This will become important when we need exact timing in our game or demo. There are various ways to exactly sync the action on the screen with the refresh rate and will talk about building so-called Stable Raster Routines when an opportunity comes up.

This is a simplified explanation but we will come back to Bad Lines at a later point and for that you should have a basic understanding.

-act