| |
Krill
Registered: Apr 2002 Posts: 2980 |
TIL: The instruction after SEI can be executed before a pending IRQ is handled
As described here: http://visual6502.org/wiki/index.php?title=6502_Timing_of_Inter..
I never knew this, after all those years, and thought i'd share this as a heads-up.
Thanks to Bubis for pointing it out to me! |
|
| |
Mixer
Registered: Apr 2008 Posts: 452 |
Interesting. Any uses for this? Force NMI timing at stable raster? SEI + delay. |
| |
White Flame
Registered: Sep 2002 Posts: 136 |
The 6502 implemented delay slots before delay slots were cool. ;-) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
well it makes sense 6502 have a kind of prefetch. guess hardwired behaviour doesnt wants to drop the instructions before executed. |
| |
lft
Registered: Jul 2007 Posts: 369 |
This could lead to horrible bugs indeed, if sei/cli are used around critical sections (like Disable/Enable are often used in AmigaOS).
It's kind of neat that when this happens, the status register gets pushed with the I bit set. That way, RTI will correctly restore an environment in which interrupts are disabled. |
| |
doynax Account closed
Registered: Oct 2004 Posts: 212 |
Yet an RTI leaving the IRQs unacknowledged does not single-step. Evidently there is either or two cycles of pipelining involved.
I wonder though, is it possible to prove one cycle of latency in the mask register short of cheating with visual6502? Which of the PLP read cycles is the dummy one?
Incidentally this is common a number of architectures and the reason why interrupt barriers exist. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Wait, so if I understand that correctly if I have
SEI
{instruction1}
{instruction2}
it's possible to get an interrupt *between* instructions one and two?
That could be Bad :(
Thanks for the heads up. |
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
So, always nop after sei? :) |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Eh, anything that doesn't access any memory outside the instruction stream should be fine.
Though if you're being really evil one might have to also remember to avoid using your interrupt handler to modify the instruction immediately following the SEI... |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
yet another reason to forget this cargo cult of putting sei/cli around raster irq setup :) |
| |
MagerValp
Registered: Dec 2001 Posts: 1078 |
I think you're reading the trace wrong. The next instruction following an SEI can be fetched, but not executed if an IRQ occurs during the SEI. The instruction will be re-fetched and executed following the RTI.
And yes, protecting IRQ setup with SEI/CLI is still wrong, but not for this reason :) |
| |
Dano
Registered: Jul 2004 Posts: 234 |
Quote: I think you're reading the trace wrong. The next instruction following an SEI can be fetched, but not executed if an IRQ occurs during the SEI. The instruction will be re-fetched and executed following the RTI.
And yes, protecting IRQ setup with SEI/CLI is still wrong, but not for this reason :)
Sorry for being offtopic there, but why is putting the IRQ setup into SEI/CLI wrong? Doesn't this ensure that no IRQ is happening while setting up the shizzle? I am happy to be enlighted on how to do this correctly. |
| |
TWW
Registered: Jul 2009 Posts: 545 |
Quote: Sorry for being offtopic there, but why is putting the IRQ setup into SEI/CLI wrong? Doesn't this ensure that no IRQ is happening while setting up the shizzle? I am happy to be enlighted on how to do this correctly.
What he said |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Quoting MagerValpI think you're reading the trace wrong. The next instruction following an SEI can be fetched, but not executed if an IRQ occurs during the SEI. The instruction will be re-fetched and executed following the RTI.
Ok, that makes a lot more sense. |
| |
MagerValp
Registered: Dec 2001 Posts: 1078 |
SEI doesn't prevent IRQs from happening, it just stops the CPU from handling them. Odds are good that you have a pending IRQ when you CLI, which means you have to have extra setup code to clear that. So for your generic $080d setup code, simply do
lda #$7f
sta $dc0d before setting up a raster IRQ instead of using SEI. |
| |
lft
Registered: Jul 2007 Posts: 369 |
Quoting MagerValpI think you're reading the trace wrong. The next instruction following an SEI can be fetched, but not executed if an IRQ occurs during the SEI. The instruction will be re-fetched and executed following the RTI.
That makes more sense indeed. The status register will still be pushed with I set, but the interrupt handler is called between the SEI and the following instruction. Phew! |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: SEI doesn't prevent IRQs from happening, it just stops the CPU from handling them. Odds are good that you have a pending IRQ when you CLI, which means you have to have extra setup code to clear that. So for your generic $080d setup code, simply do
lda #$7f
sta $dc0d before setting up a raster IRQ instead of using SEI.
you also need lda $dc0d to clear the pending irq, lda #$7f.. just stops more to happen. afaik.
lda #$7f
sta $dc0d
sta $dd0d
lda $dc0d
lda $dd0d
to be on the safe side. |
| |
lft
Registered: Jul 2007 Posts: 369 |
Yes, but the point is that if you do
lda #$7f
sta $dc0d
before turning off interrupts, then you don't have to clear the flag. If there is an interrupt pending, it will be invoked right now, once. Then it will be off.
On a side note, there is no need to disable CIA2 interrupts (NMI) at the beginning of a program that is launched from BASIC. They aren't active in that environment. |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Quoting MagerValpI think you're reading the trace wrong. The next instruction following an SEI can be fetched, but not executed if an IRQ occurs during the SEI. The instruction will be re-fetched and executed following the RTI. You're probably right, that makes a lot more sense. The text on visual6502.org is a bit ambiguous.
Oswald: I guess it's safe to assume that previously installed interrupt handlers would acknowledge their IRQs until you disable them. So don't exchange one cargo cult for another. :)
But anyhow, SEI/CLI is required when you install interrupt hooks on top of pre-existing handlers, especially if you have no knowledge of which interrupts are currently active and shall remain so. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
ah right, my eye didnt catch the instead :)thanks. |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Quoting lftOn a side note, there is no need to disable CIA2 interrupts (NMI) at the beginning of a program that is launched from BASIC. You do, however, want to trigger one NMI that you never acknowledge, so the pesky restore key won't disrupt your meticulously hand-crafted timing. :) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
I dont care about restore, if the user wants to crash the demo let it be. its his own fault :) |
| |
lft
Registered: Jul 2007 Posts: 369 |
The enemy (nmi?) cannot push RESTORE if you disable his hand. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:I dont care about restore
i've switched to just pointing the NMI vectors to some silly routine that punishes the bastard who pressed RESTORE accordingly :) |
| |
TWW
Registered: Jul 2009 Posts: 545 |
Ground the fucker ^^ |
| |
MagerValp
Registered: Dec 2001 Posts: 1078 |
For reference, here's a bog standard raster IRQ setup that'll work every time if run from basic:
lda #$7f
sta $dc0d
lda #$35
sta $01
lda #$1b
sta $d011
lda #$fa
sta $d012
lda #<irq
sta $fffe
lda #>irq
sta $ffff
lda #1
sta $d019
sta $d01a
NB: Clearing pending IRQs with $d019 is not strictly necessary if you run from a freshly reset machine (the kernal writes $0f to $d019 on reset), but if something else ran before and exited to the basic prompt there may be an unacknowledged raster IRQ pending. |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Quoting MagerValpbut if something else ran before and exited to the basic prompt there may be an unacknowledged raster IRQ pending. Hmm, if whatever ran before left unacknowledged interrupts behind, wouldn't they trigger time and again without ever being acknowledged, so the BASIC prompt would never be reached and IRQs be handled in an endless loop? :) |
| |
MagerValp
Registered: Dec 2001 Posts: 1078 |
No, they're still masked by a zero value in $d01a. Hmm, I wonder if the soft reset before the ready prompt clears it... Just checked, and afaict, nope. |
| |
iAN CooG
Registered: May 2002 Posts: 3193 |
" if run from basic "
and what about if it's not? Why even assuming it? It's not better to be safe and put ALSO sei/cli, and clearing $D019 too in any case? |
| |
MagerValp
Registered: Dec 2001 Posts: 1078 |
Clearing $d019 is necessary, and testing a bit more it seems like it's necessary even on a freshly reset machine. SEI/CLI is still useless though, and only creates the problem of having to clear $dc0d. |
| |
Stone
Registered: Oct 2006 Posts: 172 |
Quoting iAN CooG" if run from basic "
and what about if it's not? Then you either know about the calling context and set things up accordingly, OR you know nothing, in which case initial setup is the responsibility of the caller. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Quoting MagerValpFor reference, here's a bog standard raster IRQ setup that'll work every time if run from basic.
and if you also zero $d01a at the start of the routine, it should then behave itself if your predecessor left a raster interrupt installed :) |
| |
MagerValp
Registered: Dec 2001 Posts: 1078 |
Quote: Quoting MagerValpFor reference, here's a bog standard raster IRQ setup that'll work every time if run from basic.
and if you also zero $d01a at the start of the routine, it should then behave itself if your predecessor left a raster interrupt installed :)
You wouldn't even be able to load stuff from disk with a raster IRQ running, so I don't think it's necessary for account for that. |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
You can load fine from disk using KERNAL routines, with a raster IRQ running. You just need to do it right. And it loads even slower, of course. :) |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
64er mag had some example for this.... it was slooooooooooow =) |
| |
MagerValp
Registered: Dec 2001 Posts: 1078 |
It's also possible to press restore while running, and to use SD2IEC. If you set yourself up for failure, don't be surprised when you fail :) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: Clearing $d019 is necessary, and testing a bit more it seems like it's necessary even on a freshly reset machine. SEI/CLI is still useless though, and only creates the problem of having to clear $dc0d.
relying on things that are not under your control is usually a bad idea. (machine is in an after reset state). this is much more of a cargo cult, than using SEI/CLI. |
| |
Bitbreaker
Registered: Oct 2002 Posts: 508 |
After all, why bother about those few wasted bytes, where's the highly optimized demo parts? :-D How can this behaviour finally be misused? By having the upcoming instruction of the SEI on a register being read or not? |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Since the succeeding opcode is merely fetched, and not executed, then the pipeline flushed and the interrupt handled, then the opcode re-fetched and finally executed...
I can only imagine some arcane anti-cracking/debugging/reverse-engineering setup there, nothing demo-worthy. |
| |
TWW
Registered: Jul 2009 Posts: 545 |
Morale of the story is:
SEI/CLI your init. take care of unwanted IRG/NMI events from smegging up your shit. Let the byte optimizers optimize^^ |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Quoting TWWMorale of the story is:
SEI/CLI your init.
You appear to have forgotten the word "don't"
Just use MagerValp's routine from comment 26, and you'll be fine. SEI/CLI does nothing but create a problem that requires additional handling. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Quoting KrillSince the succeeding opcode is merely fetched, and not executed, then the pipeline flushed and the interrupt handled, then the opcode re-fetched and finally executed...
I can only imagine some arcane anti-cracking/debugging/reverse-engineering setup there, nothing demo-worthy.
Yes, you'd have to be running code stored in read-sensitive IO registers, at the precise cycle an IRQ is expected. I find it hard to imagine any kind of scenario where that would save you any cycles or memory. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: Quoting TWWMorale of the story is:
SEI/CLI your init.
You appear to have forgotten the word "don't"
Just use MagerValp's routine from comment 26, and you'll be fine. SEI/CLI does nothing but create a problem that requires additional handling.
good luck with that when an irq midst your interrupt setup interferes with your initialization. |
| |
lft
Registered: Jul 2007 Posts: 369 |
The only interrupt source that is enabled at program start is CIA1. And we disable all CIA1 interrupts. So where would the interference come from again? |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: The only interrupt source that is enabled at program start is CIA1. And we disable all CIA1 interrupts. So where would the interference come from again?
assumption is the root of all bugs. if you change enviroment you're facing hrs of debugging until you find the faulty non sei/cli irq setup, that relies on having the system in a known state. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
anyhow I realise this is a religious argument, everyone should just do it as he likes. doesnt really matter. |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Oswald, if there's a source you don't know about to disable, you're going to have bugs regardless of whether you SEI/CLI or not, as it's going to hit while your code isn't expecting it.
And if you do know about it, you can disable it, in which case an SEI before you disable it will create extra work for you, or an SEI after you disable it will do nothing.
Either way all you are doing is adding extra bytes to your init code with zero improvements to reliability.
It may even cause your raster interrupt to have it's first occurrence on the wrong line altogether, which can occasionally produce a frame of garbage at the start of your routine. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:Yes, you'd have to be running code stored in read-sensitive IO registers, at the precise cycle an IRQ is expected. I find it hard to imagine any kind of scenario where that would save you any cycles or memory.
it could be a fun riddle for obfuscation though :) |
| |
ChristopherJam
Registered: Aug 2004 Posts: 1409 |
(actually scratch that "it may even" para from the end of my last comment, I didn't quite think that one through - if a CIA interrupt goes off during setup unacknowledged, the consequences are going be considerably worse than a single frame...) |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Quoting Oswaldthis is a religious argument This may be an academic discussion (unless you need the size, 4K and all), but it's certainly nothing to do with religion. Well, unless you are a cargo cultist. :) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
"Either way all you are doing is adding extra bytes to your init code with zero improvements to reliability."
An IRQ may destroy A while you try to lda #$7f sta $dc0d. another irq from the other CIA may re-enable $dc0d. You may have interrupt sources from VICII too, fucking you up in all sorts of ways. (rewriting fffe/f after you've set them up for example).
"if there's a source you don't know about to disable, you're going to have bugs regardless of whether you SEI/CLI or not, as it's going to hit while your code isn't expecting it."
you may just forget about your super size effective irq setup and it will backfire when you least expect it. |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Now you're grasping at straws. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: Now you're grasping at straws.
Now you're trolling. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
anyhow I have real machine experience when I've been setting up raster irq without acking timer interrupt for ages, and then at a case it refused working, and I wondered how could I forget to set it up correctly. Since then I religiously ack it. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:An IRQ may destroy A while you try to lda #$7f sta $dc0d
in that case you have much bigger problems than anything discussed here |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
And we are discussing interrupt setup when run from a plain BASIC environment. So disabling CIA1 interrupts is enough, no SEI/CLI required. Period. :) |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
even in most other scenarios... eg in a trackmo you pretty much want to always do it at a very defined point to avoid glitches - and then you exactly know what happens anyway, and dont need sei/cli at all. you DO need them only when you do brute force AEG style linking =) |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
Okay. I'll always try to make sure to remember to use SEI/CLI then. |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
Ha ha |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
"and then you exactly know what happens anyway"
yeah, until you dont and start having bugs, which is always the case.
Suprised by Gunnar's hatred towards doing it the >right< way, having seen his overly pedantic sources. As a rule of thumb you dont want to rely on things being in a certain state when programming. |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Quoting Oswaldhatred towards doing it the >right< way, having seen his overly pedantic sources. "Hatred" is too strong a word in this context, and the flip side of pedantry is that unnecessary bytes also cause that certain itch. :)
And as for "right", again, either you come from BASIC, in which case there only is CIA1 interrupt to worry about, or you don't, in which case all bets are off and you're doing whatever specific stuff needs doing, with or without SEI/CLI. |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Oh, and when assuming that some people run demos from a BASIC environment with all kinds of interrupts enabled, you can still disable all of them without SEI/CLI.
Unless its a truly hostile environment with interrupt handlers destroying register contents and setting up other interrupts, etc., as you describe, then
i dunno, the people running those don't deserve a demo treat. :) |
| |
Copyfault
Registered: Dec 2001 Posts: 478 |
I think Oswald is basically right here as he's just applying Murphy's Law to the coding of IRQs and their setups.
Then again, once you start optimizing (which is what C64 demo coding is all, no?) it's absolutely right to track down every unnecessary byte or cycle - even if it "feels odd" at first. Have also been using SEI/CLI ever since but I'm really happy and thankful to be enlightened by this discussion.
Just my 2c... |
| |
Copyfault
Registered: Dec 2001 Posts: 478 |
Hmm, upon further thinking, a basic raster IRQ setup could be done even shorter.
After basic start just switch to RAM
start:
lda #$34
sta $01
...
main:
<calculations done on irq-level=0>
...
and place the actual init routine @$ff48 in RAM:
$ff48
lda #$7f
sta $dc0d
lda #<irq
sta $fffe
lda #>irq
sta $ffff
etc.
So the CIA1-irq is misused for the init routine, which itself sets up everything as needed (and will ofcourse only be called once). It however assumes that (at least on irq-level=0) the cpu sees only RAM, i.e. that I/O is switched off there (which is how I always do it, i.e. having $01=$34 in level 0 and $01=$35 for higher irq-levels).
Or are there other traps I fail to see atm? |
| |
Copyfault
Registered: Dec 2001 Posts: 478 |
...aehmm..
must ofcourse be
$ff48
!!inc $01!!
lda #$7f
sta $dc0d
...
|
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Hmm, what does that setup from timer IRQ save? I don't see the shortening (and you'd also have to ack the IRQ yourself). :)
And please explain your notion of "irq-levels". How many are there? Are interrupt handlers themselves interrupted? Are there more banking settings than all-RAM ($30/$34) for main loop and with IO ($35) for interrupt handlers? Something going via $0314/15? |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:yeah, until you dont and start having bugs, which is always the case.
i know its useless to explain, but: mindlessly doing sei/cli and not thinking about when to do it and how to enable/disable the interrupts and their sources is what creates the bugs, not omitting it and knowing what to do. as a matter of fact, that kind of nonsense gave me a lot of headache in a certain demo i linked from parts made by a coder with the same mindset - and the whole "trick" to make it work flawless and bugfree was removing this sei/cli style interrupt setups and move them where they belong - and when they happen at the right time there is simply no need for sei/cli anymore (granted, it doesnt hurt either. however still doing it equals writing 0 to $d020 at random places, just to be sure the border is still black). |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Quoting Groepazwriting 0 to $d020 at random places, just to be sure the border is still black Which then produces grey dots all over the place on many VICs, another pet peeve of mine! :) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Groppie, except your bugs werent caused by the sei/cli pair, but the irq setup wasnt timed correctly. and the bugs could have been even worse if those irq inits were interrupted by the raster irqs. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
again, let me write it in bold for you:
IF the IRQ setup had been timed correctly THEN SEI/CLI would not have been required. and Blindlessly using SEI/CLI made it "work" WITH THE BUGS.
and sure, without SEI/CLI the broken setup might have not worked at all. i totally prefer this over halfassed buggy glitchfest however. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
"without SEI/CLI the broken setup might have not worked at all."
thank you. |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
It's not uncommon that bugs cause erroneous behaviour only in the presence of other bugs. Fix only either, and the other lies dormant until some later time, fix both and you win. :) |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
indeed, that sei/cli stuff only masked other - and bigger - problems. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
Quote: It's not uncommon that bugs cause erroneous behaviour only in the presence of other bugs. Fix only either, and the other lies dormant until some later time, fix both and you win. :)
sei/cli wasnt there to fix a bug. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
time for some classic rock |
| |
Copyfault
Registered: Dec 2001 Posts: 478 |
Quoting KrillHmm, what does that setup from timer IRQ save? I don't see the shortening (and you'd also have to ack the IRQ yourself). :) Ah, you're right with that acknowledging of the IRQ which would come "on top".
Quoting KrillAnd please explain your notion of "irq-levels". How many are there? Are interrupt handlers themselves interrupted? Are there more banking settings than all-RAM ($30/$34) for main loop and with IO ($35) for interrupt handlers? Something going via $0314/15? Yes, what did I mean with "irq-level" *questioningmyself*? I just wanted to distinguish between a "level=0" situation which would be code running outside any irq (which usually is the main loop) and a "level>0" situation for code running inside an IRQ. As there is a certain priority among the different IRQ triggers (e.g. NMI beats Raster), one could define the "irq-level" along these priorities; alternatively, an irq-level could also describe the "depth" of the IRQ trigger chain which occurs when an IRQ is triggered on code running inside an IRQ and so on, but...
...but for the case I had in mind, the terms "main loop" and "inside Raster IRQ" suffice, so I better switch to these now. Usually, I have a main loop running and a raster irq set up. I want a clear separation between the memory access: full ram ($01=$34) in the main loop and IO ($01=$35) in the irq code. As there are usually some IO-registers to be initialised during init, I at least need $01=$35 once in the main loop. By misusing the CIA1-irq as stated in one of my former postings I could avoid this and have all IO accesses inside the IRQ.
Which leaves me with a little question. Is it possible to have an IRQ execution directly after the write cycle of that STA $D019?
...
sta $d019
-> irq possible _before_ the next instruction?? <-
dec $01
...
(has influence on the irq code, i.e. wether an INC $01 at the beginning suffices or a LDA#$35:STA$01 is a must -> +2 bytes :/)
Even more benefit would most probably come together when misusing that CIA1-IRQ of the basic startup for init when using timer irqs instead of raster irqs. But I'll stop now, toooo much text already :) |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Quoting CopyfaultIs it possible to have an IRQ execution directly after the write cycle of that STA $D019? [...] (has influence on the irq code, i.e. wether an INC $01 at the beginning suffices or a LDA#$35:STA$01 is a must You ack a possibly pending raster IRQ with the write access to $d019, but any potentially arising subsequent raster IRQ condition should not trigger an actual IRQ before you enable the raster IRQs via $d01a. This will be when you have already set up your IRQ handler, and that one will behave and properly backup and restore $01. So i guess INC $01 works. |
| |
spider-j
Registered: Oct 2004 Posts: 498 |
Quoting Krillbut any potentially arising subsequent raster IRQ condition should not trigger an actual IRQ before you enable the raster IRQs via $d01a.
Do I understand correctly that when setting up a raster IRQ without SEI/CLI the write to $d01a is the "pendant" to CLI?
So according to you guys the correct way (coming from BASIC) would be:
lda #$7f
sta $dc0d
; ...
; do init stuff ( $01 config etc. )
; setup $fffe/$ffff and $d011 / $d012 for raster IRQ
; ...
lda #$01
sta $d01a ; raster IRQ is able to fire after this (?)
?!?
No need for $d019 in this case, is that correct? |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
correct |
| |
TWW
Registered: Jul 2009 Posts: 545 |
Quote: Quoting Krillbut any potentially arising subsequent raster IRQ condition should not trigger an actual IRQ before you enable the raster IRQs via $d01a.
Do I understand correctly that when setting up a raster IRQ without SEI/CLI the write to $d01a is the "pendant" to CLI?
So according to you guys the correct way (coming from BASIC) would be:
lda #$7f
sta $dc0d
; ...
; do init stuff ( $01 config etc. )
; setup $fffe/$ffff and $d011 / $d012 for raster IRQ
; ...
lda #$01
sta $d01a ; raster IRQ is able to fire after this (?)
?!?
No need for $d019 in this case, is that correct?
I guess you could time the raster to trigger at line #$80 and then enable raster IRQs at VSYNC and see if the raster IRQ triggers immediately or only when raster compare = 80.
This should depend on VIC behaviour, and exactly how the internals deal with the IRQ line (i.e. does the IRQ masking override the output or inhibit the input).
Too lazy to test though but should be straight forward. Same question really regarding the CIAs. And I am sure there is someone with inner detailed knowledge who could answer this straight out.
Nevertheless, SEI/CLI your shit or I will break into your house and take a "huge" crap at your can and leave it for you guys and torment your dreams ever after. I mean HUGE crap, not the spiral peewee ones, no a god dam rhino size pile of stinking CRAP!
DO YOU HEAR ME???? |
| |
TWW
Registered: Jul 2009 Posts: 545 |
Ok, that was perhaps a bit much... sorry... lolz |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Quoting spider-jNo need for $d019 in this case, is that correct? If you scroll up a bit to some of MagerValps comments:
Quoting MagerValpClearing pending IRQs with $d019 is not strictly necessary if you run from a freshly reset machine (the kernal writes $0f to $d019 on reset), but if something else ran before and exited to the basic prompt there may be an unacknowledged raster IRQ pending. [...] Hmm, I wonder if the soft reset before the ready prompt clears it... Just checked, and afaict, nope. [...] Clearing $d019 is necessary, and testing a bit more it seems like it's necessary even on a freshly reset machine. |
| |
spider-j
Registered: Oct 2004 Posts: 498 |
Quoting KrillIf you scroll up a bit to some of MagerValps comments:
Ah okay, saw his code example also now. Didn't see that earlier. That probably happens when you're half-assed reading csdb threads while working... Thx. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
"Clearing $d019 is necessary, and testing a bit more it seems like it's necessary even on a freshly reset machine."
could you provide a testcase for this? sounds like something that should be checked if it behaves the same in VICE :) |
| |
Copyfault
Registered: Dec 2001 Posts: 478 |
Quoting KrillQuoting CopyfaultIs it possible to have an IRQ execution directly after the write cycle of that STA $D019? [...] (has influence on the irq code, i.e. wether an INC $01 at the beginning suffices or a LDA#$35:STA$01 is a must You ack a possibly pending raster IRQ with the write access to $d019, but any potentially arising subsequent raster IRQ condition should not trigger an actual IRQ before you enable the raster IRQs via $d01a. This will be when you have already set up your IRQ handler, and that one will behave and properly backup and restore $01. So i guess INC $01 works.
So true! Sorry for my confusion, but actually I meant $D01A, not $D019. So, now hopefully the correct question: can a raster IRQ be triggered directly after writing to $D01A? My understanding would be that even if an IRQ condition is active directly after the $D01A-write, the IRQ routine should not be processed before the next instruction has been finished. So my assumption is as follows:
...
lda #$01
sta $d01a
-> irq condition here... <-
dec $01
-> ...is processed here <-
(so INC $01 at the beginning of the IRQ code would suffice)
Is this correct? |
| |
MagerValp
Registered: Dec 2001 Posts: 1078 |
The VIC will register a pending raster IRQ whenever it reaches the raster line specified in $d011/12, regardless of the state of $d01a. So yes, when you enable $d01a, unless you cleared $d019 just before, you will trigger a raster IRQ before the next instruction.
It's easy to demonstrate using the VICE monitor:
(C:$0218) > d011 9b ff ; Set IRQ line to 511, i.e. never
(C:$0218) > d019 ff 00 ; Disable VIC IRQs and clear pending
(C:$0218) x ; Run for a couple of frames
(C:$ea7e) m d019 d01a ; Verify that no IRQ has been latched
>C:d019 70 f0
(C:$d0a9) > d011 1b ; Set IRQ line to 255
(C:$d0a9) x ; Run for a couple of frames
(C:$021a) m d019 d01a ; Verify that a raster IRQ has been latched
>C:d019 71 f0
(C:$0216) z ; Step one instruction, we're in keyboard polling
.C:0218 85 CC STA $CC - A:00 X:FF Y:2E SP:f2 ..-...ZC 2515975
(C:$0218) > d01a 01 ; Enable raster IRQ
(C:$0218) z ; Next instruction is IRQ handler
.C:ff48 48 PHA - A:00 X:FF Y:2E SP:ef ..-..IZC 2515985
So, just ignore my previous speculation about $d019 (I should have tested before posting :) and use the IRQ setup routine from comment #26. |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Are we certain that VICE works correctly there? Things like various cycle delays and internal pipelining aren't perfect yet, afaik, hence groepaz asking for test programs whenever possible. :) |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
indeed, especially how registers behave after powerup and/or reset is always questionable, because its documented rather poorly (if at all). |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
nice, didnt know that d019 is almost always on, nice insight. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
btw, i wouldnt trust the VICE monitor to do such testing even IF the implementation in VICE is generally correct - the sideeffects (like clearing latches when reading) may or may not behave as expected. better make a small test program and verify it on a real c64. |
| |
MagerValp
Registered: Dec 2001 Posts: 1078 |
If simple stuff like this didn't work correctly in VICE there'd be tons of glitching demos, but of course it never hurts to verify: pendingirq.prg. RUN it, then, in order:
SYS49152 - no latched IRQ turns border black
SYS49194 - latched IRQ turns border white
SYS49208 - triggered IRQ turns border green
VICE matches my HMOS C64. |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Quoting MagerValpIf simple stuff like this didn't work correctly in VICE there'd be tons of glitching demos Of course the general behaviour can easily be verified on the real thing and implemented in an emulator. But the question was something in the realm of 1-cycle delay or not, i.e., if an IRQ that is triggered pretty much at the exact cycle the IRQ mask is set would cause the CPU to execute the interrupt handler right away or only an instruction later. This requires a much more complicated setup to determine and verify. |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
also, i was referring to the reset behaviour mostly :) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
I thought it was established that the instr is only fetched ?
"Since the succeeding opcode is merely fetched, and not executed, then the pipeline flushed and the interrupt handled, then the opcode re-fetched and finally executed.." |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
I was referring to Copyfault's last question in post #85. |
| |
MagerValp
Registered: Dec 2001 Posts: 1078 |
Quote: Quoting MagerValpIf simple stuff like this didn't work correctly in VICE there'd be tons of glitching demos Of course the general behaviour can easily be verified on the real thing and implemented in an emulator. But the question was something in the realm of 1-cycle delay or not, i.e., if an IRQ that is triggered pretty much at the exact cycle the IRQ mask is set would cause the CPU to execute the interrupt handler right away or only an instruction later. This requires a much more complicated setup to determine and verify.
Sure, and while it's an interesting question, we're then beyond the simple needs of an initial, unstable, raster IRQ setup. Whatever synchronization method you use for the stable IRQ will make it moot. I would still be very surprised if x64sc didn't emulate this particular detail accurately. I can't be arsed to build a test program for that detail right now anyway :)
Oh, and regarding Copyfault's question in #85, the VIC-II can trigger a raster IRQ during the sta $d01a instruction, so no, you're never guaranteed to execute the following instruction before the first IRQ. |
| |
Krill
Registered: Apr 2002 Posts: 2980 |
Quoting MagerValpthe VIC-II can trigger a raster IRQ during the sta $d01a instruction, so no, you're never guaranteed to execute the following instruction before the first IRQ. It wouldn't pull down the IRQ line going to the processor before the LSB of $d01a is set, though, and then at least i wouldn't know when exactly this takes effect in the form of executing the first instruction of the interrupt handler. |
| |
lft
Registered: Jul 2007 Posts: 369 |
Just some idle thoughts: When sprites 3-7 are enabled, the earliest start of a raster interrupt handler happens nine cycles later than if those sprites are disabled. Not ten, which would be expected if the CPU responded immediately. So the first cycle of interrupt latency is due to something that happens in parallel to what the cpu is doing, and is unaffected by whether it's halted or running. It could be latching the signal, for instance.
So even if the interrupt is triggered by writing to d01a, at least one more cycle (fetching the next opcode) should happen before the main program is interrupted. And then it seems reasonable that the fetched instruction is executed. But the recent discussion makes me uncertain.
This should be tested. |
| |
MagerValp
Registered: Dec 2001 Posts: 1078 |
Good points, and easy enough to test: pendingirq2.prg, same sequence of SYS calls as in comment #91. The instruction immediately following the sta $d01a, dey, is executed before the IRQ triggers (verified that VICE matches my C64). So this means that immediately writing the register in the VICE monitor with > d01a 01 doesn't match the behavior of sta $d01a, but I suppose that isn't too surprising.
It makes sense too - at least on the 65c02 IRQs are evaluated during the last cycle of the previous instruction, and what happens is that the next opcode is replaced by $00, forcing a BRK. NMOS 6502 presumably works the same. |
| |
Copyfault
Registered: Dec 2001 Posts: 478 |
So my assumption was correct :)
Thanks to everyone for clarification, esp. to MagerValp for quickly mocking up a test prg. |