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: 488
Joined: Tue Mar 22, 2016 8:27 pm
Location: Minnesota, USA

Re: RAMBO-1 Mapper Investigation

Post by Ben Boldt » Wed Feb 12, 2020 12:03 pm

I am simulating it more accurately now and I am seeing something interesting. It sure looks like my test is still screwed up but I thought I would share in case it triggers any ideas for you. The green channel inverts each time I start a new scanline. I am probably off by a scanline, either that or they somehow are reloading right before the IRQ, which doesn't really make sense.
zoom.png
overview.png

Edit:
I had not implemented pre-render scanline 261 correctly. It now makes more sense:
tek00024.png


Edit 2:
Focusing on this example, where it writes $04 to $C000:

Code: Select all

Scanline | PA12 | PPUCycle | Event
---------+------+----------+---------------
241      |   1  | 28       | NMI
258      |   0  | 261      | $C000=$BC
258      |   0  | 279      | $C001=$00
258      |   0  | 291      | $E001=$00
188      |   1  | 295      | IRQ
188      |   0  | 304      | $E000=$00
189      |   0  | 44       | $E001=$00
189      |   0  | 62       | $C000=$04
193      |   0  | 288      | IRQ
193      |   0  | 297      | $E000=$00
194      |   0  | 133      | $E001=$00
194      |   0  | 151      | $C000=$17
217      |   1  | 303      | IRQ
217      |   0  | 312      | $E000=$00
241      |   1  | 24       | NMI
I bumped this write later and later until it didn't use the new value. I found this:

Code: Select all

                       _______     _______     __
PA12 __________________|     |_____|     |_____|
      ^                 ^     ^
      |                 |     +----After first falling edge PA12 (NOT using new value)
      |                 +----------After first rising edge PA12 (still using new value)
      +----------------------------PPU cyc 62 (uses new value - original example)
I ensured that there was always a small delay after changing PA12 to avoid any potential race condition. I.e. PA12 was definitely high, followed by a delay, before writing to $C000 in the middle test result.

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

Re: RAMBO-1 Mapper Investigation

Post by Ben Boldt » Wed Feb 12, 2020 3:13 pm

Scopeshots:
orig.png
after first rising edge.png
after first falling edge.png

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

Re: RAMBO-1 Mapper Investigation

Post by Ben Boldt » Thu Feb 13, 2020 4:49 pm

Latest text description, untested, but now at least considering this behavior where you can use a new reload value right away. It is not narrowed down to the IRQ being ACKed enabling this ability, that is still unknown what exactly opens the doors to make that immediately writable -- I just know that the door closes after the first falling edge of PA12. In addition, I do not know if the falling edge of PA12 itself triggers it or if it is actually M2 edge triggered with PA12 as an input. Lots to be carefully thought about and narrowed still, but we have made a step in the right direction finally.

Of the 4 main bullets in the M2 falling edge, there are conflicting statements there. I do not yet know which precedence or hierarchy these go in. It is now harder to avoid having an 8-bit comparison happening, but I think it is still valid for that to be a goal. I changed the 8-bit counter to an up-counter which is a step in the wrong direction from that goal. Lots more work to do here.

On M2 falling edge:
  • If PA12 = 0:
    • If 4-bit counter < 16: 4-bit counter++.
    • else keep the same value.
  • If PA12 = 1:
    • If 4-bit counter = 16: Clock the 8-bit counter. (see below)
    • Always reset 4-bit counter to 0.
  • If writing to $C001 (reset):
    • Clear 8-bit counter
    • Set 4-bit counter to 17.
  • If writing to $C000 (reload value):
    • If 8-bit counter = 0: Also reload 8-bit counter with new value being written to $C000
    • Do not reset the 4-bit counter, but do count it as an M2 cycle for that counter.

On 8-bit counter clock:
  • If value = $C000:
    • If IRQ is enabled, trigger IRQ (wait 1 more cycle before doing that though, regardless of PA12 next cycle...)
    • Always clear 8-bit counter.
  • Else value++.

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

Re: RAMBO-1 Mapper Investigation

Post by Ben Boldt » Fri Feb 14, 2020 2:42 pm

New drawing, definite progress being made understanding this thing.

The work I did before without toggling PA12 within each scanline turns out is still very valid information. It is not necessary to toggle it for the info I was looking for. It takes 1 M2 cycle with PA12 high to detect entering the sprite area of the scanline, and 16 M2 cycles with PA12 low to detect exiting it the sprite area of the scanline. So, filling it in with PA12s all high vs. toggling doesn't end up entirely invalidating that information.

I found that the unlocking of the reload is not anything triggered by writing to a register. The concept in the 2nd state machine in the diagram shows that it will constantly be loading the value from $C000 into the 8-bit counter each M2 cycle until that state becomes locked. This can explain the ability to "directly" write the 8-bit counter in this condition.

Note that in this diagram, the counters and state machines have a few references to each other. Since everything is clocked from M2, this means that the existing state resulting from the previous M2 cycle is used for this reference -- not the next state resulting from the present M2 cycle being considered. It gets me every time. Therein explains the "next cycle" / "1 cycle late" stuff we have known about with IRQ, and just demonstrated in the previous scopeshots with the locking of the 8-bit reload 1 cycle later than we might expect, etc.
state_machine.png


Edit:

I am not sure if this explains the +1 scanline anymore, I still have to think about that versus my older observations.

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

Re: RAMBO-1 Mapper Investigation

Post by Ben Boldt » Mon Feb 17, 2020 9:53 pm

Just a quick update,

I updated the A/B/C1/C2 simulator from before with the 3 state machine / 2 counter idea from the previous diagram I shared. I don't understand how yet but it does usually get the extra scanline correct when doing the A/B/C1/C2 test. I have at least 2 A/B/C1/C2 combinations that do not match the chip. For example, 10/10/15/15 gets an extra scanline before the IRQ on the chip but not in the simulator. I understand that the A/B/C1/C2 test is not realistic and might not even make much sense, but if the diagram matches the chip, it should give the same answer, so the fact that it doesn't means it is valuable. Whatever I am doing in that test gets it to hiccup in a different way.

Also, one detail I did not share about the scope shots. In those tests, when I got to the sprite area, I toggled PA12 for each M2 cycle. So that is not exactly a perfect test but I thought I should clarify that. So, PA12 rose the first time, followed by an M2 cycle, then PA12 fell, followed by another M2 cycle. And it was that 2nd M2 cycle where, if it was a write to $C000, was no longer allowed to take immediate effect. I think there is still something there not captured in my diagram because the way I drew it, it gets locked following that first M2, which is good. But if $C000 was written at the first M2, the 8-bit counter would not get reloaded until the 2nd M2, which is expressly forbidden by the statement "reload 8-bit counter if 8-bit reload unlocked". Almost as if the unlock needs to jump through another state before becoming truly locked... I will try adding an additional state there to the simulator tomorrow and see if it makes any improvement.


Edit:
Alternatively, I could try making the 8-bit counter's reload asynchronous/transparent (i.e. not waiting for M2).

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

Re: RAMBO-1 Mapper Investigation

Post by Ben Boldt » Wed Feb 19, 2020 4:08 pm

I got sort of stuck the way I was looking at this with the A/B/C1/C2 test. The problem with that test is that it runs through many loops before giving a result, so anything within the whole loop could propagate to the result, making it very difficult to debug. So I started a new type of test that does a 1-shot from power on. The challenge here (or possibly benefit?, see below) is that you start with a random state.

1-shot test:

Power on: PA12 = 0, wait 3.6msec
- Write 00 to E000 (IRQ Ack / Disable)
- Write 01 to C000 (Reload value)
- Write 00 to C001 (Set IRQ mode to scanline counter mode)
- Write 00 to E001 (IRQ enable)
- Goto [X]
[X]
- PA12 = 0
- Do A1 dummy reads
- Goto [Z]
[Y]
- PA12 = 0
- Do A2 dummy reads
- Goto [Z]
[Z]
- PA12 = 1
- Do B dummy reads
- Loop to [Y] 20 times (i.e. trigger 20 scanlines)
- After 20 times, stop test, examine waveform triggered on scope.


Results from these values:
A1, A2, B, result
20 20 10 3
20 20 1 3
16 16 10 3
15 15 10 Never
14 14 10 Never
12 16 10 3
11 16 10 3
1 16 10 3

Result=3 means IRQ went low on the 3rd time I got to [Z]. Since this is a power-on test, the internal state machines may come up in any random state. I find that in some cases I get a 2 on at least some of these tests. However, I found no combination that made it ALWAYS 2. It proves that writing to all 4 registers E000, C000, C001, E001 in itself is not enough to completely initialize all of the scanline state machines into known states.

I modified the test as follows:
Insert 514 dummy reads before the register writes. No change.

I then removed that modification and did a different modification as follows:
Before writing to any of the registers, set PA12 = 1, delay, do a dummy read, set PA12 = 0, delay, then proceed with the normal test. Always the result is 2 scanlines with this modification. To me, this change represents entering sprite region, so it suggests that the 8-bit counter reload can only be unlocked from within sprite region. I made this change on the state diagram.

I then added to this test an additional 20 dummy reads like this:
Before writing to any of the registers, set PA12 = 1, delay, do a dummy read, set PA12 = 0, delay, [20 DUMMY READS], then proceed with the normal test.
I still get result = 2 scanlines when doing this, even though this test will have returned to background region before writing to the registers. So 8-bit reload remains unlocked even when entering background region. We already knew and are again confirming that PA12 must be 1 (i.e. re-enter sprite region) in order to lock out the 8-bit reload.

Since there are now 2 inter-dependencies between the sprite/background state machine and the lock/unlock state machine, I merged them into 1. They are still functionally the same, just providing 2 different ways of looking at it. This is another incremental progress but not finished and not tested enough yet.
merged.jpg

Post Reply