Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
 Welcome to our latest new user mattfp1 ! (Registered 2017-11-20) You are not logged in 
CSDb User Forums


Forums > C64 Coding > TIL: The instruction after SEI can be executed before a pending IRQ is handled
2017-11-07 16:56
Krill

Registered: Apr 2002
Posts: 902
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!
2017-11-07 17:38
Mixer

Registered: Apr 2008
Posts: 228
Interesting. Any uses for this? Force NMI timing at stable raster? SEI + delay.
2017-11-07 18:54
White Flame

Registered: Sep 2002
Posts: 134
The 6502 implemented delay slots before delay slots were cool. ;-)
2017-11-07 21:39
Oswald

Registered: Apr 2002
Posts: 4124
well it makes sense 6502 have a kind of prefetch. guess hardwired behaviour doesnt wants to drop the instructions before executed.
2017-11-07 22:41
lft

Registered: Jul 2007
Posts: 314
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.
2017-11-07 23:05
doynax

Registered: Oct 2004
Posts: 211
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.
2017-11-08 08:45
ChristopherJam

Registered: Aug 2004
Posts: 682
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.
2017-11-08 09:01
JackAsser

Registered: Jun 2002
Posts: 1251
So, always nop after sei? :)
2017-11-08 09:24
ChristopherJam

Registered: Aug 2004
Posts: 682
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...
2017-11-08 12:22
Groepaz

Registered: Dec 2001
Posts: 8275
yet another reason to forget this cargo cult of putting sei/cli around raster irq setup :)
2017-11-08 13:54
MagerValp

Registered: Dec 2001
Posts: 891
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 :)
2017-11-08 14:26
dano

Registered: Jul 2004
Posts: 112
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.
2017-11-08 15:50
TWW

Registered: Jul 2009
Posts: 409
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
2017-11-08 16:01
ChristopherJam

Registered: Aug 2004
Posts: 682
Quoting MagerValp
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.


Ok, that makes a lot more sense.
2017-11-08 16:07
MagerValp

Registered: Dec 2001
Posts: 891
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.
2017-11-08 16:14
lft

Registered: Jul 2007
Posts: 314
Quoting MagerValp
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.


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!
2017-11-08 19:09
Oswald

Registered: Apr 2002
Posts: 4124
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.
2017-11-08 20:47
lft

Registered: Jul 2007
Posts: 314
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.
2017-11-08 20:48
Krill

Registered: Apr 2002
Posts: 902
Quoting MagerValp
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.
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.
2017-11-08 21:12
Oswald

Registered: Apr 2002
Posts: 4124
ah right, my eye didnt catch the instead :)thanks.
2017-11-08 21:17
Krill

Registered: Apr 2002
Posts: 902
Quoting lft
On 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. :)
2017-11-08 21:38
Oswald

Registered: Apr 2002
Posts: 4124
I dont care about restore, if the user wants to crash the demo let it be. its his own fault :)
2017-11-08 21:46
lft

Registered: Jul 2007
Posts: 314
The enemy (nmi?) cannot push RESTORE if you disable his hand.
2017-11-08 22:05
Groepaz

Registered: Dec 2001
Posts: 8275
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 :)
2017-11-09 15:43
TWW

Registered: Jul 2009
Posts: 409
Ground the fucker ^^
2017-11-09 16:18
MagerValp

Registered: Dec 2001
Posts: 891
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.
2017-11-09 16:27
Krill

Registered: Apr 2002
Posts: 902
Quoting MagerValp
but 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? :)
2017-11-09 16:44
MagerValp

Registered: Dec 2001
Posts: 891
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.
2017-11-09 16:48
iAN CooG

Registered: May 2002
Posts: 1750
" 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?
2017-11-09 16:51
MagerValp

Registered: Dec 2001
Posts: 891
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.
2017-11-09 19:01
Stone

Registered: Oct 2006
Posts: 118
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.
2017-11-10 08:56
ChristopherJam

Registered: Aug 2004
Posts: 682
Quoting MagerValp
For 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 :)
2017-11-10 11:16
MagerValp

Registered: Dec 2001
Posts: 891
Quote: Quoting MagerValp
For 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.
2017-11-10 11:20
Krill

Registered: Apr 2002
Posts: 902
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. :)
2017-11-10 11:22
Groepaz

Registered: Dec 2001
Posts: 8275
64er mag had some example for this.... it was slooooooooooow =)
2017-11-10 11:24
MagerValp

Registered: Dec 2001
Posts: 891
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 :)
2017-11-10 11:30
Oswald

Registered: Apr 2002
Posts: 4124
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.
2017-11-10 11:55
Bitbreaker

Registered: Oct 2002
Posts: 430
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?
2017-11-10 13:30
Krill

Registered: Apr 2002
Posts: 902
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.
2017-11-11 03:23
TWW

Registered: Jul 2009
Posts: 409
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^^
2017-11-11 05:05
ChristopherJam

Registered: Aug 2004
Posts: 682
Quoting TWW
Morale 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.
2017-11-11 05:09
ChristopherJam

Registered: Aug 2004
Posts: 682
Quoting Krill
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.


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.
2017-11-11 07:59
Oswald

Registered: Apr 2002
Posts: 4124
Quote: Quoting TWW
Morale 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.
2017-11-11 08:09
lft

Registered: Jul 2007
Posts: 314
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?
2017-11-11 08:58
Oswald

Registered: Apr 2002
Posts: 4124
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.
2017-11-11 09:38
Oswald

Registered: Apr 2002
Posts: 4124
anyhow I realise this is a religious argument, everyone should just do it as he likes. doesnt really matter.
2017-11-11 10:48
ChristopherJam

Registered: Aug 2004
Posts: 682
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.
2017-11-11 11:28
Groepaz

Registered: Dec 2001
Posts: 8275
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 :)
2017-11-11 11:40
ChristopherJam

Registered: Aug 2004
Posts: 682
(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...)
2017-11-11 11:45
Krill

Registered: Apr 2002
Posts: 902
Quoting Oswald
this 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. :)
2017-11-11 11:56
Oswald

Registered: Apr 2002
Posts: 4124
"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.
2017-11-11 12:34
Krill

Registered: Apr 2002
Posts: 902
Now you're grasping at straws.
2017-11-11 13:06
Oswald

Registered: Apr 2002
Posts: 4124
Quote: Now you're grasping at straws.

Now you're trolling.
2017-11-11 13:26
Oswald

Registered: Apr 2002
Posts: 4124
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.
2017-11-11 14:23
Groepaz

Registered: Dec 2001
Posts: 8275
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
2017-11-11 17:23
Krill

Registered: Apr 2002
Posts: 902
And we are discussing interrupt setup when run from a plain BASIC environment. So disabling CIA1 interrupts is enough, no SEI/CLI required. Period. :)
2017-11-11 17:29
Groepaz

Registered: Dec 2001
Posts: 8275
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 =)
2017-11-11 22:05
Frantic

Registered: Mar 2003
Posts: 1318
Okay. I'll always try to make sure to remember to use SEI/CLI then.
2017-11-11 22:06
Frantic

Registered: Mar 2003
Posts: 1318
Ha ha
2017-11-12 04:49
Oswald

Registered: Apr 2002
Posts: 4124
"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.
2017-11-12 09:27
Krill

Registered: Apr 2002
Posts: 902
Quoting Oswald
hatred 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.
2017-11-12 09:46
Krill

Registered: Apr 2002
Posts: 902
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. :)
2017-11-12 13:05
Copyfault

Registered: Dec 2001
Posts: 216
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...
2017-11-12 13:25
Copyfault

Registered: Dec 2001
Posts: 216
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?
2017-11-12 13:29
Copyfault

Registered: Dec 2001
Posts: 216
...aehmm..
must ofcourse be
$ff48
!!inc $01!!
lda #$7f
sta $dc0d
...
2017-11-12 14:44
Krill

Registered: Apr 2002
Posts: 902
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?
2017-11-12 14:47
Groepaz

Registered: Dec 2001
Posts: 8275
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).
2017-11-12 14:58
Krill

Registered: Apr 2002
Posts: 902
Quoting Groepaz
writing 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! :)
2017-11-12 15:08
Oswald

Registered: Apr 2002
Posts: 4124
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.
2017-11-12 16:14
Groepaz

Registered: Dec 2001
Posts: 8275
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.
2017-11-12 17:20
Oswald

Registered: Apr 2002
Posts: 4124
"without SEI/CLI the broken setup might have not worked at all."

thank you.
2017-11-12 18:06
Krill

Registered: Apr 2002
Posts: 902
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. :)
2017-11-12 18:25
Groepaz

Registered: Dec 2001
Posts: 8275
indeed, that sei/cli stuff only masked other - and bigger - problems.
2017-11-12 19:11
Oswald

Registered: Apr 2002
Posts: 4124
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.
2017-11-12 19:29
Groepaz

Registered: Dec 2001
Posts: 8275
time for some classic rock
2017-11-13 00:02
Copyfault

Registered: Dec 2001
Posts: 216
Quoting Krill
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). :)
Ah, you're right with that acknowledging of the IRQ which would come "on top".

Quoting Krill
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?
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 :)
2017-11-13 13:41
Krill

Registered: Apr 2002
Posts: 902
Quoting Copyfault
Is 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.
2017-11-13 15:14
spider-j

Registered: Oct 2004
Posts: 133
Quoting Krill
but 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?
2017-11-13 16:42
Groepaz

Registered: Dec 2001
Posts: 8275
correct
2017-11-13 16:49
TWW

Registered: Jul 2009
Posts: 409
Quote: Quoting Krill
but 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????
2017-11-13 16:49
TWW

Registered: Jul 2009
Posts: 409
Ok, that was perhaps a bit much... sorry... lolz
2017-11-13 17:16
Krill

Registered: Apr 2002
Posts: 902
Quoting spider-j
No need for $d019 in this case, is that correct?
If you scroll up a bit to some of MagerValps comments:
Quoting MagerValp
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. [...] 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.
2017-11-13 18:59
spider-j

Registered: Oct 2004
Posts: 133
Quoting Krill
If 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.
2017-11-13 19:23
Groepaz

Registered: Dec 2001
Posts: 8275
"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 :)
2017-11-13 22:17
Copyfault

Registered: Dec 2001
Posts: 216
Quoting Krill
Quoting Copyfault
Is 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?
2017-11-14 15:25
MagerValp

Registered: Dec 2001
Posts: 891
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.
2017-11-14 15:31
Krill

Registered: Apr 2002
Posts: 902
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. :)
2017-11-14 15:54
Groepaz

Registered: Dec 2001
Posts: 8275
indeed, especially how registers behave after powerup and/or reset is always questionable, because its documented rather poorly (if at all).
2017-11-14 16:17
Oswald

Registered: Apr 2002
Posts: 4124
nice, didnt know that d019 is almost always on, nice insight.
2017-11-14 17:42
Groepaz

Registered: Dec 2001
Posts: 8275
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.
2017-11-14 20:53
MagerValp

Registered: Dec 2001
Posts: 891
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.
2017-11-15 10:04
Krill

Registered: Apr 2002
Posts: 902
Quoting MagerValp
If 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.
2017-11-15 12:02
Groepaz

Registered: Dec 2001
Posts: 8275
also, i was referring to the reset behaviour mostly :)
2017-11-15 15:05
Oswald

Registered: Apr 2002
Posts: 4124
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.."
2017-11-15 15:21
Krill

Registered: Apr 2002
Posts: 902
I was referring to Copyfault's last question in post #85.
2017-11-15 16:38
MagerValp

Registered: Dec 2001
Posts: 891
Quote: Quoting MagerValp
If 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.
2017-11-15 17:10
Krill

Registered: Apr 2002
Posts: 902
Quoting MagerValp
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.
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.
2017-11-15 17:30
lft

Registered: Jul 2007
Posts: 314
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.
2017-11-15 22:44
MagerValp

Registered: Dec 2001
Posts: 891
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.
2017-11-17 23:07
Copyfault

Registered: Dec 2001
Posts: 216
So my assumption was correct :)

Thanks to everyone for clarification, esp. to MagerValp for quickly mocking up a test prg.
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
Acidchild/Padua
thesuperfrog
Pantaloon/Fairlight
Guests online: 47
Top Demos
1 Uncensored  (9.7)
2 Edge of Disgrace  (9.7)
3 Coma Light 13  (9.6)
4 The Shores of Reflec..  (9.6)
5 Lunatico  (9.6)
6 Comaland 100%  (9.5)
7 Incoherent Nightmare  (9.5)
8 Wonderland XII  (9.5)
9 Comaland  (9.5)
10 Wonderland XIII  (9.5)
Top onefile Demos
1 FMX Music Demo  (9.6)
2 Pandemoniac Part 2 o..  (9.6)
3 Daah, Those Acid Pil..  (9.5)
4 Dawnfall V1.1  (9.5)
5 Synthesis  (9.5)
6 Dawnfall  (9.4)
7 Treu Love [reu]  (9.4)
8 Field Sort  (9.4)
9 Pro Memoria 4  (9.3)
10 KAOS 64  (9.3)
Top Groups
1 Oxyron  (9.4)
2 Booze Design  (9.4)
3 Censor Design  (9.3)
4 Crest  (9.3)
5 The Judges  (9.3)
Top Musicians
1 Rob Hubbard  (9.7)
2 Jeroen Tel  (9.7)
3 Drax  (9.6)
4 LMan  (9.5)
5 Linus  (9.5)

Home - Disclaimer
Copyright © No Name 2001-2017
Page generated in: 2.629 sec.