| |
ChristopherJam
Registered: Aug 2004 Posts: 1403 |
SEI considered harmful.
Once more for the people at the back:
Don't wrap your interrupt initialisation with SEI/CLI.
It's a bad way to avoid interrupts being dispatched while you're changing the IRQ pointer, because it then requires additional code to acknowledge any pending CIA IRQs that might trigger between the SEI being executed and you turning off the CIA timer or interrupt enable.
If you're coming from BASIC, just do this instead:
lda #$7f
sta $dc0d
..then change $01, set your IRQ pointer(s), and init your own raster and/or timer IRQ(s)
If you're coming from a previous part, ask your teammate to turn off any IRQs and acknowedge any requests before they pass the baton (cf 'IRQ recovery' link below) - then all you need to do is set up your own IRQ.
As previously flogged to death at
TIL: The instruction after SEI can be executed before a pending IRQ is handled
C-64 coding cargo cults
Best practice IRQ recovery |
|
... 36 posts hidden. Click here to view all posts.... |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Quote: y'all make it sound too easy, there's music sync to worry about too, frameskips are fugly.
That’s what you avoid by NOT doing SEI/CLI |
| |
Burglar
Registered: Dec 2004 Posts: 1066 |
Quote: That’s what you avoid by NOT doing SEI/CLI
yes, but it's not the full story, u dont know when (rasterline) u arrive, so u also dont know if music played this frame or not, there may be multiple irqs.
and u dont want to modify the rasterline the music is playing at too much (or at least not at once). |
| |
Cruzer
Registered: Dec 2001 Posts: 1048 |
Quoting Burglaryes, but it's not the full story, u dont know when (rasterline) u arrive, so u also dont know if music played this frame or not, there may be multiple irqs.
and u dont want to modify the rasterline the music is playing at too much (or at least not at once). Whatcha talking about? Not doing SEI/CLI fixes all this. Just remove SEI/CLI from your code and it automatically becomes a perfectly linked and sync'ed trackmo. :D |
| |
chatGPZ
Registered: Dec 2001 Posts: 11290 |
Just use a proper dubstep soundtrack |
| |
Krill
Registered: Apr 2002 Posts: 2940 |
Is it this time of the year again. But lemme try to add a twist to this very old discussion.
A more or less interesting detail is that when coming from BASIC, the VIC raster interrupt flag is ALWAYS set.
Meaning that when you don't clear the latch by writing a 1-bit to $D019 bit 0, the interrupt will trigger immediately after unmasking it via LDA #1 : STA $D01A.
Take note that a raster interrupt may be flagged in the 3 (or 4?) cycles between clearing the latch and unmasking the interrupt.
I'll stop here and let yous dwell on this for a bit as to what this might or might not mean for timing-sensitive routines like stable-raster clockslides. =) |
| |
Martin Piper
Registered: Nov 2007 Posts: 699 |
I think, in the C64 world, the SEI is there because the IRQ level interrupt can have a trigger that comes from more than one source, it's not just the CIA it's also the VIC, for example.
This means that technically it's not possible to completely stop all IRQ sources with just one store to $dc0d. It's not an atomic operation because you also need to stop the VIC trigger as well.
In theory it could be the case that even if the $dc0d source is disabled in the mainline (outside the IRQ), a raster IRQ could be triggered which then enables the $dc0d source before it returns, which then means a mainline VIC trigger disable would not guarantee the IRQs are really off.
The SEI then basically is an atomic way of guaranteeing that IRQs are stopped before then having to disable their triggers, and acknowledge those potential triggers, before continuing.
Of course this doesn't handle the case when an NMI could enable a raster or CIA IRQ trigger. However at least for NMI triggers then don't happen because of the VIC and their control is via $dd0d. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1403 |
So yes, SEI guarantees atomicity, but that doesn't make a difference coming from BASIC, and while it does defend against the following hypothetical:
Quoting Martin PiperIn theory it could be the case that even if the $dc0d source is disabled in the mainline (outside the IRQ), a raster IRQ could be triggered which then enables the $dc0d source before it returns, which then means a mainline VIC trigger disable would not guarantee the IRQs are really off.
..it doesn't defend against the same hypothetical with dd0d substituted for dc0d - especially if the ISR also overrides RTI restoring I. Really, if a previous part is messing with those sorts of techniques, it needs to shut itself down properly before handing over control to the next part.
Excellent point from Krill about how you really should be acknowledging prior VIC interrupts before you set up your own - I nearly added to my initial post that you should also ensure that your interrupt setup code isn't getting in the way of when you expect your first IRQ to hit too (eg by waiting on $d012 before you start writing to d011/12/19/1a).
And yes, music handover is important if you don't want to fuck with the timing - it's just as important to avoid double calling as it is to avoid frameskip, and either way it's probably a bigger discussion than just "do this magic at init time" (eg, what happens if you need to spend a couple of frames unrolling some code or data? Who is responsible for continuing to play the tune, while not trashing other things?) |
| |
Martin Piper
Registered: Nov 2007 Posts: 699 |
I think for the first part of a multi-part demo, the initial load, boot or whatever, there needs to be a very robust init which would include the "large" SEI/kill stuff/CLI arrangement.
But for all subsequent parts, as long as a IRQ/NMI contract can be agreed, then there doesn't need to be such a robust init. Actually in such situations there might even be sections of memory that are kept consistent with their IRQ/NMI carrying on things like music etc. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1403 |
Yes, basically big productions need team-wide guidelines on handover.
But for simple one-filers or intros? Just poke $dc0d,127, wait for $d012 to go negative, then set up your raster IRQ.
(ok ok, and if you must insist on SEI, don't forget to lda $dc0d after you write to it) |
| |
spider-j
Registered: Oct 2004 Posts: 483 |
Quoting KrillMeaning that when you don't clear the latch by writing a 1-bit to $D019 bit 0, the interrupt will trigger immediately after unmasking it via LDA #1 : STA $D01A.
This here should be okay then – writing #1 to $D019 first, then $D01A:
init_irq: lda irq_lines
sta 0xD012
sta irq_plus_cmp+1
inc irq_plus_cmp+1
lda #<irq
sta 0xFFFE
lda #>irq
sta 0xFFFF
lda #0x0B
sta 0xD011
lda #0x01
sta 0xD019
sta 0xD01A
rts
Or isn't it? |
Previous - 1 | 2 | 3 | 4 | 5 - Next |