| |
Hypnosis
Registered: Mar 2015 Posts: 36 |
Cycles to get into IRQ routine
How many cycles does it take from an IRQ trigger to the start of the IRQ routine, assuming the CPU finished the instruction when it triggers? It should be around 6-9 cycles but I'm not sure how many. |
|
... 53 posts hidden. Click here to view all posts.... |
| |
lft
Registered: Jul 2007 Posts: 369 |
Remember in the movie Magnolia, when the kid is watching as frogs fall from the sky? "This happens. This is something that happens."
Today I had this weird crash that would go away whenever I changed something. I finally tracked it down. My decruncher was reading a bitfield by shifting a byte in memory, in a loop. Something like:
loop
asl memory
rol
dey
bne loop
A raster interrupt occurred during the branch instruction, just like we discussed here, so it was delayed until after the shift instruction. This is the maximum delay if we only use legal opcodes.
Meanwhile, my raster interrupt was moving along with a border sprite, so it happened to be on rasterline 0 at this exact moment. Therefore, the interrupt was first delayed by one cycle (because rasterline 0), and then an additional eight cycles for the bne+asl combo.
The jitter compensation code was reading a timer that is counting down 8,8,7,...,1 that would normally be in the range 1..7, corresponding to the expected range of interrupt latencies. The value is EORed with 7 and stored into a branch instruction followed by a clockslide. The extra latency made the timer return 8; the branch offset became 15 and the program crashed.
As soon as I changed anything, anywhere, the crunched data would come out a little differently, and the interrupt on rasterline 0 wouldn't strike exactly on that Achilles' heel. |
| |
Copyfault
Registered: Dec 2001 Posts: 474 |
Upped my old test prog here: Cycle Jitter TestProg. I have to admit that I was not motivated to include nmi irqs so this still needs a suitable test suite.
Quoting Flavioweb
...
-EDIT-
Seems that 10c jitter only occurs on raster line 0.
In other lines max jitter is 9c.
...
Hmm, in my routine the values read from $dc04 lie between $10 and $17, giving eight different values. In line 0 it's clear that there's another cycle offset, but for the other lines I'm not sure if you really have _nine_ different jitter values??? |
| |
Flavioweb
Registered: Nov 2011 Posts: 463 |
I registered the _nine_ cycles when, using this loop
LOOP
INC $FFFF,X
DEX
BNE LOOP
the first BNE cycle was executed on last cycle of previous raster line where irq is triggered. |
| |
lft
Registered: Jul 2007 Posts: 369 |
Just to establish some common terminology:
Latency: The number of cycles from an interrupt until the first instruction in the interrupt handler starts to execute.
Jitter: The random variation in latency, i.e. the difference between minimum latency and maximum latency.
If minimum latency is equal to maximum latency, the amount of jitter is zero. Thus, if we observe e.g. four different timer values, there is a jitter of three cycles.
Returning to the topic, here's a recapitulation:
The 6502 normally checks for interrupts at the end of the second-to-last cycle of an instruction. The minimum latency is therefore 2 + 7 cycles: two for the two last cycles of the current instruction, and seven to handle the interrupt (push on stack etc.)
If we get the interrupt while executing a stream of nops, as in the double-irq method, the maximum latency is 1 + 2 + 7 cycles: one for the last cycle of the first nop (we just missed the check!), and then as above.
The longest legal instruction is seven cycles (e.g. asl abs,x). If an interrupt happens during the final cycle of the previous instruction, the latency is therefore 1 + 7 + 7 cycles.
So far, we have a jitter of (1 + 7 + 7) - (2 + 7) = 6 cycles.
Now we add the special case discussed in this thread, where a non-page-crossing branch "sticks" to the subsequent instruction (the branch target). Maximum latency is now 3 + 7 + 7, and the jitter becomes 8 cycles.
With illegal opcodes, the longest instruction is 8 cycles. If we also consider the delayed IRQ on rasterline 0 as latency, the total jitter becomes (1 + 3 + 8 + 7) - (2 + 7) = 10 cycles.
That is, we can expect 11 different timer values.
Did I get that right? |
| |
Flavioweb
Registered: Nov 2011 Posts: 463 |
Lft: yep, you're right. |
| |
lft
Registered: Jul 2007 Posts: 369 |
No, hang on. For branch instructions, the interrupt flag is actually checked at the end of the first cycle (but not at the end of the second cycle). So for the worst case, we're only stuck with the last two cycles of the branch. (1 + 2 + 8 + 7) - (2 + 7) = 9 cycles jitter, 10 different timer values. |
| |
Flavioweb
Registered: Nov 2011 Posts: 463 |
Yes.
If second cycle of a taken branch opcode, is executed on cycle zero of a rasterline (first cycle of branch op is on last cycle of previous line), then cycles added to wait for current opcode to finish are 2 from taken branch, plus next opcode cycles.
So, if we have branch opcode + 7 cycles opcode, cpu wait for 2 cycles from branch + 7 cycles from next opcode.
If we are on raster line 0, and first cycle of branch is on first cycle of the line, irq is triggered on cycle 1 so our first irq opcode is far 1 + 2 + 7 + 7 = 17 cycles from first cycle of the line. |
| |
Copyfault
Registered: Dec 2001 Posts: 474 |
Quoting lftJust to establish some common terminology:
Latency: The number of cycles from an interrupt until the first instruction in the interrupt handler starts to execute.
Jitter: The random variation in latency, i.e. the difference between minimum latency and maximum latency.
...
Thanks for giving a proper definition of jitter - I'd even suggest to say jitter value as jitter refers more to the phenomenon itself ;).
To be honest I have been using the term jitter (value) in two different ways: sometimes for the delay until the irq handler starts, which makes sense only for a fixed situation, on other occasions for the difference between the maximal and the minimal occuring latency, which makes sense only when looking at a complete set of situations (e.g. all possible situations).
To distinguish between them I also used current jitter value and maximal jitter value resp., but your definitions suit our needs way better.
Back to the actual jitter values: my tests give
Set of situations jitter value/differnt timer values
-------------------------------------- ----------------------------------
no illegals, raster irq outside line=0 7/8
illegals, raster irq outside line=0 8/9
no illegals, raster irq on line=0 8/9
illegals, raster irq on line=0 9/10
Missing in the list above is the Set of "NMI interrupts IRQ"-situations. Did anyone already have a look at these cases? |
| |
Hypnosis
Registered: Mar 2015 Posts: 36 |
I revisited this topic since I seemed to miscalculate when I was implementing a timer interrupt. I single stepped in Vice to see where the cycles ended up. I have a stable raster interrupt firing a timer A interrupt while executing nop instructions. I use timer B to measure cycles.
What happens in Vice is that
1. timer A wraps around
2. one nop is executed
3. another nop is executed
4. next instruction is now the nmi interrupt's first instruction
What's confusing is that there are 9 cycles between step 3 and 4. If so, why is the first nop executed? |
| |
lft
Registered: Jul 2007 Posts: 369 |
Possibly there is a delay before the CIA generates the interrupt. I believe the old and new CIA versions differ in the details here. |
Previous - 1 | 2 | 3 | 4 | 5 | 6 | 7 - Next |