Page 1 of 2

Interrupt pins and short pulses

Posted: Sun Jun 09, 2013 3:39 am
by ulfalizer
I'm trying to figure out what's going on with a particular behavior in the NES at the hardware level (related to VBlank flag reading for those in the know :)), and it would help if I understood more about how short pulses (possibly shorter than a CPU half-cycle) to the interrupt pins are interpreted.

In Visual 6502, it looks like interrupts are polled during φ1 (internally the input from the pin is pulled low during cclk, so whatever value it has during φ2 won't be seen). Does this mean that the value on the interrupt pin right at the end of φ1 is the value the CPU will see? What are the approximate tolerances here, as I'm guessing the signal can't be too short and still be seen?

Re: Interrupt pins and short pulses

Posted: Sun Jun 09, 2013 5:08 am
by GARTHWILSON
I don't know if this will help any, but 9 years ago I tried an experiment to test NMI (not IRQ) on a Rockwell R65c02 and found that it samples on every falling phase-2 edge (with a brief setup and hold time required), and seeing it low (after it was high, since NMI is edge-triggered), at any cycle of an instruction, even if for only one falling phase-2 clock, would make the processor start the interrupt sequence at the end of the instruction. I wrote about it briefly at viewtopic.php?f=4&t=225&p=1481h#p1481. Normally the I/O ICs that do the interrupting however will not release the line anyway until your ISR clears their interrupt condition, so it's not an issue.

Re: Interrupt pins and short pulses

Posted: Sun Jun 09, 2013 6:33 pm
by BigDumbDinosaur
The timing diagrams in the WDC data sheets indicate that the MPU samples IRQB and NMIB at each fall of the Ø2 clock. If the pulse duration on either is such that one is not low at the fall of Ø2 the interrupt will not be recognized as being asserted. Note that the 65C816's ABORTB interrupt input doesn't follow this timing scheme. It must be asserted at the rise of Ø2—assuming a condition arises that warrants that an abort sequence be triggered—and maintained until the next fall of Ø2 in order for the '816 to correctly sequence the interrupt.

In practice, as Garth notes, the pulse duration would likely exceed one Ø2 cycle due to latency in the interrupt service routine, as well as the unavoidable R-C time-constant of the interrupt circuitry. The latter wouldn't enter into the picture if all interrupting devices have totem-pole outputs and are directly connected to the MPU's interrupt inputs.

Re: Interrupt pins and short pulses

Posted: Sun Jun 09, 2013 8:30 pm
by ulfalizer
GARTHWILSON wrote:
I don't know if this will help any, but 9 years ago I tried an experiment to test NMI (not IRQ) on a Rockwell R65c02 and found that it samples on every falling phase-2 edge (with a brief setup and hold time required), and seeing it low (after it was high, since NMI is edge-triggered), at any cycle of an instruction, even if for only one falling phase-2 clock, would make the processor start the interrupt sequence at the end of the instruction. I wrote about it briefly at viewtopic.php?f=4&t=225&p=1481h#p1481. Normally the I/O ICs that do the interrupting however will not release the line anyway until your ISR clears their interrupt condition, so it's not an issue.
Is "on the falling phase-2 edge" different from "during phase 1"? The finest resolution you get in the sim is a half-cycle, so it seems you wouldn't be able to distinguish it further there at least. :|

Here's an example of the smallest IRQ assertion interval that will trigger an interrupt for LDA #$FF: http://visual6502.org/JSSim/expert.html ... 6&steps=20 . Note that IRQ only needs to be asserted during phase 1, and that it's asserted during the last tick of the LDA (the instructions are viewed as starting when they are fetched here, even though Execute still shows the old instruction during the fetch).

The NES thing is an NMI btw (from the graphics chip). The 6502 seems to sample the NMI input each cycle and set a "pending NMI" flag if it goes from high to low. The point where it samples the IRQ input (usually during the last tick of an instruction) also seems to be the point where it checks if it got an NMI.

Re: Interrupt pins and short pulses

Posted: Sun Jun 09, 2013 11:07 pm
by GARTHWILSON
Quote:
Is "on the falling phase-2 edge" different from "during phase 1"?
Slightly. If it went down after the falling edge of phase 2, and came right back up again, ie, the low pulse fit between phase-2 edges with room to spare on both ends, it would not be seen.

Re: Interrupt pins and short pulses

Posted: Sun Jun 09, 2013 11:33 pm
by ulfalizer
GARTHWILSON wrote:
Quote:
Is "on the falling phase-2 edge" different from "during phase 1"?
Slightly. If it went down after the falling edge of phase 2, and came right back up again, ie, the low pulse fit between phase-2 edges with room to spare on both ends, it would not be seen.
Seems odd that it would be on the falling edge instead of the rising edge though. During phase 2 the input from the pin is driven low, so the value has to be polled during the first phase. The state of the chip can't really change during the first phase though (if you ignore analog effects), so it seems that it would be the value at the end of phase 1, or equivalently at the rising edge of phase 2, that would matter.

Might be missing something though...

Re: Interrupt pins and short pulses

Posted: Mon Jun 10, 2013 6:20 am
by BigDumbDinosaur
ulfalizer wrote:
GARTHWILSON wrote:
Quote:
Is "on the falling phase-2 edge" different from "during phase 1"?
Slightly. If it went down after the falling edge of phase 2, and came right back up again, ie, the low pulse fit between phase-2 edges with room to spare on both ends, it would not be seen.
Seems odd that it would be on the falling edge instead of the rising edge though.

That's the way it works. When Ø2 is low the MPU does internal stuff, which includes starting on an interrupt. There really isn't a "phase 1" per se. The Ø2 clock is the timing reference.

Quote:
During phase 2 the input from the pin is driven low, so the value has to be polled during the first phase.

Nope. Polling occurs at the fall of Ø2. See the timing diagram if you are in doubt.

Quote:
The state of the chip can't really change during the first phase though (if you ignore analog effects), so it seems that it would be the value at the end of phase 1, or equivalently at the rising edge of phase 2, that would matter.

Might be missing something though...

Au contraire! The "state of the chip" does change during Ø2 low. Not to be redundant, but if you examine the timing diagram you will see that interrupt inputs are sampled at the fall of the clock, exactly as Garth described.

I assume by mentioning "NES" you are referring to the Nintendo machine. That unit has a 65C02, whose data sheet is available here and at Western Design Center's website. You probably should give it a read.

Re: Interrupt pins and short pulses

Posted: Mon Jun 10, 2013 6:53 am
by ulfalizer
Turns out I was misreading the logic closest to the pin. Thought it was a suppression mechanism, but it's actually a latch. Now it does work out to the falling edge of phase 2, but I still need to figure what's going on the in the Visual 6502 links I posted, since those make it look like it's the interrupt pins' value during phase 1 that matters. :?

The CPU in the original NES is not a 65C02, but a Ricoh 2A03, which contains an original NMOS 6502 (along with sound and other support circuitry).

Re: Interrupt pins and short pulses

Posted: Mon Jun 10, 2013 9:00 am
by BigEd
You should probably think of the visual6502 sim as seeing new input values at clock edges: the simulation responds only to clock events, and for each clock event it ripples through the effects until every node is stable. If you're thinking down at this level, you may need to think carefully about how you interpret the tabular representation.
Cheers
Ed

Re: Interrupt pins and short pulses

Posted: Mon Jun 10, 2013 9:44 am
by ulfalizer
BigEd wrote:
You should probably think of the visual6502 sim as seeing new input values at clock edges: the simulation responds only to clock events, and for each clock event it ripples through the effects until every node is stable. If you're thinking down at this level, you may need to think carefully about how you interpret the tabular representation.
Cheers
Ed
Yeah, it's prone to off-by-one errors.

The way I visualize stuff now is that each row represents the state after everything has stabilized, with state transitions "between" rows. That seems to work for external pins too, as any new values you see on them will have rippled through the chip for that row.

Still not seeing how the log from the Visual 6502 link I posted above is compatible with the pin being "sampled" (as in its value there determining what happens) on the falling edge of M2 though. Maybe I need to look at it fresh later.

Re: Interrupt pins and short pulses

Posted: Mon Jun 10, 2013 10:02 am
by BigEd
It's probably down to the fine detail of how the code is written: I added the timed interrupt code, and maybe wasn't as careful as I might have been.
Here's the log:

Code: Select all

cycle ab	 db	rw Fetch	pc	  a	 x	 y	 s	p	    Execute irq nmi
 0	0000	58	1	CLI	0000	aa	00	00	fd	nv‑BdIZc	BRK	1	1
 0	0000	58	1	CLI	0000	aa	00	00	fd	nv‑BdIZc	BRK	1	1
 1	0001	a9	1		   0001	aa	00	00	fd	nv‑BdIZc	CLI	1	1
 1	0001	a9	1		   0001	aa	00	00	fd	nv‑BdIZc	CLI	1	1
 2	0001	a9	1	LDA # 0001	aa	00	00	fd	nv‑BdiZc	CLI	1	1
 2	0001	a9	1	LDA # 0001	aa	00	00	fd	nv‑BdiZc	CLI	1	1
 3	0002	ff	1		   0002	aa	00	00	fd	nv‑BdiZc	LDA # 0	1
 3	0002	ff	1		   0002	aa	00	00	fd	nv‑bdiZc	LDA # 1	1
 4	0003	18	1	CLC	0003	ff	00	00	fd	Nv‑bdizc	LDA # 1	1
 4	0003	18	1	CLC	0003	ff	00	00	fd	Nv‑bdizc	LDA # 1	1
 5	0003	18	1		   0003	ff	00	00	fd	Nv‑bdizc	BRK	1	1
 5	0003	18	1		   0003	ff	00	00	fd	Nv‑bdizc	BRK	1	1
 6	01fd	18	0		   0003	ff	00	00	fd	Nv‑bdizc	BRK	1	1
 6	01fd	00	0		   0003	ff	00	00	fd	Nv‑bdizc	BRK	1	1
 7	01fc	18	0		   0003	ff	00	00	fd	Nv‑bdizc	BRK	1	1
 7	01fc	03	0		   0003	ff	00	00	fd	Nv‑bdizc	BRK	1	1
 8	01fb	18	0		   0003	ff	00	00	fd	Nv‑bdizc	BRK	1	1
 8	01fb	a0	0		   0003	ff	00	00	fd	Nv‑bdizc	BRK	1	1
 9	fffe	00	1		   0003	ff	00	00	fa	Nv‑bdizc	BRK	1	1
 9	fffe	00	1		   0003	ff	00	00	fa	Nv‑Bdizc	BRK	1	1
10	ffff	00	1		   0003	ff	00	00	fa	Nv‑BdIzc	BRK	1	1
10	ffff	00	1		   0003	ff	00	00	fa	Nv‑BdIzc	BRK	1	1
11	0000	58	1	CLI	0000	ff	00	00	fa	Nv‑BdIzc	BRK	1	1
11	0000	58	1	CLI	0000	ff	00	00	fa	Nv‑BdIzc	BRK	1	1
12	0001	a9	1		   0001	ff	00	00	fa	Nv‑BdIzc	CLI	1	1
12	0001	a9	1		   0001	ff	00	00	fa	Nv‑BdIzc	CLI	1	1

Re: Interrupt pins and short pulses

Posted: Mon Jun 10, 2013 10:17 am
by BigEd
For another step closer to the truth, it might amuse you to run a circuit simulation: viewtopic.php?f=8&t=1768

(As has been said, the reality is that there's a window around the clock edge, the setup time before and the hold time after, within which a synchronous input should be stable. Sometimes the hold time is zero, but not always.)

Cheers
Ed

Re: Interrupt pins and short pulses

Posted: Mon Jun 10, 2013 11:23 pm
by Dr Jefyll
ulfalizer wrote:
I'm trying to figure out what's going on with a particular behavior in the NES at the hardware level (related to VBlank flag reading for those in the know :))
Hi, ulfalizer. Sometimes it's useful to pursue more than one line of thought. The Visual6502 simulator is an amazing tool, of course. Taking a broader approach, I wonder if it'd be helpful to share with us something about the "behavior" you mention.

Are you trying to determine whether this VBlank flag gets read before or after the NMI from the graphics chip gets recognized, or is the question more complex than that? Dunno how many of us here are in the know about NES, but maybe we can ask a dumb question that'll spark something in your own mind!

-- Jeff

P.S.- As you may know, an interrupt can cause an opcode -- such as one that'll read VBlank ! -- to get fetched and then discarded. Following completion of the ISR, the exact same opcode will be fetched again. Can this possibly be pertinent? Details here.

Re: Interrupt pins and short pulses

Posted: Tue Jun 11, 2013 5:35 am
by ulfalizer
Dr Jefyll wrote:
ulfalizer wrote:
I'm trying to figure out what's going on with a particular behavior in the NES at the hardware level (related to VBlank flag reading for those in the know :))
Hi, ulfalizer. Sometimes it's useful to pursue more than one line of thought. The Visual6502 simulator is an amazing tool, of course. Taking a broader approach, I wonder if it'd be helpful to share with us something about the "behavior" you mention.

Are you trying to determine whether this VBlank flag gets read before or after the NMI from the graphics chip gets recognized, or is the question more complex than that? Dunno how many of us here are in the know about NES, but maybe we can ask a dumb question that'll spark something in your own mind!

-- Jeff

P.S.- As you may know, an interrupt can cause an opcode -- such as one that'll read VBlank ! -- to get fetched and then discarded. Following completion of the ISR, the exact same opcode will be fetched again. Can this possibly be pertinent? Details here.
Unfortunately it's a bit tricky to explain, but I'll do my best for a basic overview. I'm currently working together with blargg, who has scope readings from an actual NES, which lets me match up my findings from the simulators with the messiness of the real world.

Basically, there's a flag (it happens to be related to VBlank in this case), which is tied to NMI generation and has special behavior when reading it. The flag is set automatically at a particular point in the frame (to indicate that VBlank has started), and reading the register ($2002) that holds the flag does two things:
  1. Holds the value of the flag in a separate read buffer so it can be read (this is mentioned in the tutorial).
  2. Clears the flag. The purpose of the read buffer is to allow it to still be read.
The read behavior above happens during φ2 of the read cycle, but just to make things more complicated the duty cycle of the φ2 that comes out of the chip (called M2) has been modified in the NES; see http://wiki.nesdev.com/w/index.php/CPU_ ... escription.

The flag is tied to the NMI line such that NMI will be asserted while the flag is set (if enabled).

The messy part comes with reading the register right around the point where the flag is set. Since the read will pull it to zero, you sometimes get cases where the NMI is missed, because it isn't asserted for long enough to be seen. You also get cases where the value is missed, because the read buffer is initialized before the value is set, but the overlapping of the read with the setting still causes the flag itself to be cleared. In addition, you want to know the earliest point where the flag will read as set for timing purposes (this isn't purely academic - some games require pretty strict timing).

The above isn't really enough information to be able to draw conclusions, but it should give a flavor at least. Basically, it's messy. :P

Re: Interrupt pins and short pulses

Posted: Tue Jun 11, 2013 8:05 am
by org
Here you go :D