RAMBO-1 Mapper Investigation

Discuss hardware-related topics, such as development cartridges, CopyNES, PowerPak, EPROMs, or whatever.

Moderators: B00daW, Moderators

User avatar
Ben Boldt
Posts: 409
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

RAMBO-1 Mapper Investigation

Post by Ben Boldt » Tue Dec 03, 2019 3:14 pm

I have finally started looking at the RAMBO-1 mapper chip suggested by newrisingsun, to try to figure out the scanline counter's mysterious 'extra kick' that is necessary for some games to run properly. I got the chip from a Klax cart. I have this hooked up to my old MMC5 tester and having some unexpected things already.

I haven't gotten any life out of the scanline counter yet, but I do have the CPU cycle counter working mostly as expected. I think it is a good starting point and when I start to understand it better, I think it will make it easier to transition to the scanline counter.

Interesting, I find that writing to $E001 (IRQ acknowledge / enable) does NOT clear the IRQ; it stays low forever when I do that. I find that I have to write to $E000 (IRQ acknowledge / DISable) first, then write to $E001 in order to clear the IRQ. Does anyone have any idea why this would be? Am I doing something wrong? Pretty sure there is only 1 source of IRQ in this chip -- I don't really get how it can stay low when writing to $E001. Writing to $C000 does change the reload value similar to what is stated in the wiki, and that much functionality gives me more confidence in the setup.

Just wondering if that is a bad sign that I have to disable the IRQ in order to acknowledge it before getting in too deep with an obvious error.

NewRisingSun
Posts: 1054
Joined: Thu May 19, 2005 11:30 am

Re: RAMBO-1 Mapper Investigation

Post by NewRisingSun » Tue Dec 03, 2019 3:31 pm

I think that is the way with most IRQ-generating mappers that you have to disable the IRQ to acknowledge it. Or are you saying that writing to $E000 does not acknowledge it, and that only the enabling after disabling acknowledges it?

User avatar
Ben Boldt
Posts: 409
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: RAMBO-1 Mapper Investigation

Post by Ben Boldt » Tue Dec 03, 2019 3:33 pm

Okay, so would I be safe to edit the wiki to rename the register:

$E001 (IRQ acknowledge / enable)
to
$E001 (IRQ enable)

:?:

Does this differ from MMC3/6 behavior?
NewRisingSun wrote:
Tue Dec 03, 2019 3:31 pm
Or are you saying that writing to $E000 does not acknowledge it, and that only the enabling after disabling acknowledges it?
I wasn't saying that but let me check on that.

Edit:
Definitely writing to $E000 (disable) acknowledges the IRQ. IRQ goes high on M2 rising edge when I do that.

NewRisingSun
Posts: 1054
Joined: Thu May 19, 2005 11:30 am

Re: RAMBO-1 Mapper Investigation

Post by NewRisingSun » Tue Dec 03, 2019 3:40 pm

Yikes, that wiki page has become a mess. Better use this revision as a starting point, which represents the results of the previous hardware tests.

Basically, the only thing we still need to find out is: There must be circumstances in which the statement " IF $C001 was written to after previous clock: reload IRQ counter with IRQ Reload value PLUS ONE (see note)" does not apply, and the "IRQ counter is loaded with IRQ Reload" instead. These circumstances apply to Skull&Crossbones but only some of the time, and to Hard Drivin' all of the time. In NintendulatorNRS, the heuristic that makes all games display correctly is that reload is reload without plus one if the C001 write occurred within 16 M2 cycles of the previous IRQ being generated the last time PA12 was high (which I also use for PA12 filtering), and reload with plus one if it occurs later or otherwise outside of that time interval. That heuristic needs to be substantiated.

lidnariq
Posts: 8776
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: RAMBO-1 Mapper Investigation

Post by lidnariq » Tue Dec 03, 2019 3:51 pm

NewRisingSun wrote:
Tue Dec 03, 2019 3:31 pm
I think that is the way with most IRQ-generating mappers that you have to disable the IRQ to acknowledge it.
Huh. For no good reason I was under the impression that that was a constraint of using discrete logic, but it's hard to argue with the prevalence of the MMC3.

User avatar
Ben Boldt
Posts: 409
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: RAMBO-1 Mapper Investigation

Post by Ben Boldt » Tue Dec 03, 2019 4:01 pm

Interesting thing is that I seem to get this behavior with the cycle counter:

M2 falling edges after the write to $C001 = ($C000_value * 4) + 6

To be clear, an example, $C000 = 1.
(1*4) + 6 = 10.
IRQ falls on the 10th falling edge of M2 after (and not including) the write to $C001.

So either I'm all messed up or I'm onto something.

Edit:
I am testing with this sequence:

1. Write $02 to $C000 (Set IRQ counter reload value)
2. Write $01 to $C001 (Set to CPU cycle mode, Resets the cycle counter)
3. Write $00 to $E001 (Enable IRQ)
4. Read from address $8000 a bunch of times
5. Write $00 to $E000 (Acknowledge/disable IRQ)
6. Goto step 2.

When I change step 6 to Goto Step 3, the number of cycles to get IRQ to trigger back low walks all around. I would like to investigate this to possibly shed some light on the counter. I would expect a rollover with around 255*4 cycles to retrigger the IRQ but I am only getting cycles less than or equal to the intended reload value.

lidnariq
Posts: 8776
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: RAMBO-1 Mapper Investigation

Post by lidnariq » Tue Dec 03, 2019 4:30 pm

Ben Boldt wrote:
Tue Dec 03, 2019 4:01 pm
the number of cycles to get IRQ to trigger back low walks all around.
Any bounds on the range?

User avatar
Ben Boldt
Posts: 409
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: RAMBO-1 Mapper Investigation

Post by Ben Boldt » Tue Dec 03, 2019 5:07 pm

I can write $FF to $C000 and it does it. I didn't count the M2 cycles but the length of time is proportional correctly. It seems the sequence without resetting the cycle counter will generate the IRQ in less than or equal to the value in $C000, but still looking into it.

lidnariq
Posts: 8776
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: RAMBO-1 Mapper Investigation

Post by lidnariq » Tue Dec 03, 2019 5:11 pm

Is it consistent with the ÷4 prescaler only getting cleared by writing to $E001 ?

User avatar
Ben Boldt
Posts: 409
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: RAMBO-1 Mapper Investigation

Post by Ben Boldt » Tue Dec 03, 2019 5:31 pm

Definitely the counter keeps counting when IRQ is low. When I set $C000 = $02, and use the sequence that doesn't write to $C001 each time through, I find that the IRQ goes low whenever it hits a multiple of 12. Since my sequence looped without a multiple of 12 M2 cycles, this is why it walked around.

Trying a few different $C000 values, I find that:

Code: Select all

$C000 | Loop Multiple
------+---------------
   0  |  4
   1  |  8
   2  |  12
   3  |  16
   4  |  20
Loop = ($C000 + 1) * 4

I also added an additional dummy $8000 read between disabling IRQ and enabling IRQ. It had no effect on the multiple observed, therefore, the counter keeps running even with IRQ disabled.


Edit:

Theory:
- Counter is a 10-bit counter.
- On M2 falling edge, compare counter to [$C000] << 2 | 3
- If matching, generate IRQ if enabled, and reset counter to 0.
- Else if not matching, increment counter.

Or the other way:
- On M2 falling edge, compare counter to 0
- If matching, generate IRQ if enabled, and reset counter to [$C000] << 2 | 3
- Else if not matching, decrement counter.

Will have to test/modify this theory against the +6 stuff I was seeing earlier when causing counter reset by writing to $C001. Will have to consider what value it would be resetting to when writing to $C001.


Edit 2:

Well I haven't come up with a very clean explanation for $C001 vs. where it naturally loops. I have thought about it maybe having a separate count-to-4 timer, which outputs to an 8-bit counter but that doesn't really help me clean it up. I have stuck in extra dummy reads to see if $C001 would reset just the 8-bit counter and not the count-to-4 counter but those test showed no indication of that sort of thing going on. For all intents and purposes, it does behave like 1 big counter, I haven't been able to get 2 parts of it out of sync like that.

So, my best explanation for now is:
- Counter is a 10-bit counter.
- On M2 falling edge, compare counter to [$C000] << 2 | 3
- If matching, generate IRQ if enabled, and reset counter to 0.
- Else if not matching, increment counter.
- On write to $C001 with bit 0 = 1 (i.e. M2 counter mode), reset counter to -2.

Bleh I don't like that too much, it is possible I guess but it doesn't seem right. Seems there ought to be a good reason to do that instead of resetting to 0 (all zeros) or -1 (all 1s). Shifting left by 2 and backfilling with 1s seems reasonable but I don't like this -2 business.


Edit 3:

Plans for tomorrow: Set $C000 to a large value, do a number of dummy reads but not enough to trigger the IRQ, then write a smaller value to $C000, where it has already passed that number of dummy reads. Continue doing dummy reads after this.

Possible outcomes:
- IRQ gets set immediately when writing $C000 with the smaller value
- IRQ gets set at the very next dummy read after this
- IRQ gets set per a loop multiple after this
- IRQ gets set per a -2 behavior after this
- IRQ gets set after a full 10-bit counter rollover
- IRQ never gets set

NewRisingSun
Posts: 1054
Joined: Thu May 19, 2005 11:30 am

Re: RAMBO-1 Mapper Investigation

Post by NewRisingSun » Tue Dec 03, 2019 11:17 pm

I understand you are first trying to fully understand M2-based counting before moving on to PA12-based counting. That's cool, but keep in mind that the games for whom the current (i.e. 2015 I linked to) description fails do so when using PA12-based counting. The things to find out with regards to any scanline counter:
  • Is the counter latched or not (i.e. does writing a new value change the target of the current counting sequence?
  • What signal does the scanline counter look at? PA12 rises (MMC3)? PA12 falls (MC-ACC)? Something completely different (MMC5, Taito TCxxx)?
  • If it's PA12 rises or falls: Since there are eight PA12 rises per scanline, is the number of scanlines after which an IRQ is to be generated merely prescaled by eight (i.e. MC-ACC, J.Y. Company ASIC), or is the PA12 signal filtered in some way to register only once per scanline (MMC3)?
  • If the PA12 signal is filtered, how is it filtered? I.e. how many M2 rises/falls does PA12 have to stay low before a PA12 rise is recognized? (For MMC3 it's supposedly two, but that does not seem to work for any emulator; I have to use at least five.)
  • Once the "triggering" PA12 or whatever signal is encountered, how many M2 cycles delay until IRQ actually goes low?
  • What is the behavior when a target/reload value of $00/$FF is written? Fire IRQ all the time (MMC3-C), once (MMC3-A), never?

User avatar
Ben Boldt
Posts: 409
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: RAMBO-1 Mapper Investigation

Post by Ben Boldt » Wed Dec 04, 2019 12:12 am

Thanks for those points newrisingsun. We will get there. This chip has a few other interesting things I plan to look into as well, including the $A001 register (which may or may not exist), and any possible effect from pin 19 set high. With pin 19's proximity to the CIC pins, I wonder if it affects them somehow, possibly a region switch or change those CIC pins to PRG-RAM control for use in Famicom, etc, who knows.

User avatar
Ben Boldt
Posts: 409
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: RAMBO-1 Mapper Investigation

Post by Ben Boldt » Wed Dec 04, 2019 11:04 am

I tried this test today:
Plans for tomorrow: Set $C000 to a large value, do a number of dummy reads but not enough to trigger the IRQ, then write a smaller value to $C000, where it has already passed that number of dummy reads. Continue doing dummy reads after this.
And as usual, it did something not even in that list I made. It kept using the original value written to $C000. No matter what value I wrote to $C000 amidst running, larger or smaller, it would still expire/generate IRQ at the same exact spot. So it is not doing any comparison directly against the $C000 register -- it gets loaded elsewhere from the $C000 register each time the counter expires. To further demonstrate this, I skipped the initial write to $C000 each odd time through my test loop. The odd tests would then proceed to have the IRQ per the 2nd $C000 value, still persisting from the previous test loop.

Either the $C000 value is copied to the internal counter and it is a down-counter, or there is another latch/buffer that gets loaded from $C000 each expire/IRQ, to which an up-counter compares against.


Edit:

$C000 default value is $FF every single power on, I tried lots of times.


Edit 2:

I have the scanline counter functioning now. I find that these are the minimum conditions to trigger a scanline detection:

- At least 16 17 M2 cycles with PPU A12 low (typically background pattern table, NT or AT reads)
- Followed by 1 M2 cycle with PPU A12 high (typically 1 sprite pattern table read)
- Then the IRQ will occur on the falling edge of the next M2 cycle, regardless of PPU A12.

Injecting random values onto PPU A10 and A11 does not appear to have any effect on the scanline counter.


Edit 3:

So here is what I found today and it is pretty confusing.

During normal running, going from 1 scanline to the next, it requires at least 17 M2 cycles with PPU A12 = 0, followed by at least 1 M2 cycle with A12 = 1. The IRQ will occur on the next M2 falling edge after the first M2 cycle with A12 = 1, regardless of A12. This is normal running -- doing the reset with writing $00 to $C001 is different for the first 'scanline', as described next.

When writing to $C001, there are conditions required in order to register the first M2 cycle with A12 = 1 as a scanline.
- Note: I only tested writing $C001 with A12 = 0.
- I provide a number of M2 cycles between the previous M2 cycle with A12 = 1 and the next M2 cycle with A12 = 1, within which I send the $C001.
- This number can be no less than 13, so yes indeed it can happen easier than a normal scanline, which requires 17.
- You can send the $C001 with no fewer than 4 M2 cycles with A12 = 0 preceeding it.
- You can send the $C001 with 4, 5, 6, 7, 8, 9, 10, 11, 12, or 13 M2 cycles with A12 = 0 preceeding it, and in every case, this number plus the number of additional M2 cycles with A12 = 0 required after the $C001, always is a minimum of 13 to get that first scanline to count.

I have not seen anything where it cares how many M2 cycles with A12 = 1. Using smaller numbers of M2 cycles with A12 = 0, followed by extra M2 cycles with A12 = 1 doesn't make the scanline count. It is just looking for that first one as far as I have observed. There is a lot of x4, or x4+1 stuff going on here, I would think it is sharing some behaviors with the normal M2 counter mode, so I think we should really keep both of them in mind for extra clues how/why this works like this.

User avatar
Ben Boldt
Posts: 409
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: RAMBO-1 Mapper Investigation

Post by Ben Boldt » Thu Dec 05, 2019 12:47 pm

Interesting discovery: pin 19 high definitely affects the scanline interrupt. I need different numbers of M2 toggles with PPU A12 high and low. I don't know anything more about it yet.


Edit:
With pin 19 high, it completely ignores when I try to write to $8000 and $8001. It has these PRG and CHR banks:


PRG-ROM Banks:

Code: Select all

$8000-9FFF  |  $00
$A000-BFFF  |  $00
$C000-DFFF  |  $15
$E000-FFFF  |  $1F

CHR-ROM Banks:

Code: Select all

$0000-03FF  |  $00
$0400-07FF  |  $01
$0800-0BFF  |  $00
$0C00-0FFF  |  $01
$1000-13FF  |  $00
$1400-17FF  |  $B3
$1800-1BFF  |  $54
$1C00-1FFF  |  $B5
The 00/01/00/01 for the first 4 CHR banks does not respect register $8000 bit K / bit 5 / Full 1 KiB CHR bank mode. Always appears to always be in 2k mode like this.

Pretty strange!


Edit 2:
Register $A000 (mirroring control) also appears to have no effect with pin 19 high. The IRQ control registers do still very much have an effect with pin 19 high though.

NewRisingSun
Posts: 1054
Joined: Thu May 19, 2005 11:30 am

Re: RAMBO-1 Mapper Investigation

Post by NewRisingSun » Thu Dec 05, 2019 1:52 pm

The 17 M2 cycles threshold matches almost perfectly the "pa12Filter =16 M2 cycles" rule that I use in my code. I do not fully understand all the details of what you described about the first scanline after a $C001 write, other than that first scanline gets special treatment. This is currently reflected in my code as the scanline IRQ triggering after $C000 plus scanlines after a $C001 write, just $C000 after a reload from the counter reaching zero, and also just $C000 if $C001 was written to within the 16/17 M2 cycles interval since the last time that PA12 was high. This does not match exactly your description, but makes all games look as on real hardware in emulatoin.

As for pin 19, I would say it's either some kind of "test mode" pin, or a pin that turns the RAMBO-1 into something other than an enhanced MMC3. The latter would be the case if the PRG/CHR banks turned out to be switchable after all, using a completely different write pattern.

Post Reply