Basic timer
In addition to hardware interrupts the VIA (Versatile Interface Adapter) provides two timers which can generate interrupts and Ben Eater has a very good tutorial which explains their use. In the first example a one shot timer counts down to 0 then sets a bit in the IFR (Interrupt Flag Register). The counter is a 16-bit register and is decremented each clock pulse so the maximum count down is 65535, approximately 65mS. If we toggle an LED and restart the counter each time the interrupt occurs we have an LED flashing at about 10Hz.
As you can see from the code below, a loop via_delay is used to check whether the IFR flag has been set by the counter. Clearly it isn't very useful to sit in a loop waiting for a flag to be set although you could add more code to do other functions within that loop.
Tick Timer
Ben's second example shows a very good clock feature which we will be able to use regularly. The timer is put into freerun mode so that it starts again as soon as it reaches zero. In addition to setting the IFR a 6502 interrupt is generated. The interrupt service routine (ISR) is invoked on the 6502 each time the counter hits zero, and simply updates a four-byte tick counter in zeropage memory.
The counter is setup to hit zero every 10ms so, if we want to toggle an LED every second, we simply check whether the tick counter has increased by 100. The following program shows the various parts of the tick timer. On startup init_timer is executed to zero the tick counter and the timer is set to $207e giving 10mS interrupts. Irqvia is at a fixed address $1003 and is invoked to increase the tick count each time a timer interrupt occurs. For this demo there is a loop which updates LED and LCD periodically.
Clock program
I could then display the time using the three variables as hh:mm:ss on the LCD.
The update works independently of other VIA test functions.