6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Wed Apr 24, 2024 11:13 pm

All times are UTC




Post new topic Reply to topic  [ 29 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sun Jun 09, 2013 3:39 am 
Offline

Joined: Fri May 31, 2013 5:29 am
Posts: 44
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?


Top
 Profile  
Reply with quote  
PostPosted: Sun Jun 09, 2013 5:08 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8427
Location: Southern California
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.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Sun Jun 09, 2013 6:33 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8142
Location: Midwestern USA
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.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Sun Jun 09, 2013 8:30 pm 
Offline

Joined: Fri May 31, 2013 5:29 am
Posts: 44
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.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jun 09, 2013 11:07 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8427
Location: Southern California
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.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Sun Jun 09, 2013 11:33 pm 
Offline

Joined: Fri May 31, 2013 5:29 am
Posts: 44
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...


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2013 6:20 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8142
Location: Midwestern USA
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.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2013 6:53 am 
Offline

Joined: Fri May 31, 2013 5:29 am
Posts: 44
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).


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2013 9:00 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
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


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2013 9:44 am 
Offline

Joined: Fri May 31, 2013 5:29 am
Posts: 44
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.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2013 10:02 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
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:
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


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2013 10:17 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10793
Location: England
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


Top
 Profile  
Reply with quote  
PostPosted: Mon Jun 10, 2013 11:23 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3346
Location: Ontario, Canada
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.

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Tue Jun 11, 2013 5:35 am 
Offline

Joined: Fri May 31, 2013 5:29 am
Posts: 44
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


Top
 Profile  
Reply with quote  
PostPosted: Tue Jun 11, 2013 8:05 am 
Offline
User avatar

Joined: Fri Jun 22, 2012 7:39 am
Posts: 201
Here you go :D


Attachments:
ppu_timing.jpg
ppu_timing.jpg [ 831.31 KiB | Viewed 2861 times ]

_________________
6502 addict
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 29 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron