Wednesday, January 25, 2012

Timing & Cycle Budget

I am still dragging a bit after my weekend road trip.  Plus, my days off from work have left me playing a lot of catch-up.  So, I haven't had much time this week for progress on Fahrfall.  Fortunately, I still have some background topics I would like to cover! :-)

Due to the peculiarities of an analog video signal, anything which produces rapidly changing graphics (e.g. a video game) needs to account for the proper timings in order to avoid flicker on the screen.  Racing the Beam gives a good overview of the concerns here, albeit from the perspective of the Atari 2600 instead of the CoCo.  Anyway, the important point is that most drawing in the screen memory needs to occur during the non-visible portions of the video signal.

The VDG is helpful in this regard.  It provides a signal as the end of the visible screen is drawn.  This signal is available on one of the PIA pins that can generate an interrupt.  Alternatively this line can be polled, which is how Fahrfall uses it.  Upon detecting the end of the visible screen, Fahrfall proceeds to erase the player object and the platforms, then redraws the background scrolls, the player object, and the platforms in their new positions.  This not only gives a stable, flicker-free display of those objects, but it also ensures that they are displayed correctly even if another object has moved over them in a previous frame.

The VDG also provides a signal to indicate the end of each line on the screen.  This occurs at a rate of approximately 15.7 KHz.  Currently, Fahrfall does not make use of this signal.  In the future, this signal will probably be used to time the playback of audio data samples for some background music.  Adding this feature will be delayed for a while, since processing interrupts at that rate is terribly expensive and adding polling throughout the code will likely be a bit ugly.

Finally, the score and the flame effect are actually updated at the very beginning of the visible display area.  This is acceptable for the score because it doesn't get updated very often anyway.  As for the flame effect...well, it is supposed to flicker, right? :-)

Mind The Budget

This brings us to the topic of cycle budgeting.  The normal clock rate for the CoCo is ~0.895 MHz, which would give us approximately 14914 cycles per frame in which to work.  Of that, approximately 10752 cycles happen during the visible portion of the video signal, leaving only around 3920 cycles for the non-visible portion.  (The numbers don't quite add-up due to some rounding-down at several stages of the cycle computations.)  It's too bad that drawing on the screen is the most difficult and time consuming part of the least so far!

The CoCo does have a little trick up it's sleeve here -- the "hi-speed poke".  There is a setting for the SAM that doubles the CPU clock speed to ~1.79 MHz.  The problem is that the VDG kinda chokes when that setting is enabled, causing the video display to be garbled.  That limits the use of the "hi-speed" setting to times when video is not being displayed -- exactly when we need the boost!  So by enabling this setting after the end of the visible display area and disabling it before we get back around to the beginning of the next visible portion of the display, we essentially double the amount of time we have for display updates -- ~7840 non-visible cycles, hooray!

Keeping Tabs

So, how do we know if Fahrfall is holding to it's budget?  Well, the technique I mentioned in an earlier post gives at least a rough estimate of how much of the visible budget is being used.  Of course, that is the fattest part of the budget anyway...  Exceeding the non-visible budget results in display corruption at the top of the screen, but that doesn't really tell you if you are still under budget but getting close to exceeding it.

That leaves the tried-and-true method called cycle counting.  Cycle counting is tedious and error-prone, and it can be more of an art than a science in many cases.  Many assemblers (including mamou) can assist by providing estimates for individual instructions, but manual analysis is usually required to determine the aggregate cost of a given routine.  For interested readers I recommend Nick Bensema's Guide to Cycle Counting on the Atari 2600.  Obviously it is written for the 6502-based processor in the Atari 2600.  But, the basic techniques will be similar for other 8-bit processors (including the 6809).

As for Fahrfall, I did an analysis of my non-visible drawing routines.  That includes updates for the background scrolls, the player object, and the platforms.  Right now, that is taking around 7000 cycles -- a bit tight, but hopefully that at least leaves enough room for playing some background music in the future.  Beyond that, there is probably room for a little optimisation there and perhaps I can move some of that work into the visible area so long as I properly account for the timing of the video signal.

I haven't done any analysis on the visible area so far, since that budget is so big and so little work gets done there at this time.  Let's hope that there aren't any big, ugly monsters waiting to eat me there!

Anyway, I hope you have enjoyed this little diversion.  Please continue to watch this space for more updates on Fahrfall!


  1. That was a great read; I also loved seeing Nick's name mentioned (I used to hang out with him at a local 2600 meeting here in Phoenix, but it's been a while since I last saw him - he really knew his Atari).

    1. Thanks! I don't know Nick, but obviously I like his guide. :-)