Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > Cycles to get into IRQ routine
2015-05-20 04:17
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....
 
2015-05-26 19:38
Flavioweb

Registered: Nov 2011
Posts: 463
Quoting Copyfault
if the irq happens on the first cycle of a branch, it will be processed after the second cycle of the branch; but if an irq happens during the second cycle of a branch, processing is delayed until the end of the opcode following the branch instruction.

So, with this code
LOOP
    INC $FFFF,X
    DEX
    BNE LOOP

if an irq happens durng second cycle of BNE, and branch is taken, 2(BNE)+7(INC)=9 cycles are executed before irq and, as a "borderline case of the corner cases", if BNE cross page boundary, 3+7=10 cycles are executed.
I'm wrong?
(Ok... i know we all need to avoid boundary cross... and probably no one use a INC $FFFF,X... but it's just to see if my thoughts are correct.)
2015-05-26 20:28
Oswald

Registered: Apr 2002
Posts: 5094
"if irq is triggered on first cycle of BNE, then BNE + INC are executed before CPU starts irq sequence..."

this still doesnt seem to make sence. last cycle of bne will check forr irq condition, if bne finished then cpu jmps to irq, or why not ?
2015-05-26 20:30
Copyfault

Registered: Dec 2001
Posts: 478
@Flavio: I remember there was a different behaviour when that branch was pagecrossing.

No pagecrossing, branch taken, irq on 2nd branch cycle (marked with <>):
next op.....cycles
BNE (taken) [R=1st branch cycle]<R=2nd branch cycle>[R=add.cycle]
INC abs,X   [R=1st INC cycle][2][3][4][5][6][7]
<irq processing starts here>


Same with pagecrossing:
next op.....cycles
BNE (taken) [R=1st branch cycle]<R=2nd branch cycle>[R=add.cycle for branch taken][R=add.cycle for pagecrossing]
<irq processing starts here>


There was this explanation with socalled "opcode fetch cycles" that do not allow irq acknowledging and that an irq is not processed before it was acknowledged. Having a pagecrossing situation, the first additional branch cycle belongs to those opcode fetch cycles whereas the next additional cycle for the page crossing does not; thus, it results in less jitter.
2015-05-26 20:36
Flavioweb

Registered: Nov 2011
Posts: 463
Quoting Oswald
last cycle of bne will check for irq condition, if bne finished then cpu jmps to irq, or why not ?

If branch isn't taken, last cycle is the second, if branch is taken, last cycle is the third (or the fourth if the page boundary is crossed)...
maybe that's the "problem" ...
2015-05-26 21:52
MagerValp

Registered: Dec 2001
Posts: 1078
Quoting Oswald
this still doesnt seem to make sence. last cycle of bne will check forr irq condition, if bne finished then cpu jmps to irq, or why not ?


Branches are special. Normally IRQs are evaluated before the last cycle, which for an untaken branch is the second cycle. When branches are extended to three cycles as they are taken, or four cycles when taken across a page boundary, the IRQ evaluation at the second cycle still triggers the IRQ.

I wonder if this is true also for other instructions that are extended on page crossing, such as LDA $FFFF,X.
2015-05-27 05:11
Oswald

Registered: Apr 2002
Posts: 5094
okay, so IRQ is triggered, but not taken until BNE ends? or IRQ is taken at 2 cycle of a 4 cycle BNE, then how does the CPU find its way back to the middle of the BNE ? I dont think this latter one happens.

what exactly happens when an IRQ is evaluated ? I still dont get it how irq could be delayed to happen after the next instruction after the BNE, if it happens during a BNE.
2015-05-27 06:55
Flavioweb

Registered: Nov 2011
Posts: 463
I suppose that BNE "decides" to execute next op during his second cycles, but as copyfault stated, additional cycles are "added" later... so cpu execute added operations then execute next op, like if irq is triggered on second as last cycle of bne.
2015-05-27 10:09
lft

Registered: Jul 2007
Posts: 369
I think the key is to ask: Why is the interrupt inhibited during the second tentative opcode fetch, but not during the first?

That is, on a 4-cycle branch, we're performing two speculative opcode fetches before the third (correct) fetch. It appears that the first speculative fetch can be replaced with a BRK/IRQ (so the interrupt immediately follows a 2-cycle branch-not-taken). The third fetch can also be replaced (so the interrupt immediately follows a 4-cycle branch with page crossing). But the second is inhibited.

I think the answer has to do with how the PC register is updated. It can be incremented in a single cycle, or it can be loaded through the ALU in one or two cycles depending on whether there is a carry. The interrupt mechanism needs to push PC to the stack.

During a normal fetch, the PC reflects the value that needs to be pushed, so if the fetch is replaced with a BRK, we can presumably also inhibit the normal increment, and write the PC to the stack.

During the first tentative fetch, the PC also reflects the value that needs to be pushed if the branch is not taken---which we know at this point.

But during the second tentative fetch, the PC could be wrong. We have already written the PC LSB, so there's no way to go back; we have to do the carry-adjust (if ALU reports a carry). Thus, we cannot at this point push the PC to the stack. Actually, we could, but we'd have to take the carry signal from the ALU into consideration. I think, quite simply, that the design team were cutting corners here, and saving silicon by leaving out that special case.

So it boils down to this: We cannot divert an opcode fetch that follows a 3-cycle branch-taken, because we don't know yet whether this is a 4-cycle branch. And thus we could potentially be pushing an invalid return address.

But what about an infinite branch-to-self? Surely it can be interrupted? Has anybody investigated?
2015-05-27 10:23
MagerValp

Registered: Dec 2001
Posts: 1078
What? No, the branch doesn't get split in two. Evaluation, that is whether an IRQ should be acted on, is separate from triggering. They don't happen at the same time. Roughly speaking IRQs and NMIs just force the CPU to execute a BRK instruction instead of the next opcode. The point is that IRQ evaluation happens one cycle earlier than what most programmers and emulator writers expect, and in the case of branch instructions even earlier in some cases.
2015-05-27 10:31
lft

Registered: Jul 2007
Posts: 369
@MagerValp: I'm not sure if that was a response to my post, but here's what's confusing: Consider a 4-cycle branch. After fetching the branch opcode and the branch offset, there are three cycles in which the next opcode is fetched. The first two are thrown away. Of these three cycles, it appears that the first and the third can be diverted to interrupt handling (BRK). So there's a conspicuous gap in the middle, which cannot be explained simply by saying that the evaluation happens at some specific time.
Previous - 1 | 2 | 3 | 4 | 5 | 6 | 7 - Next
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
LordCrass
pcollins/Quantum
Guests online: 83
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 Edge of Disgrace  (9.6)
6 What Is The Matrix 2  (9.6)
7 The Demo Coder  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 No Listen  (9.6)
2 Layers  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 Dawnfall V1.1  (9.5)
7 Rainbow Connection  (9.5)
8 Onscreen 5k  (9.5)
9 Morph  (9.5)
10 Libertongo  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Triad  (9.3)
5 Censor Design  (9.3)
Top NTSC-Fixers
1 Pudwerx  (10)
2 Booze  (9.7)
3 Stormbringer  (9.7)
4 Fungus  (9.6)
5 Grim Reaper  (9.3)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.04 sec.