!pr2
Delays, delays, delays.....................Bob Sander-Cederlof

We always want speed.  Making computers compute faster keeps our industry humming.  Yet nearly every major program has pieces of code called delays.

We use them to generate carefully controlled, timed events:  for example, generating a musical tone.  We use them to synchronize events, or to provide time for external events to occur.  We even use them just to slow the computer down so we can watch it work.

Delays are used so often that Woz had the foresight to put a general purpose delay subroutine permanently inside the monitor ROM.  It resides at $FCA8.  It is short (only 12 bytes), sweet (only uses one register, the same one which controls how long a delay you get), and slow (on purpose).  Here is a listing:

!lm+5
WAIT   SEC             PREPARE TO SUBTRACT
.1     PHA             SAVE A COPY OF A-REG
.2     SBC #1          COUNT A-REG DOWN TO ZERO
       BNE .2          ...UNTIL A=0
       PLA             GET SAVED COPY OF A-REG
       SBC #1          COUNT THIS COPY DOWN TOO
       BNE .1          ...UNTIL A=0
       RTS
!lm-5

To use this subroutine, you load the A-register with a value which will determine the length of the delay, and then JSR WAIT.  When the subroutine returns, A=0 and somewhere between 29 and 167309 clock cycles have elapsed.  The formula, somewhat confusingly printed on page 165 of the white Apple II Reference Manual (and elsewhere in other manuals), is:

       # cycles = (5*A*A + 27*A + 26)/2

For an example of its use, look in the monitor listing at $FBDD (the bell routine).  Examples of other timing loops are found in the tape cassette I/O routines ($FCC9-$FD0B) and the paddle reading subroutine ($FB1E).

Bill and I spent the last two weeks working with software which surrounds the Novation Cat Modem.  It is loaded with calls on the monitor WAIT subroutine.  It is exceedingly tiresome to crank out a formula like the quadratic above by hand, or even with a calculator, over and over and over, when you have several Apples sitting in the same room!

After four or five trips to the manual and the calculator, I decided to work out the times for all possible values of the A-register.  Once and for all.

Here is a little Applesoft program which does the job, and elsewhere in this AAL you will find a full page showing all the cycle counts.


















The A-register values are given in both hex and decimal.  The delay count is given in thousands of cycles.  Each cycle is close to one microsecond, so you could think of the counts as being in milliseconds.

The purists among you will want to multiply these cycle counts by the ACTUAL clock period (.9799268644 microseconds average, according to Sather) to get ACTUAL time.

RWTS in DOS or ProDOS also give lessons in the use of precise delays.  You will find weird little pieces of code which make no sense whatever inside RWTS.  Things like PHA followed immediately by PLA, followed by a NOP.  These are usually just delaying tricks.  A PHA-PLA pair takes exactly seven cycles, a NOP 2 more.  There is a delay while waiting for the motor to come up to speed.  Another while stepping the head from track to track.

These last two are intertwined, so that delays used while stepping across tracks count towards the total delay required 
to get the disk rotating at 300 rpm.

Don Lancaster in his Enhancing the Apple books makes good use of delays in synchronizing graphics generation with the CRT.  By updating a picture in one graphics page while displaying another, and then switching pages, you can get pretty impressive animation.  However, the page flipping operations sometimes splatter the display.  Using delays just right, you can make the switching occur when it won't be noticed.  You can even mix graphics into the middle of a text screen or vice versa, or mix hi-res and lo-res on the same screen.

Jim Sather in "Understanding the Apple II" also uses delays to control the screen switches in interesting ways.  Jim figured out exactly how many cycles everything in the video generation circuitry takes.  Using his programs you can even use hi-res to draw underlines on text screens!  A horizontal scan takes exactly 65 clock cycles.  A vertical scan takes exactly 17030 cycles.  The following program, adapted from one given on page 3-16 of Sather's book, splits the screen between hi-res and lo-res.  Tapping the space bar moves the boundaries of the split.  Play with it!
