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 > Best practice IRQ recovery
2021-06-10 20:30
Trap

Registered: Jul 2010
Posts: 222
Best practice IRQ recovery

Hi,

Here's a little newbie question. Sorry, I'm still learning this shit and it's really complicated :(

I have kernel off ($01=$35) and I am running IRQ's using the normal $fffe/$ffff vectors.
I want to exit from this and call a prepacked piece of code (in this case something packed with TinyCrunch).

I tried restoring the IRQ vectors and jump to the packer. However, it just hangs. I tried some other things but all gave the same result. The only thing that worked was when I did this:

sei
lda #$36
sta $01
jsr $ff81
jmp unpacker

The problem of course is that it resets the VIC which isn't really great for my situation.

So, my question:

What is the correct/proper way to exit from a part and go to the next? preferably not using kernal routines :|

Thank you.

Trap
 
... 78 posts hidden. Click here to view all posts....
 
2021-06-13 10:32
ChristopherJam

Registered: Aug 2004
Posts: 1378
so, the following would work, but it's hella overengineered.

Quoting TWW
Yes!
    // Unknown state of VIC/CIA
    sei
    ldx #0
    stx $d01a
    lda #$7f
    sta $dc0d
    sta $dd0d
    cli
    // IRQ May happen here if one was triggered between the SEI and the write to the IRQ reg to diasble them.

Given that you're still allowing the triggered IRQ to go ahead, the only effect of wrapping the above in SEI/CLI is that you're potentially delaying the response to the IRQ to after
the write, hence giving the IRQ handler an opportunity to undo it.

Quote:
    // Unknown state of VIC/CIA
    sei
    lda #0
    sta $d01a
    lda #$7f
    sta $dc0d
    sta $dd0d
    lda $dc0d
    lda $dd0d
    lda #1
    sta $d019
    cli
    // No URQ can trigger now from VIC/CIA.


^the entire sequence of re-disabling CIA interrupts and acknowledging any that occured is only required in this section because you wrapped the first section in SEI/CLI
2021-06-13 10:39
ChristopherJam

Registered: Aug 2004
Posts: 1378
Quote: If there was code running that used two or more interrupt sources to operate correctly, then using SEI/CLI would be advisable. This is because the code below without SEI/CLI is not atomic:

lda #$7f
sta $dc0d
sta $dd0d
ldx #0
stx $d01a


In other words, there are a few cycles between switching off IRQ source from CIA1, CIA2 and VIC2 where such complex code could misbehave, say for example by enabling the source in the IRQ that you've just switched off.

So using SEI/CLI is the correct bullet proof way of tackling that issue.


The sequence doesn't need to be atomic.

Interrupts could occur before you enter the sequence regardless of whether the sequence itself is wrapped, and leaving the I flag clear just allows them to occur as late as just before the instruction performing the write.

Once the write occurs however, as long as you *didn't* execute an SEI, no CIA interrupts will occur afterwards.

And if you're concerned about a VIC interrupt reenabling your CIA interrupt, then wrapping that your code with SEI/CLI will only defer that to the end of the section; it does nothing to protect you against that.
2021-06-13 10:50
ChristopherJam

Registered: Aug 2004
Posts: 1378
argh, damn it. Give the possibility of "some other coder's VIC interrupt setting up a CIA interrupt or vise versa" I might actually need to reconsider my stance.

How hostile an environment do I want to guard against is the question I guess..
2021-06-13 10:59
Martin Piper

Registered: Nov 2007
Posts: 634
For the cost of two bytes SEI/CLI pair to handle all the hostile cases, I'd say it was reasonable.
I might even switch of the CIA2 source first, then CIA1. To handle NMIs.
2021-06-13 11:31
TWW

Registered: Jul 2009
Posts: 541
Quote: For the cost of two bytes SEI/CLI pair to handle all the hostile cases, I'd say it was reasonable.
I might even switch of the CIA2 source first, then CIA1. To handle NMIs.


Better yet, ground the NMI if you're not using it;

    lda #<NMI_Lock
    sta $fffa
    lda #>NMI_Lock
    sta $fffb       // Set NMI Vector to point to RTI
    ldx #$00
    stx $dd0e       // Stop CIA #2 Timer A
    stx $dd04
    stx $dd05       // Set CIA #2 Timer A to 0 cycles
    inx
    stx $dd0d       // Enable CIA #2 Timer A as NMI source
    lda #$81
    sta $dd0e       // Start Timer A and trigger NMI
    bne *+3
NMI_Lock:
    rti


@ CJ: "Given that you're still allowing the triggered IRQ to go ahead, the only effect of wrapping the above in SEI/CLI is that you're potentially delaying the response to the IRQ to after"

If you are fiddling with the IRQ vectors and not having the I-Flag set you're asking for it :)
2021-06-13 12:08
ChristopherJam

Registered: Aug 2004
Posts: 1378
haha, writing to the NMI vector without disabling the pertinent CIA first is just as much asking for it.

SEI is no more effective at disabling otherCIA and VIC than turning off the relevant sources, and if you're *really* concerned about hostile/badly written code I've yet to see anything that would protect against someone using a never-returning once-per-frame NMI that immediately sets up a raster interrupt from scratch before falling into NOPs.

You're still going to be vulnerable right up to the point that you've written to both DC0D and I and there's not much you can do about that.

At some point you need to set some ground rules for the code you're shutting down. So yes, if you want to be tolerant of the preceding part setting enable bits in ISRs, by all means wrap your shutdown code in SEI/CLI. It still won't be ironclad, but it will indeed deal with a few more possibilities.

Alternately, either assume that enabling interrupt sources should only be done at startup, or make it the responsibility of the preceding part to shut down gracefully.
2021-06-13 12:08
Copyfault

Registered: Dec 2001
Posts: 466
Quoting Martin Piper
If there was code running that used two or more interrupt sources to operate correctly, then using SEI/CLI would be advisable. This is because the code below without SEI/CLI is not atomic:

lda #$7f
sta $dc0d
sta $dd0d
ldx #0
stx $d01a


In other words, there are a few cycles between switching off IRQ source from CIA1, CIA2 and VIC2 where such complex code could misbehave, say for example by enabling the source in the IRQ that you've just switched off.
This is what I was pointing at with my last post: an IRQ condition might become fulfilled during the execution of the STORE-opcodes that actually switch off further IRQ triggers by the source the STORE is affecting. The no. of cycles that it'll take to enter the irq routine depends on the cycle this irq condition was fulfilled - and the added comments in the example source code reflect my understanding of this delay.

Quoting Martin Piper
]So using SEI/CLI is the correct bullet proof way of tackling that issue.
I still don't understand why this should be needed. Switching off an IRQ source does just this; no further IRQs should be triggered after the source has been disabled, with the exception of the ones that got triggered while performing the disabling store opcode (see above).

But reading the other posts, I guess I have to ask: where am I wrong?
2021-06-13 12:17
ChristopherJam

Registered: Aug 2004
Posts: 1378
Quoting Copyfault
I still don't understand why this should be needed. Switching off an IRQ source does just this; no further IRQs should be triggered after the source has been disabled, with the exception of the ones that got triggered while performing the disabling store opcode (see above).

But reading the other posts, I guess I have to ask: where am I wrong?


You're not really wrong. The only edge case this misses is when an interrupt triggered by one source reenables interrupts from another source you've already shut down (eg a VIC interrupt setting up a CIA interrupt).
2021-06-13 12:23
Copyfault

Registered: Dec 2001
Posts: 466
Quoting ChristopherJam
argh, damn it. Give the possibility of "some other coder's VIC interrupt setting up a CIA interrupt or vise versa" I might actually need to reconsider my stance.

How hostile an environment do I want to guard against is the question I guess..
Ah ok, if the irq vecs have been changed already and need to be readjusted to some new routine, this might become tricky without SEI/CLI. Not completely impossible, but needs careful planning when the hi/lo-vecs are set.

In my former posts, I had a basic startup situation with its standard irqs in mind...
2021-06-13 12:27
Copyfault

Registered: Dec 2001
Posts: 466
Quoting ChristopherJam
Quoting Copyfault
I still don't understand why this should be needed. Switching off an IRQ source does just this; no further IRQs should be triggered after the source has been disabled, with the exception of the ones that got triggered while performing the disabling store opcode (see above).

But reading the other posts, I guess I have to ask: where am I wrong?


You're not really wrong. The only edge case this misses is when an interrupt triggered by one source reenables interrupts from another source you've already shut down (eg a VIC interrupt setting up a CIA interrupt).
Oh yes! So mixtures of IRQ sources have to be forbidden ;) But this'd narrow the possibilities (and thus the creativity) so I fear the revenge of evil SEI/CLI :(
Previous - 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 - 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
MADMAX
Guests online: 91
Top Demos
1 Next Level  (9.8)
2 Mojo  (9.7)
3 Coma Light 13  (9.7)
4 Edge of Disgrace  (9.6)
5 Comaland 100%  (9.6)
6 No Bounds  (9.6)
7 Uncensored  (9.6)
8 The Ghost  (9.6)
9 Wonderland XIV  (9.6)
10 Bromance  (9.6)
Top onefile Demos
1 It's More Fun to Com..  (9.8)
2 Party Elk 2  (9.7)
3 Cubic Dream  (9.6)
4 Copper Booze  (9.5)
5 Rainbow Connection  (9.5)
6 TRSAC, Gabber & Pebe..  (9.5)
7 Onscreen 5k  (9.5)
8 Wafer Demo  (9.5)
9 Dawnfall V1.1  (9.5)
10 Quadrants  (9.5)
Top Groups
1 Oxyron  (9.3)
2 Nostalgia  (9.3)
3 Booze Design  (9.3)
4 Censor Design  (9.3)
5 Crest  (9.3)
Top Coders
1 Axis  (9.8)
2 Graham  (9.8)
3 Lft  (9.8)
4 Crossbow  (9.8)
5 HCL  (9.8)

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