ROM Computer Magazine Archive ROM ISSUE 9 — DECEMBER/JANUARY 1985 / PAGE 25

Atari's Timing System
by Bob Cockroft

    This article is the first in a series on the Atari's timing system. It will be the goal of this series to explain in some detail how the timing system operates, and to present a number of practical applications. This first article will give an overview of the system and will apply its basic principles to the screen COLOR Register.
    Many people program without using the timing system. This is unfortunate in that the Atari has an effective system that can be used in a number of ways. In fact, the time base which the circuitry operates is synchronized with the television signal. This produces both a distinct graphics screen and some interesting programming possibilities. There are 2 main types of standard television signals(NTSC/PAI). Canada and the United States use the NTSC system which creates 60 frames per second and 262 lines per frame. However, European countries use the PAL system which creates, instead, 50 frames per second and 312 lines per frame. As a result of the difference, the Atari must modify its timing system to make it compatible with either the NTSC or PAL standards.

The PAL byte

    The standard(NTSC/PAL) your television uses can be determined by examining the `PAL' byte($D014/ dec 53268). If the PAL byte equals zero, the PAL standard is used. Conversely, if the PAL byte does not equal zero, your television uses the NTSC standard.(see below) For simplicity, this article assumes that you have a NTSC standard television.

PAL $D014

bit number: 
dec. 53268

b0 
...      ...
  not   used
  ...
b3...
...
b2...
...
b1...
...not...
used...
 
NTSC     =
  PAL      =
...
1
0
...
1
0
...
1
0
...
= 13
=   0


    Every 1 /60th of a second the electron beam of a NTSC standard television creates a new screen by drawing horizontal lines of graphics from top to bottom. The 6502 processor synchronizes with the television by causing a system interrupt after every screen is drawn(per. of 1/60 of a sec.). The period in which the electron beam of the T.V. returns to the top of the screen from the bottom is called the VERTICAL BLANK. The computer interprets this period as a non-maskable interrupt. As a result, an interrupt occurs regularly every 1/60th of a second. This interrupt, in conjunction with the Timers, can be used to cause the computer to automatically change colours, sound, or any other function.
    By setting its system clock rate to 1.79 MHz, the distance in which the electron beam moves across the screen can be measured in terms of machine cycles. For example, the time in which the 6502 executes a 4 cycle instruction like `EOR'(absolute), the electron beam will move 2 character widths across the screen. As a result, colour changes or many other types of graphics effects can be done in the middle of a horizontal line of graphics. Unfortunately, because the timing system is not exact(in terms of small fractions of a second) it is often difficult to pinpoint the precise spot on the screen where you want the graphics effect to occur.
    The Atari computer has 6 timers. Their address and interrupt vectors are listed below.


Symbol
(Timer)
 
Location
(dec.),
Symbol
Vec/Flag
Interrupt
Vector/flag
RTCLOK 18,19,20

none
CDTMV1 536,537
CDTMA1
550,551
CDTMV2
538,539
CDTMA2 552,553
CDTMV3 540,541
CDTMA3 554
CDTMV4 542,543
CDTMA4 556
CDTMV5 544,545
CDTMA5 558


    The first item on the above list, Realtime Clock(RTCLOK), is the most convenient timer; therefore, it should be used where simple timing routines are needed. This device uses 3 bytes from 18 to 20 dec. The first byte, address 20 increments every VBLANK. In other words, once every 1/60th of a second the value in this location increases by one. When address 20 reaches a value of `255', it is reset to `0' and address 19 is incremented by one. In turn, when address 19 reaches a value of `255' it is reset to `0' and address 18 is incremented by one.(sec below)

Realtime Clock

                    +1 < 255
      ----------------------
      |      |      |      |
 LOC. |  18  |  19  |  20  |
      |      |      |      |
      ----------------------
          +1  < 255

Below is a program which uses these bytes to make a basic clock.

10 REM ***********************
20 REM *                     *
25 REM *    REALTIME CLOCK   *
30 REM *                     *
35 REM ***********************
50 GRAPHICS 0
52 REM * TURN OFF CURSOR *
55 POKE 752,1
58 REM * SET REALTIME CLOCK TO ZERO *
60 POKE 18,0:POKE 19,0:POKE 20,0
70 P0SITION 17,8:? "CLOCK"
80 POSITION 16,12:? "Hr Min Sec"
90 TH=0:TM=0:TS=0
97 REM *
98 REM * REFER TO REALTIME CLOCK *
100 T=INT(PEEK(19)*4+PEEK(20)/60)
101 REM * DETERMINE SEC,MIN AND HOURS *
102 TS=T
104 IF T>59 THEN TS=0:TM=TM+1:POKE 19,0:POKE 20,0
107 IF TM>59 THEN TH=TH+1
110 POSITION 16,10
120 ? " ";TH;":";TM;";TS;" "
140 GOTO 100

    The Realtime clock bytes can be changed through the POKE command (or the equivalent) to any starting value. In fact, the above program does this at line 60, where it initially sets the clock to zero. Unfortunately the Realtime clock does not have interrupt capabilities. In other words, it is unable to stop the regular functions of the Operating System when the clock reaches a predetermined point. Without an interrupt capability, a timer program is unable to take over control of the computer when another program is currently executing. Fortunately, some of the other timers have interrupt capabilities.
    The Atari computer contains 5 countdown timers. Using a 2 byte configuration, these timers decrement from a user defined starting value that can range anywhere from 1 to 65536. If a value of `250' were POKEd into one of these timers, it would be reduced by `1' every VBLANK(1/60 of a sec). When this value reaches zero, control is forced through the address stored in its corresponding interrupt vector. By pointing the interrupt vectors to the location of a user created machine code, most any operation can be performed even though the computer is busy doing something else. For example, suppose you wanted the computer to automatically change the screen colour while you were programming in BASIC. The first step in accomplishing this would be to make a machine language subroutine that would change the colour of the screen. This subroutine would need to store different values to playfield color register($2C6)(710 dec). In addition, a RTS(return from subroutine) instruction would need to be placed at the end of the routine so that control would be given back to the Operating System. Although this code could be stored anywhere in free RAM, for the purposes of this demonstration assume that a group of bytes beginning at 1536($600 hex) are used. The following is a routine containing all the characteristics mentioned above.

Machine Subroutine
dec  command  ;explanation

173  LDA $64B ;load colour value
 75  lo byte
  6  hi byte
 24  CLC      ;clear carry bit
105  ADC #10  ;add 10 to the color value
 10  amount
141  STA $64B ;store colour value
 75  lo byte
  6  hi byte
141  STA $2C6 ;display new colour
198  lo byte
  2  hi byte
 96  RTS      ;return from subroutine

    The second step is to decide the length of time for which the timer is to be set. Because the timer can have a value as high as 65536 and decrements every 1/60th of a second, the maximum period is 18.2 minutes. However, for simplicity, assume that timer 2 is given a value of ` 100'dec(538,539).(see below)

100 dec

location 538 = 100  The 2 bytes of
location 539 = 0    Timer 2

    The computer would then begin to decrement the value (100) every VBLANK (60th of a sec). When the value reaches zero, control is passed to the address specified by Timer 2's interrupt vector bytes (552,553). To cause the colour of the screen to change, store the starting address of the machine subroutine to the interrupt vectors. As a result, when timer 2 counts down to zero, control is passed to the subroutine where the screen colour is changed. The first program at the end of the article changes the screen colour in a manner similar to the one described.

The SETVBV Routine

    Because the count-down timers are decremented during the VBLANK process, special care is needed to set them correctly. The easiest method of setting them is to use the SETVBV routine ($E45C). By storing the timer number in the Accumulator (`A'), the low byte of the timer value in the `Y' Register, and the corresponding high byte in the `X' register, 'jumping' to the SETVBV routine will set the timer automatically.

LDA #2      ;Set count-down timer 2
LDY #250    ;low byte 250 cycles
LDX #0      ;hi byte
JSR SETVBV  ;jump to the routine

SETVBV = $E45C

    The following program changes screen colour in much the same way as described in this article.

10 REM *************************
20 REM *                       *
30 REM *       AUTOMATIC       *
40 REM *  COLOUR MODIFICATION  *
50 REM *       PROGRAM 1       *
60 REM *                       *
10 REM *************************
80 REM *
95 REM * STORE SUBROUTINE l(at 1536)*
100 FOR X=1536 TO 1536+10
105 READ D
110 POKE X,D
115 NEXT X
117 REM * STORE SUBROUTINE 2(at 1580)*
120 FOR X=1580 TO 1580+14
125 READ D
130 POKE X,D
135 NEXT X
138 REM *
140 REM * SET TIMER POINTERS TO *
142 REM * SUBROUTINE 2 (1580)   *
145 POKE 552,44:POKE 553,6
147 REM *
150 X=USR(1536)
9990 REM *
9992 REM *
9995 REM * SUBROUTINE 1 (set timer 2) *
10000 DATA 104,169,2,160,10,162,0,32,92,228,96
10002 REM *
10004 REM *
10005 REM * SUBROUTINE 2 (change colour) *
10100 DATA 173,75,6,24,105,10,141,75,6,141,198,2
10115 REM * RETURN TO THE FIRST SUBROUTINE *
10117 REM * IN ORDER TO RESET TIMER 2      *
10120 DATA 76,1,6


10 REM *****************
20 REM *               *
30 REM *  SOUND DEMO   *
40 REM *  PROGRAM 2    *
50 REM *               *
60 REM *****************
100 P60=100
110 P61=100
120 REM * DISPLAY AND PRINT SCREEN *
130 GRAPHICS 0
140 POSITION 13,2:? "SOUND TEST"
150 POSITION 2,20:? "Use the JOYSTICK to change the values"
160 POSITION 2,21:? "stored in addresses 53760 and 53761"
170 POSITION 2,4
180 ? "SYMBOL:    AUDF(1)      AUDC(1)"
190 POSITION 2,15:? "AUDF(1)=Audio channel one frequency"
200 POSITION 2,16:? "AUDC(1}=Audio channel one control"
210 POSITION 2,5
220 ? "ADDRESS:   53760        53761"
230 POSITION 2,7:? " Value:"
240 POKE 752,1
250 REM *
260 REM * USE JOYSTICK TO CHANCE SOUND *
270 ST=STICK(0)
280 IF ST=14 AND P60<255 THEN P60=P60+1
290 IF ST=13 AND P60>0 THEN P60=P60-1
300 IF ST=11 AND P61<255 THEN P61=P61+1.
310 IF ST=7 AND P61>0 THEN P61-P61-1
320 REM *
330 REM *
340 REM * CHANGE SOUND FREQUENCY *
350 POKE 53760,P60
360 REM *
370 REM * CHANGE VOLUME AND DISTORTION *
380 POKE 53761,P61
390 REM *
400 REM *
410 POSITION 14,7
420 ? P60;"         ";P61;"       "
430 GOTO 270