Thursday, March 22, 2012

6522 VIA Experiment #2

In this instalment we'll use the timer on the VIA to generate pulses.


The 6522 VIA has two timers. Timer 1 can operate in several modes. One of the modes is a free running mode where the PB7 line toggles every time the timer counts down to zero. In free running mode the timer continuously reloads the count when it reaches zero. This allows generating a square wave of an accurate frequency, with no CPU overhead once it is set up.

The frequency, f, of the output is determined by the formula:

        f = PH2 / (2 * (n + 2) )

where PH2 is the frequency of the phase 2 (CPU) clock and n is the timer count value. The maximum frequency is when n = 0, giving a frequency of 1/4 of the PH2 clock. On my system the clock is 2MHz (a stock Replica 1 is 1 MHz), giving a maximum frequency of 500 KHz. The minimum frequency is when n = hex $FFFF or 65535 decimal, resulting in a rate of about 15.26 Hz.

If you wanted a rate of 60 Hz for example, the closest timer value would be 16665 which results in a rate of 59.9988 Hz. Unfortunately, if you were to use this for a clock based on 60Hz, it would result in an error of more than one minute per day. It is better to use a time value that results in an exact multiple of seconds. For example, the value 9998 produces exactly 100 Hz.

The following BASIC program will show the timer values that give exact frequencies (you need to run it with an floating point BASIC like Applesoft Lite and not Integer BASIC).

REM BASIC program to find counts that result in exact frequencies
100  FOR I = 0 TO 65535
110  F = 1000000 / (I + 2)
120  IF F =  INT (F) THEN  PRINT I;" ";F
130  NEXT I

Here is the output of the program:

COUNT FREQ (HZ)
0 500000
2 250000
3 200000
6 125000
8 100000
14 62500
18 50000
23 40000
30 31250
38 25000
48 20000
62 15625
78 12500
98 10000
123 8000
158 6250
198 5000
248 4000
318 3125
398 2500
498 2000
623 1600
798 1250
998 1000
1248 800
1598 625
1998 500
2498 400
3123 320
3998 250
4998 200
6248 160
7998 125
9998 100
12498 80
15623 64
19998 50
24998 40
31248 32
39998 25
49998 20
62498 16

Now for the the code for our example. We first set the Interrupt Enable Register to not generate any interrupts as our code is not prepared to handle interrupts. We write to the ACR to set the Timer 1 mode. We then write the low and high bytes of the counter. Writing the high byte starts the counter counting. After that we return. At this point the VIA continues to generate square wave pulses on the PB7 output.

Here is the source code:

  .include "6522.inc"


  COUNT = $4119
      
  LDA #$00
  STA IER             ; disable all interrupts
  LDA #%11000000
  STA ACR             ; Set to T1 free running PB7 enabled
  LDA #<COUNT
  STA T1CL            ; Low byte of count
  LDA #>COUNT
  STA T1CH            ; High byte of count
  RTS

And here is the output on an oscilloscope. Mine scope has a counter this reports the frequency, quite close to the 60Hz we were aiming for.

60Hz Square Wave Output


1 comment: