| |
ChristopherJam
Registered: Aug 2004 Posts: 1402 |
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.... |
| |
spider-j
Registered: Oct 2004 Posts: 481 |
Can this happen to CIA2 NMI too? In the latest version of my framework I switched to that for playing music to get rid of the "SEI problem".
Of course: you can break it by pressing RESTORE. But are there any sideeffects without user interaction that can happen, once you setup the timer for a PAL frame? |
| |
Krill
Registered: Apr 2002 Posts: 2940 |
Quoting spider-jCan this happen to CIA2 NMI too? In the latest version of my framework I switched to that for playing music to get rid of the "SEI problem".
Of course: you can break it by pressing RESTORE. But are there any sideeffects without user interaction that can happen, once you setup the timer for a PAL frame? What is the SEI problem, specifically?
And playing regular music (no samples) via NMI? Dunno, i'd rather prefer restore-proof blocked NMI. =) |
| |
spider-j
Registered: Oct 2004 Posts: 481 |
Quoting KrillWhat is the SEI problem, specifically
My group mates ignoring the "coding guidelines" ;-) And I must admit, after switching to the NMI solution I also found everything easier to handle. You can just do with raster IRQs what you want to do and yes there is a NMI "somewhere" that will steal you cycles but it is way easier to handle than let's say moving your IRQ lines for one effect and caring about the music (avoiding frame drops or too long player call "distances"). Yeah of course the user can destroy that by pushing RESTORE, but after all tests I did even if your NMI is nothing more than "RTI" mindlessly hitting RESTORE will make problems anyway. So I decided that pressing RESTORE shouldn't be considered a "real use case". |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1402 |
A few minor points.
Firstly, my understanding is that NMIs can be prevented altogether (like, not even the single byte RTI called) if you just trigger an NMI from CIA#2 and never acknowledge it. Not something I've ever bothered with, but it's a solid option.
Secondly, minor quibble about the comments here:
lda #0x01
sta 0xD019
; ... may trigger here
sta 0xD01A
; ... is ack'd here
rts ; ... next opcode is ececuted
; ... and irq routine starts here
The write to d019 clears the latch ('acknowledges' previous raster matches), d01a enables interrupts, doesn't acknowledge.
But yes, Copyfault is correct - going to read TIL: The instruction after SEI can be executed before a pending IRQ is handled properly I see that I missed the tail end of the discussion last time round, and it indeed confirms my experiments from yesterday. Even if the interrupt condition latch is already set, the instruction after the write to $d01a is still executed before the interrupt occurs.
(for a hot minute I thought Copyfault was erroneously drawing a connection between the post-SEI prefetch and the $d01a thing, but I was just misled by that other post changing topics partway down the page. My bad.) |
| |
oziphantom
Registered: Oct 2014 Posts: 488 |
when doing the initial set up and not a 4K/16K release I just clobber everything
ClearInterupts .macro
sei
lda #$7f
sta $dc0d ;turn off all types of cia irq/nmi.
sta $dd0d
lda $dc0d
lda $dd0d
lda #$00
sta $D01a
lda #$ff
sta $D019
sta $dc0e
sta $dc0f
sta $dd0e
sta $dd0f
lda $d01e
lda $d01f
.endm
But then I also make my code C64 and C128 compatible, the C128 doesn't use the CIA timer but actually uses the VIC Raster. But also read the Sprite collision values to clear and event on them, as sometimes d015 can be set by some menus, other tools and then you move the screen and VIC bank you can get some random collision triggers. Well okay it happened to me once, but eh never again...
The nice thing about SEI is it lets me set up the rasters I want at any point in the code and then CLI when it is ready for primetime without having to think about where and when I init things. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1402 |
Nice "clobber all the things" there, oziphantom.
Quoting oziphantom
The nice thing about SEI is it lets me set up the rasters I want at any point in the code and then CLI when it is ready for primetime without having to think about where and when I init things.
Wait, doesn't that mean that your first raster interrupt can occur on the wrong line? (eg if you set up the rasters, then spend a frame doing some other init stuff, then do the CLI on some other line than the one where the interrupt should happen) |
| |
oziphantom
Registered: Oct 2014 Posts: 488 |
yeah but that generally isn't a massive problem, GoatTracker takes 4 frames to warm up music etc. Maybe the colour splits will be wrong for part of a frame etc But having it fire in the middle of initing the SID routine for example could potentially be a disaster. Or if on the 128 with the wrong ZP and SP register a total disaster. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11281 |
As for "clobber all the things" - in trackmo startups i also had disabling of AR and FC3 - as those can cause weird shit too (due to longer system irq). |
| |
Copyfault
Registered: Dec 2001 Posts: 468 |
Quoting ChristopherJam[...]
Secondly, minor quibble about the comments here:
lda #0x01
sta 0xD019
; ... may trigger here
sta 0xD01A
; ... is ack'd here
rts ; ... next opcode is ececuted
; ... and irq routine starts here
The write to d019 clears the latch ('acknowledges' previous raster matches), d01a enables interrupts, doesn't acknowledge. Oh my bad! Yes, I fooled around with the wording and "ack'ing" is indeed done by writing to $D019, while setting $D01A serves as an IRQ-enabler. Thanks for putting that straight!
Quoting ChristopherJamBut yes, Copyfault is correct - going to read TIL: The instruction after SEI can be executed before a pending IRQ is handled properly I see that I missed the tail end of the discussion last time round, and it indeed confirms my experiments from yesterday. Even if the interrupt condition latch is already set, the instruction after the write to $d01a is still executed before the interrupt occurs.
(for a hot minute I thought Copyfault was erroneously drawing a connection between the post-SEI prefetch and the $d01a thing, but I was just misled by that other post changing topics partway down the page. My bad.) No, no, it was just me being confused why the IRQ should start _before_ the following opcode is executed, but my world's order has just been reinstated ;)
Quoting KrillQuoting Copyfault[...]? Thought this was the "result" of the TIL: The instruction after SEI can be executed before a pending IRQ is handled thread, no? In post #99 of this thread MagerValp linked the testprog I have in mind. Maybe. But that would just underline my point. =) Yes, it indeed does :) |
| |
Perplex
Registered: Feb 2009 Posts: 255 |
You don't SEI! https://www.youtube.com/watch?v=hyMM8WP5XFk |
Previous - 1 | 2 | 3 | 4 | 5 - Next |