andym00
Registered: Jun 2009 Posts: 45 |
CIA Timer latency ?
Just got to the root of a mysterious problem and I'm wondering why, because I've not heard about this before..
I'm using CIA1-Timer A as a trigger point for calling a scheduler serving a bunch of tasks in the background..
CIA1-TimerA is setup like this:
lda #0
sta $dc0e
sta $dc0f
lda #$7f ; Disable all interrupts..
sta $dc0d
lda #0 ; Set timer to 0 cycles..
sta $dc04
sta $dc05
lda #$81 ; Enable IRQ for Timer A..
sta $dc0d
lda $dc0d
The aim being that at any point I want to trigger a task swap I can just do:
lda #%10011001
sta $dc0e
Either to just serve background tasks in a round-robin way, or to force it to service a specific task immediately..
I'm mainly triggering it from within very high rate NMIs (where I force it to switch to a specific task), but it can also be triggered by the tasks themselves when they've completed work..
My question is this..
This test thread:
test_thread:
inc $d021
jsr Generate_Pulse_Train
jsr Generate_Pulse_Buffer
dec $d021
lda #%10011001
sta $dc0e
jmp test_thread
With the timer set to zero cycles it should underflow at the next clock cycle, by which point JMP has begun to execute and and by the time it finishes (3 cycles later) the IRQ should be pending, and should pull the non-interrupt code into the IRQ where we fall into the scheduler..
Except it doesn't.. Not instantly anyway..
The task loop above is execcuting the inc $d021 before the CIA one-shot timer trigger has invoked the interrupt.. Inserting one NOP after the sta $dcoe and before the jump makes it work as expected, but I'm wasn't aware of any latency in starting the timers like this, or latency in terms of triggering an interrupt.. Did I miss something here ?
So it appears there's some latency with either triggering a one-shot timer, the interrupt being triggered, or something else..
Has anyone got a reasonable explanation for this behaviour, because I'm unhappy with a bodgy NOP in there without knowing exactly why I need it..
And before you ask, the idea is to have 100% stable NMI timers running at 7.8K, with raster interrupts still working underneath, and with a flexible prioritised task system running underneath that :)
|