Rad Racer 2 [MMC3]

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Rad Racer 2 [MMC3]
by on (#55670)
- What's required to get this game working on MMC3? Does it use a different revision than SMB3 or MegaMan3 as examples?

by on (#55677)
Rad Racer 2 uses four-screen mirroring. Some of the roms floating around don't have this correctly marked in the header, so check for that first. Since the cart is hard wired in four-screen mode, writes to the MMC3 mirroring register should be ignored.

by on (#55678)
- Great, thank you. ^_^;;

- Next, see something wrong?
Image

- The right side is glitched, part of the road appears. Any ideas?

by on (#55679)
FCEUX also has it screwed up:
Image

Nestopia and Nintendulator have no problem though.

by on (#55681)
- I wonder if this game uses a different MMC board revision, implying a different IRQ setup (A or B).

by on (#55682)
It uses the TVROM board: http://wiki.nesdev.com/w/index.php/TVROM

I don't think it relies on any 'special' behavior. My MMC3 code is pretty dumb (no accounting for different IRQ setups, doesn't deal with manually clocking A12, etc), and I don't see these glitches.

by on (#55695)
- I have no clue (yet). Just double checking: the nametables are update through writes to $2000-$3EFF, right? Here's my write code:
Code:
_ppubank_name_write((tempaddr>>10)&3,tempaddr&0x3FF,data);
(bank 0..3, address 0..3FF, value)

by on (#55708)
looks ok to me.

by on (#55713)
- If I pull back the PPU x scroll update to a lower value (<257), it fixes partially; less then 245 causes the IRQ to malfunction. Of course, this was just an hack to look for the problem.

by on (#55719)
I don't know... I guess I still suspect cpu timing (as mentioned in the Battletoads thread) or perhaps even a cpu bug. The reason I say this is because I tested Rad Racer (1, not 2) w/ RockNES and saw glitches similar to ones I saw in my emulator when I had some cpu timings wrong.

I tried recreating the Rad Racer 2 issue by 'breaking' some of my cpu code, but didn't have any luck.

by on (#55721)
James wrote:
I don't know... I guess I still suspect cpu timing (as mentioned in the Battletoads thread) or perhaps even a cpu bug. The reason I say this is because I tested Rad Racer (1, not 2) w/ RockNES and saw glitches similar to ones I saw in my emulator when I had some cpu timings wrong.

I tried recreating the Rad Racer 2 issue by 'breaking' some of my cpu code, but didn't have any luck.


- Forget the last public version, it's broken. Heh, the last public version of your emu doesn't recognize the 4-screen mirroring as it seems.

- Here my latest RockNES binary anyway. If you want to look the source code, just let me know.

by on (#55724)
Zepper wrote:
Heh, the last public version of your emu doesn't recognize the 4-screen mirroring as it seems.


Yeah, I just fixed it a couple of weeks ago (which is why I could respond so quickly :lol:). I have some other changes that need to be wrapped up before I release a new version.

Zepper wrote:
If you want to look the source code, just let me know.


I'd be happy to take a look at it, if you want me to. I sent you a PM with my email address -- we can discuss off-line.

by on (#55726)
Usually, whenever I get a situation like this, I use Nintendulator Debug and put breakpoints at PPU writes, to see if the timing is correct and matches what the other emulator does.

by on (#55744)
- It seems the same problem with this demo by Bregalad. Uh, could someone test it with PowerPak?

Image

- Of course, this glitch isn't "static". It disappears from left to right, then restarts. Just try it in my latest binary to see what I mean.

by on (#55751)
Which PPU pixel does the bankswitch/pattern table change instruction end on?

by on (#55762)
I can test the demo on a PAL NES, but it's no longer available... could you upload another copy?

by on (#55763)
- Sure. It's not the original package, but I believe it's 3 files anyway. For PAL, you should try the CNROM version.

by on (#55765)
I've re-uploaded it. (I removed it cause people didn't seems to pay attention to it).
Note that only the PAL version is confirmed to work on hardware for now.

by on (#55767)
What's the difference between midscanline.nes and midscanline_b.nes? Both work fine in nemulator. The CNROM version doesn't, but I don't support PAL mode, so I guess that's to be expected.

by on (#55770)
Bregalad wrote:
I've re-uploaded it. (I removed it cause people didn't seems to pay attention to it).
Note that only the PAL version is confirmed to work on hardware for now.


- How exactly? Do you mean a black screen or garbage?

by on (#55785)
Huh ??

by on (#55786)
I think Zepper clicked the wrong post's reply button. Let me rephrase: For each ROM that fails, exactly what does it do that fails?

by on (#55788)
tepples wrote:
I think Zepper clicked the wrong post's reply button. Let me rephrase: For each ROM that fails, exactly what does it do that fails?


Nah. ^_^;; omg, here we go:

- You said the ROM doesn't work, but does it display something or black screen only?

by on (#55805)
Well I said it does work on PAL and is untested on NTSC (but very very likely to work as it only differs in timing, which is adapted, from the PAL version).

by on (#55826)
- Ah, ok. ^_^;;

by on (#56084)
Zepper -- saw that you released a new version of RockNES. Did you fix this issue? If so, what was the problem?

by on (#56085)
- I didn't fix it. It's probably my gfx engine.

by on (#93815)
Sorry for bumping it, but such problems are still pending. Any help? This glitch occurs in Mega Man 3 (glitched scanline on Magnet Man, instead of Shadow Man), Rad Racer 2 and Gauntlet 2 (glitches at right).

by on (#93824)
Are you sure the two are related? MM3 is a single line issue where RR2 is multiline.

For what it's worth I don't see how the MMC3 could cause the RR2 issues, my guess is your comment about it being your gfx engine is correct. I can see how the MMC3 could cause the difference in MM3 but if it was you wouldn't be able to pass blargg's tests like you now do. I guess it's possible you've got MMC3 mirroring issues but not IRQ. You probably knew that though...

by on (#93844)
Screenshots:
Image Image Image

- Mega Man 3: glitch should be on Shadow Man box, and not on Magnet Man.
- Rad Racer 2: right side is glitched.
- Gauntlet 2: glitched at right side, 3 segments of +-20 pixels.

All these games use IRQ. If I adjust the IRQ to trigger later (much like mapper 64), the glitches are gone... but I disagree.

by on (#93856)
Ahh I see. I though you fixed the issue and were able to pass blargg's tests. Looks like your timing is still off and failing scanline timing test. We went further into the details on that other thread of yours. Solve those issues ensuring your PPU and CPU are properly in sync. I'm guessing once you get that you'll fix ALL of these IRQ problems.

by on (#94000)
My emu pass in all MMC3 IRQ tests, including CPU tests.

by on (#94009)
Oh my bad, I thought I had the latest release.

So if you delay /IRQ's you fix the radracer2 and MM3 issues but then subsequently fail blargg's tests? Interesting...

by on (#94019)
infiniteneslives wrote:
So if you delay /IRQ's you fix the radracer2 and MM3 issues but then subsequently fail blargg's tests? Interesting...


I kept hitting issues where the exact delay value needed to run MM3 Gemini Stage and Super Mario Bros 3 didn't match what Ryphecha had (5 vs 6 ticks, IIRC), and I'd be surprised if my CPU core still had bad cycle timings. So it certainly makes you feel that there's some incredibly timing-sensitive stuff going on around there.

by on (#94066)
I'm reviewing my VBlank/NMI timing, as a possible reason for such glitches. Regarding blargg's vbl_timing test (VBlank timing), it says "Reading 1 PPU clock before VBL should suppress setting". Well, should it be done "manually"? In short words, should I put a flag to avoid such thing?

by on (#94071)
byuu wrote:
I kept hitting issues where the exact delay value needed to run MM3 Gemini Stage and Super Mario Bros 3 didn't match what Ryphecha had (5 vs 6 ticks, IIRC), and I'd be surprised if my CPU core still had bad cycle timings. So it certainly makes you feel that there's some incredibly timing-sensitive stuff going on around there.


Not sure if follow, are you saying something like MM3 and SMB3 required different IRQ timings in your emu than someone elses? What are you referring to as ticks? I'm guessing you're talking about number of CPU cycles that CHR A12 must be low before the counter is allowed to be clocked by a subsequent CHR A12 rising edge? If so I'm confused because that would affect which scanline the IRQ would be fired (because you improperly counted scanlines), not what time a IRQ should be fired during a given scanline (specifically what CPU cycle) which is what Zepper is having issues with.

While I agree there are some time sensitive issues with the IRQ, the time that an IRQ should be fired within a given scanline is simple in regards to how the NES works: The CPU must receive the IRQ the exact moment (within logic delays) of the CHR A12 rising edge. This MUST be *mid-cycle* for the CPU (and probably PPU as well), not at the beginning or end of the CPU's current cycle. Now I'm not the guy to ask when it comes to how to do this in an emu, but I have a pretty solid grasp of what's actually happening in the hardware. I would think this means you have to account for what time CHR A12 goes high within the PPU cycle (I'm guessing it's not in the beginning, but sometime mid-PPU cycle I haven't looked at this on my scope but could if desired). Since the PPU and CPU's clocks aren't usually aligned this means that an emulator would have to somehow have keep track of timing and syncronize numerous times within a single PPU/CPU cycle.

I imagine that rounding the time that CHR A12 rises to the beginning of the PPU's cycle could cause issues like Zepper is seeing. If he rounds up to that start of the PPU cycle he passes blargg's tests, and if he delays to the end of the PPU cycle or so, RR2 and MM3 operater properly. My guess is he needs to fire the IRQ in the middle of the PPU cycle to get them both to work. Now I'm making some assumptions on how RockNES might work and might be way off base. But if what I'm saying doesn't make sense let me know, I'll draw a timing diagram to illustrate my point.

by on (#94072)
@infiniteneslives, let me know if you want to give a look into my sources.

by on (#94078)
> I'm guessing you're talking about number of CPU cycles that CHR A12 must be low before the counter is allowed to be clocked by a subsequent CHR A12 rising edge?

I believe so, yes. Been a few months, emulated a few more systems since then. Basically I am talking about this:

Code:
//this is a thread, tick() adds 12 cycles against a 21MHz clock
void MMC3::main() {
  while(true) {
    if(irq_delay) irq_delay--;
    cpu.set_irq_line(irq_line);
    tick();
  }
}

//called on CHR read and CHR writes
void MMC3::irq_test(unsigned addr) {
  if(!(chr_abus & 0x1000) && (addr & 0x1000)) {
    if(irq_delay == 0) {
      if(irq_counter == 0) {
        irq_counter = irq_latch;
      } else if(--irq_counter == 0) {
        if(irq_enable) irq_line = 1;
      }
    }
    irq_delay = 6;  //Ryphecha uses 5 here, which breaks SMB3 for me
  }
  chr_abus = addr;
}


> which is what Zepper is having issues with.

Sorry, I may have misunderstood. At this point I'm not having an issue, just noting an observation I had when dealing with this chip that I was hoping might be helpful.

> The CPU must receive the IRQ the exact moment (within logic delays) of the CHR A12 rising edge. This MUST be *mid-cycle* for the CPU (and probably PPU as well), not at the beginning or end of the CPU's current cycle.

Oh? I've been trying to get information on this for a while, it seems to be an undocumented area of the NES.

But it's something I needed in SNES emulation very early on: the idea I call bus hold delays. When you read, it puts the address on the bus and waits a set number of clocks. The other chip will see the read and put its data on the bus, at which point it has to be there a bit to stabilize. But the thing is, it's up to the other chip how quickly it will put the data there. The same thing goes for a write, you can put it there on the bus, but it's going to take you some time for the value to stabilize. So the other chip will wait a while there first.

The problem is, how in the world do you know exactly what values to use here? If we assume 12 cycles against the 21MHz clock, do we just wait 6 cycles before doing the read, and 12 cycles for the write? Even then, it likely varies on a per-chip basis, and possibly even on a per-register-per-chip basis.

Also, I'm not even sure I understand the concept of a mid-PPU-cycle. A cycle is usually a point between discrete operations, and in this case we're only doing a single CHR read between each cycle. So you can only really have the return value be at the start or end of the cycle. Having the MMC3 do something in the middle of a PPU read seems like nonsense.

In the middle of a CPU read, sure, that makes more sense because the CPU is doing lots of things in unison: polling IRQ flags, reading from the bus, performing asynchronous DMA (on some systems), etc.

Meh, anyway, we can start a new topic if you'd like to get in depth and feel it'd be off-topic to this discussion. Up to you. FWIW, I already have the means to simulate mid-cycle CPU actions, and I can discuss how I do that if you'd like.

by on (#94080)
I'll look at em Zepper if you'd like, although my level of understanding your code is going to be heavily dependent on the depth of you comments within the code I'm guessing. email: paul@InfiniteNesLives.com


byuu wrote:
Oh? I've been trying to get information on this for a while, it seems to be an undocumented area of the NES.


Kinda, I don't know if blargg understood this exactly or not. But my hardware MMC3 failed when I made this error as did Zepper's emu. We were discussing it and the '5-6 ticks' here That's about the extent of the current documentation to my knowledge.


Quote:
Also, I'm not even sure I understand the concept of a mid-PPU-cycle. A cycle is usually a point between discrete operations, and in this case we're only doing a single CHR read between each cycle. So you can only really have the return value be at the start or end of the cycle. Having the MMC3 do something in the middle of a PPU read seems like nonsense.


Depending on how your emu works it might be nonsense. But on hardware like you've pointed out signals take time. For instance I think it's safe to say addresses change in the middle of the PPU cycle just like any processor. Clock edge to start cycle then the address becomes valid a few nsec later. The MMC3 doesn't get that valid address (CHR A12 rise) until the PPU is in the midst of it's cycle. It then takes some time for the MMC3 to generate the /IRQ and the CPU to sense that interupt, this is going to be a large delay relatively since it's a pull-up open collector signal. If the time offset between the CPU and PPU clocks is smaller than this entire delay it might be easy to assume that the IRQ arrives at the CPU in the current cycle and will be executed in the next cycle. When in reality this long sequence of events causes the IRQ to delayed to the point where it doesn't arrive at the CPU until the NEXT cycle and will get executed one cycle later. However when the CPU and PPU are aligned I wouldn't expect the delay to be long enough to push the /IRQ into the next CPU cycle.

In any event these delays are present in the hardware and they may be relied upon by certain games. If Zepper gets blargg's tests to pass with no delay and RR2 to work with X delay, then perhaps the sweet spot is between zero and X amount of delay.