nyef wrote:
Dr Jefyll wrote:
Anyway, sometimes you really do need to hit some I/O device at a precise rate with no jitter, or at least no jitter greater than your oscillator variation, and having a scheme whereby you can do so on an interrupt-driven basis can be useful, as long as your clock speed is fast enough, and your interrupt handler short enough, that you can get useful work done in the meantime and still compensate for the jitter inherent in interrupt response on most platforms.
It's an interesting thread that Garth has just linked to. I didn't see any implementation of this here so thought I'd show a way I've done it for a similar purpose - this is to implement accurate split screen on a BBC Micro, using a VIA timer to wait until a point somewhat earlier than the target time and then a loop in the ISR to wait for an exact time point:
Code:
1060 .topstart
1070 LDA #(timerbias-(time2-time1)) AND &FF
1080 JSR timersync
...
1520 .timersync
1530 STX zpsavedx
1540 CLC
1550 ADC &FE64
1560 LSR A
1570 BCS P%+2
1580 BCS P%+2
1590 LSR A
1600 BCC P%+4
1610 LSR zpjunk
1620 TAX
1630 .syncloop
1640 BIT 0
1650 DEX
1660 BNE syncloop
1670 LDX zpsavedx
1680 BIT 0
1690 RTS
In this context, at "topstart" a VIA Timer 1 interrupt has just fired and "time2-time1" is the value that was in the latches, and loaded into the timer at the time of the interrupt. "timerbias" is a small value, e.g. 10, used to make the interrupts occur slightly early so that latency in the interrupt can be tolerated more or less. If an interrupt was being serviced when the time elapsed for example then some of this tolerance would be used up. (Looking back, 10 seems a really small number so I might have misremembered this bit. )
So A gets loaded with a value we'd like to see on T1, and "timersync" compares it against the current count in T1 and adds a variable delay so that by its end we are at a consistent offset from that time point.
It's worth noting that the VIAs in the BBC Micro are clocked at half of the usual CPU frequency, and any access to them aligns the CPU with that slower clock. So this loop actually has to wait for twice as many CPU cycles than the T1 difference that was calculated. (Edit - I suspect adding an extra "LSR" and "BCS P%+2" after line 1550 would make it work for cases where the VIA shares the usual CPU clock.)
If you're interested in the wider use case for this or the rest of the code, please see here:
https://stardot.org.uk/forums/viewtopic ... 12#p356012