Registered: Apr 2002
Extending MOS 6522 VIA timers to more than 16 bits without interrupts|
This is a trick i came across on some Commodore/drive related newsgroup, which i've put to good use in my loader, and the question is this:
Is there a canonical name for this technique*? :)
And not just for the VIA, but generally in micro-controller usage.
(My SE-fu has failed me, couldn't find anything noteworthy on the net or 6502.org, nor could i find that original newsgroup post.)
Background: Unlike on the 6526 CIA, the 16-bit VIA timers cannot be linked in hardware for 32-bit timeouts.
65535 cycles at 1 MHz are about 65.5 milliseconds, which is just a bit more than 3 PAL videoframes and insufficient for many purposes.
The normal method to extend that timeout period is to have an interrupt for every timeout, which would increase a variable, effectively yielding more than 16 bits with the help of software.
Unfortunately, interrupts are often not feasible (especially in disk drive code), so here's the
Solution: Arithmetically couple two timers by giving them different timeouts.
Consider timer A with a timeout of 65535 ($ffff) cycles, and timer B with 65533 ($fffd) cycles.
As they reset with different periods, their counters will drift apart over time.
Thus, a simple check like this:
lda >counterA; timer A current counter value MSB
cmp >counterB; timer B current counter value MSB
bmi timedout ; hibyte(counterA - counterB) >= 128 -> timeoutmakes it possible to have much longer timeouts than just 65535 cycles.
For this example, that's
65535 * 256 * 128 / (65535 - 65533) = 1,073,725,440 cycles
which is a 30-bit number and corresponds to roughly 18 minutes at 1 MHz.
The bigger the period difference is, the smaller the effective timeout is.
For practical purposes, the minimum is 2 as in this example.
* Note that it works without (co-)prime numbers, but is possibly related to those approaches.