This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Super C Area 1 and MMC3

Super C Area 1 and MMC3
by on (#99863)
I'm working through Disch's mapper docs and the wiki trying to get a handle on the MMC3's scanline counter so I can better understand the first boss battle in Super C. In short, once you hit the end of the level, scrolling halts and a large helicopter flies into view from the left side. My hypothesis was that the heli was drawn with BG tiles (Mega Man-style) and scrolled while the static lower terrain was handled with a scanline IRQ. This seems to be the case.

However, I wanted to look at how this happens programmatically and I'm tripped up on a small detail. (I'm new to both FCEUX debugging and MMC3, so bear with me.) I set breakpoints on the IRQ registers. $C000 (count value), $C001 (reset counter), and $E000 (IRQ disable) appear to be written every VBLANK (or twice?). $C000 never varies from #$F0. As expected, $E001 (IRQ enable) is not written until the 'boss area' scrolls into view. FCEUX throws a break at scanline 162. When I fool around with the scroll line display in the Name Table Viewer, I can verify that that is the point where the IRQ fires.

My confusion stems from the value in $C000. How does #$F0 count down to triggering at scanline 162? My only suspicion about the discrepancy is that shortly after the write to $C000, there are ten writes to $2006 (all #$00 as far as I can tell). The MMC3 docs indicate that this can manually manipulate the scanline counter, but I don't understand either enough to know how.

Surely I'm missing something. Or maybe I'm totally off base. Any insight is appreciated.
Re: Super C Area 1 and MMC3
by on (#99866)
The mmc3 scan line counter is triggered off of CHR A12 rising edges (only if chrA12 was previously low for ~5 CPU cycles to prevent multiple clocks during sprite fetching)

So accesses to $2006 will take CHR A12 high thus clocking the scan line counter the value is irrelevant. That's the "how" youre asking about. But I don't see how 240-10=160. Which NT are the BG and sprites mapped to? If they don't follow normal "rules" you can clock the scan line counter more than once per scanline which might be the reason for the math 'error'
Re: Super C Area 1 and MMC3
by on (#99874)
Background tiles are in the left pattern table and sprites on the right. Sprites are 8x16. So nothing out of the ordinary there.

And yeah, it's definitely the math I'm not getting.
Re: Super C Area 1 and MMC3
by on (#99876)
noattack wrote:
Surely I'm missing something. Or maybe I'm totally off base. Any insight is appreciated.

Yes, you are missing something.
When you write any value into any other space than $0000-$0700 in RAM(save for WRAM and/or SRAM), your write will not be "visible"!
Meaning-no matter what value you write into $C000, FCEU's "Hex editor" will always show the value from currently mapped PRG bank.The previous value will not be changed.
Which value happens to be F0 in this case...
Re: Super C Area 1 and MMC3
by on (#99878)
In other words, I think you need to set a write breakpoint on $C000 and look at the value being written, not just read what's mapped into $C000 at any given time.
Re: Super C Area 1 and MMC3
by on (#99887)
Hmm, I thought that's what I was doing. Let me step through my process to verify.

I opened FCEUX's 6502 Debugger, went to the BreakPoints field, and clicked the Add... button. I then input C000 in the address field, checked 'Write,' and left the 'CPU Mem' radio button selected. Each time the breakpoint hits, I get one of two outputs in the debugger:

07:FC12:A2 FF     LDX #$FF
07:FC14:8E 00 C0  STX $C000 = #$F0
07:FC17:8E 01 C0  STX $C001 = #$03
07:FC1A:A9 10     LDA #$10
07:FC1C:8C 06 20  STY $2006 = #$00
07:FC1F:8C 06 20  STY $2006 = #$00
07:FC22:8D 06 20  STA $2006 = #$00
07:FC25:8D 06 20  STA $2006 = #$00
07:FC28:8C 06 20  STY $2006 = #$00
07:FC2B:8C 06 20  STY $2006 = #$00
07:FC2E:8D 06 20  STA $2006 = #$00
07:FC31:8D 06 20  STA $2006 = #$00
07:FC34:8C 06 20  STY $2006 = #$00
07:FC37:8C 06 20  STY $2006 = #$00


07:FC40:A5 45     LDA $0045 = #$A2
07:FC42:8D 00 C0  STA $C000 = #$F0
07:FC45:8D 01 C0  STA $C001 = #$03
07:FC48:9D 00 E0  STA $E000,X @ $E001 = #$2C

(I bumped the results back a line so you could see the LDA/LDX commands. The second block also doesn't have the string of $2006 writes.)

Is this the wrong approach? What I don't get is why the values loaded in X and A don't match those showing up in the output. Again, this might be me misinterpreting the debugger output.
Re: Super C Area 1 and MMC3
by on (#99888)
The value next to STA is the value you would get if you were to read the address right now, which is the value in ROM. For a normal STA to RAM, not a mapper write, that would represent the value being overwritten. Look at the LDA #$A2 to see the count you expect.
Re: Super C Area 1 and MMC3
by on (#99891)
Thanks tepples! The answer was right in front of me and I missed it.