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!

Hardware Basics Part 2 - A Complicated Relationship


ϕ - the ruler of the system clock 

We have learned that various signals are generated somewhere in the Commodore C64, namely the Color Clock, Dot Clock and System Clock. And we also learned that we have exactly one period of the system clock - a so called CPU cycle - to draw 8 pixels to the screen. 

This already implies that the VIC-II must be somewhat involved during each Cycle - it is our video chip after all. And it actually has a much bigger role than you might expect. In fact I have not explained in the last article how the Dot Clock is transiting to the System Clock other than it is somewhere divided by the number 8. 

You may be surprised to learn that the actual origin of the system clock signal is not the CPU 6510 but in fact the VIC-II. The VIC-II generates all clock frequencies for accessing the data bus for both, itself and the CPU. Regulated by our crystal Y1 the VIC-II receives the Dot Clock signal which it converts to ultimately define the system clock rate which the VIC-II then sends out to the CPU 6510. The 6510 uses this unmodified signal to set the system clock rate for all other components in the system. 

To get a better imagination, lets look at the VIC-II and the 6510, and I mean that we look at the actual integrated circuits sitting on your C64 main board. A few pins on each of the two chips are connected with each other. 

It all breaks down to the symbol ϕ which is the Greek letter Phi and  pronounced just like the english word "Fee". 

The VIC-II has three related Pins labeled ϕ0, ϕColor,  and ϕIN  and the CPU 6510 has two Pins labeled ϕ1 and ϕ2 - the interplay between those signals result in the system wide clock frequency. 

ϕIN and ϕColor are Input Lines where the ϕColor pin receives the Color Clock signal and the ϕIN pin the Dot Clock signal. The ϕ0 pin is an output line that sends out the Dot Clock signal divided by 8. That pin is connected to the CPU 6510 pin labeled 0IN and finally with this received the CPU propagates the unchanged system clock rate of 985.245 kHz on PAL respectively 1022.7 kHz on NTSC machines to all other components via the output pin ϕ2.  But it does not end here - we get now to the delicate part of the VIC-II / CPU 6510 relationship.

Dynamic Logic and the two phases

From a system wide perspective the ϕ2 signal from the CPU 6510 - also referenced as Phase 2 - is of major importance for timing anything in the system.   

The duration of a single period of ϕ2 is further divided into two phases - a phase where ϕ2 is set low and a phase where ϕ2 is set high. In the first phase, the low one, the VIC-II is allowed to read from the data bus and in the second phase it is the CPUs turn to access the bus, in fact as opposed to the VIC-II the CPU is eligible for both, read and write access. The two chips can not access the bus at the same time so VIC-II and the CPU have to take turns. This strange sounding principle is in fact an innovation called Dynamic Logic invented by MOS at a time when accessing the data bus on other systems was done using so-called Static Logic patterns. Effectively Dynamic Logic could be twice as fast as Static Logic implementations when used right.

You would now think that VIC-II and CPU 6510 share their phases within ϕ2 and everybody is happy but this is not entirely true.  

There are two occasions  where the VIC-II actually needs more time than a low phase of ϕ2 provides: 

  1. At the start of every 8th line starting with the first visible line on the screen the VIC-II needs 40 additional cycles to fetch character pointers.
  2. When Sprites are involved, the VIC-II needs additional 2 cycles per activated Sprite.

Lets think about this. If the VIC-II steals 40 CPU Cycles on every 8th line it means that we only have 23 Cycles left on PAL respectively 25 Cycles left on NTSC machines for CPU instructions on every of those lines. The VIC-II work is not affected of course - after all it just greedily takes all Cycles it needs to complete the Raster Line. Since we have less Cycles for CPU related work left those lines are called Bad Lines. While they are the origin for lots of trouble they also opened up interesting ways to exploit how the VIC-II outputs to the screen. 

How does the VIC-II prevent the CPU to take its turn? 

Let's look at this diagram illustrating the way of the signals and the lines responsible to manage the ϕ2 phases - note that the pins below are not accurately drawn in respect to their real position at either chip.

Flow of the various signals to generate the clock rate and to control the Dynamic Logic architecture for memory access.

Pins involved in the Frequency Flow 

  1. he Y1 Chrystal generates the initial frequency of 14.31818MHz (NTSC) respectively of 17,734475MHz (PAL)T
  2. Then the sub-color frequency of 3.58Mhz (NTSC) or 4.43MHz (PAL) is sent to the ϕCOLOR pin of the VIC-II to generate the appropriate video output. In a separate process, the Dot Clock Rate of 8.18Mhz (NTSC) respectively 7.88Mhz (PAL) is provided to the ϕIN line of the VIC-II. 
  3. The Dot Clock signal gets divided by 8 within the VIC-II and moves on via the Output Line ϕ0 to the CPU 6510
  4. the 6510 receives the System Clock Rate at ϕ1 and directs it for output to ϕ2 so finally the unmodified System Clock Rate of 1.023MHz (NTSC) or 0.985Mhz (PAL) is propagated to all other integrated circuit via ϕ2

Dynamic Logic supporting Pins

  • A - the BA pin at the VIC-II is wired to the CPU 6510 RDY pin. If BA is set high we have normal operations and the CPU knows it can do its read/write access to the data bus during a high ϕ2 phase. If the VIC-II needs more cycles because it is for instance fetching Character Pointers on every 8th line, BA is set low and by that RDY on the CPU side becomes low as well. When this happens, the CPU is finishing any remaining write operations and then stops accessing the data bus.  
  • B - the AEC line signals the current phase within ϕ2. It is set low when the VIC-II accesses the bus and set high when it is the turn of the CPU. When the BA line is set to low, so is the AEC line.

 

How the VIC-II defrauds the CPU 6510

From the diagram above you can see that the VIC-II has control over the CPU access to the data bus. It can simply pause the 6510 activity by setting BA low. When the VIC-II has finished its extra work it returns BA to high indicating normal operations.

Let's recap the order of events during the interplay of VIC-II and CPU 6510: 

  1. Normal Operation: VIC-II and CPU share happily access to the data bus. When ϕ2 is low, it's the VIC-II turn, when ϕ2 is high, then it is the CPU 6510 turn. As long as the BA line of the VIC-II is set to high, this is what happens.
  2. VIC-II Stun: VIC-II  needs more time to fetch Character Pointers or take care of Sprites. It ets BA low effectively telling the CPU that it is not supposed to do anything for some time on the data bus. The CPU finishes any remaining write operation which can take between 1-3 Cycles 
  3. VIC-II TakeOver: After the CPU has finished writing ultimately the VIC-II is in control. It can now read from the data bus as long as required. For fetching Character Pointers that would be a time of 40 Cycles.
  4. VIC-II Release: Now that the Character Pointers are fetched, the VIC-II sets BA back to high and the CPU is now informed that we are back to normal operations. 
  5. Back to Normal Operation: VIC-II and CPU again take turn in accessing the data bus within the two phases of ϕ2 .

 

What is the big deal?

The problem with this relationship between the VIC-II and the CPU 6510 are two things. First of all the CPU will finish any write access before it goes into "sleep mode". Write operations take up 1-3 Cycles depending on the instruction. This is an uncertainty we need to handle eventually. And of course, the other problem is that by stealing a number of cycles for VIC-II operations on a Raster Line, we have accordingly less CPU cycles in total left for CPU routines.

Often this is not an issue but when you reach for the stars and want to build great VIC-II effects which needs to be cycle exact then you need to take Bad Lines eventually into account and figure out how to work around or even with them. 

-act