| |
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.... |
| |
TWW
Registered: Jul 2009 Posts: 541 |
Quoting ChristopherJamhaha, writing to the NMI vector without disabling the pertinent CIA first is just as much asking for it.
Yes, you should disable/ack CIA#2 interrupts first before grounding it / fiddling with the vectors. Here is the full code I use to setup a safe raster IRQ without presuming too much:
sei
// Disable/ack all CIA interrupts
ldx #$7f
stx $dd0d
lda $dd0d
stx $dc0d
lda $dc0d
// Bank in all available RAM except IO
lda #$35
sta $01
// Ground NMI
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
// Set IRQ Vector
lda #<IRQ_Vector.getValue()
sta $fffe
lda #>IRQ_Vector.getValue()
sta $ffff
// Set Raster Interrupt Compare Value
lda #Raster_Compare_Value.getValue()
sta $d012
lda $d011
.if (Raster_Compare_Value.getValue()<256) {
and #%01111111
} else {
ora #$80
}
sta $d011
// Ack any pending Raster Compare IRQs (normally not neccessary)
lda #$01
sta $d019
// Enable Raster IRQs
// lda #$01
sta $d01a
// Allow IRQ's
cli
// async code
async:
jmp async
I consider this as safe as I can make it without making assumptions on what was.
Another important point is that if you are running async. code after the cli (instead of jmp *) you can get straight to that with no hassle and you are sure the VIC IRQ which was setup fires exactly when you told it and not by accident after the cli if some latent CIA IRQ fired (which it may have if you entered from basic). |
| |
chatGPZ
Registered: Dec 2001 Posts: 11108 |
you forgot the second SEI |
| |
Oswald
Registered: Apr 2002 Posts: 5017 |
|
| |
TWW
Registered: Jul 2009 Posts: 541 |
Quoting Groepazyou forgot the second SEI
If a NMI is executed between the SEI and the DD0D disable code, the Processor Status Register (PSR) gets pushed to the stack. When the inevitable RTI is executed the PSR is pulled from stack, the I-flag is restored without the need to set it a second time. |
| |
Trap
Registered: Jul 2010 Posts: 222 |
Wow. This sure sparked a discussion :) I read the thread a few times, but I honestly still don't feel I am any bit closer to knowing how I should deal with my problem?
Thank you all for dishing in - truly wonderful and much appreciated though :) |
| |
chatGPZ
Registered: Dec 2001 Posts: 11108 |
But what if the NMI handler manipulates the Stack? Are you assuming it doesnt? |
| |
Trap
Registered: Jul 2010 Posts: 222 |
I am not using NMI or reading any keyboard presses. Just a normal IRQ running with kernal off ($01=$35). |
| |
chatGPZ
Registered: Dec 2001 Posts: 11108 |
To answer your question we'd still need to know what exactly you are trying to do - there is no universal answer :) |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1378 |
Quoting TrapI am not using NMI or reading any keyboard presses. Just a normal IRQ running with kernal off ($01=$35).
Then you can ignore almost all of the last 50 comments, and just
lda #$7f
sta $dc0d
ldx #0
stx $d01a
no SEI/CLI required. (that said, you do still need to ack the interrupt you're responding to if you do this in an ISR instead of in your main) |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1378 |
Quoting TWWWhen the inevitable RTI is executed
We already covered this - the RTI is not at all inevitable if the interrupt in question is just setting up for another interrupt. |
Previous - 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 - Next |