Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
 Welcome to our latest new user juanjosescg ! (Registered 2024-04-16) 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-12 23:28
TWW

Registered: Jul 2009
Posts: 541
Quoting Copyfault
acknowledging should be in the realm of the irq handler.


Even if you disable new CIA IRQ's from occurring, existing ones isn't cleared and may trigger a premature interrupt.

Simply put:

// You do not know the state of the CIA here
sei
// a CIA interrupt may activate here
lda #$7f
sta $dc0d
sta $dc0d
// CIA maintain the IRQ signal, but don't generate new ones
lda #100
sta $d012 // This is where you want the IRQ to happen
lda #1
sta $d01a
fffe/ffff vetor = IRQ_Code
cli
// latent CIA IRQ triggers here instead of @ line 100
jmp *
IRQ_Code:
blablabla

Avoided by ack'ing the CIAs prior to cli'ing
2021-06-13 00:56
chatGPZ

Registered: Dec 2001
Posts: 11089
we *really* need this rant :)
// switch off irq sources
lda #$7f
sta $dc0d
sta $dd0d
ldx #0
stx $d01a
// whatever irq was pending triggers here and the old handler handles it
// setup irq sources and change pointers
lda #100
sta $d012
lda #$1b
sta $d011
lda #>handler
sta $ffff
lda #<handler
sta $fffe
// perhaps wait for rasterline here to avoid glitching
// enable irq sources
inx
stx $d01a
2021-06-13 02:59
Copyfault

Registered: Dec 2001
Posts: 466
Quoting Groepaz
we *really* need this rant :)
We do, but I won't volunteer as I'm not worthy enough to tickle this sensitive topic!

Quoting Groepaz

// switch off irq sources
lda #$7f
sta $dc0d
sta $dd0d
ldx #0
stx $d01a
// whatever irq was pending triggers here and the old handler handles it
// setup irq sources and change pointers
lda #100
sta $d012
lda #$1b
sta $d011
lda #>handler
sta $ffff
lda #<handler
sta $fffe
// perhaps wait for rasterline here to avoid glitching
// enable irq sources
inx
stx $d01a
Yes, this is the way to do it. Only detail I'm not sure about is when the potentially still pending IRQs might happen: my guess is that the irq acknowledging will still be in place, i.e. any "old" irq routine might be called at different spots.
// switch off irq sources
lda #$7f
sta $dc0d
         //if an irq condition happens before cycle 3 of this opcode, it will be
         //triggered directly after the STA-opcode has been processed...
sta $dd0d
         //...if not, it will take until this 2nd STA-opcode before the irq is triggered
ldx #0
         //same here: any pending IRQs of CIA2 will happen here the latest
stx $d01a
         // whatever irq was pending triggers here...
// setup irq sources and change pointers
lda #100
         //..or here if the raster IRQ condition occured at cycle 3 or 4 of the STX-opcode
[...]

Is this correct or do I mix things up?
2021-06-13 06:33
Martin Piper

Registered: Nov 2007
Posts: 631
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.
2021-06-13 08:48
TWW

Registered: Jul 2009
Posts: 541
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.


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.

    // 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.




@ GPZ: "// perhaps wait for rasterline here to avoid glitching"

Instead, just ack any pending IRQ's and you don't have to wait. Don't overthink it.

Edit: Typos
2021-06-13 10:32
ChristopherJam

Registered: Aug 2004
Posts: 1370
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: 1370
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: 1370
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: 631
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 :)
Previous - 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 - 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
juanjosescg
Bert/RDS
Manex/Anubis
hedning/G★P
TPM/Silicon Ltd
Core/VPN
AnonymousMOS
Guests online: 222
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 Wonderland XIV  (9.6)
9 The Ghost  (9.6)
10 Bromance  (9.6)
Top onefile Demos
1 It's More Fun to Com..  (9.9)
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 Dawnfall V1.1  (9.5)
9 Quadrants  (9.5)
10 Daah, Those Acid Pil..  (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 Musicians
1 Rob Hubbard  (9.7)
2 Jeroen Tel  (9.7)
3 Stinsen  (9.6)
4 Mutetus  (9.6)
5 Linus  (9.6)

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