Hi im emulating mmc3 and im trying to implement at least a basic system.
I know mmc3 is based on A12 ppu addr bus, but im clocking at cylce 256 of the end of the scanline. Well this give me problems with most games for example in Double Dragon 2 i have no sound and the screen doesn't scroll as its supposed (It scrolls with life meters and all that).
I have some questions maybe you can answer me.
- Does Vblank scanlines clock the mmc3 counter?
- Are there 1 or 2 irq flags.
- What does it mean in known terms "acknowledge" an interrupt?
What i do is the following and it doesn't seem to work.
0xC000 is written i store a temporary value that will be placed in the counter when scanline ends (cc == 256) or counter == 0.
When counter == 0 if 0xE001 has been written (IRQ enabled) i generate an IRQ.
When 0xC001 is writtten i raise a flag to tell the emu that at the end of the scanline must reload the counter with the temporary value written to 0xC000.
I really don't understand well how mmc3 works. I suppouse it counts scanlines, but it seems i dont get it, since it isn't working for me. (At least at a basic level).
During vblank, the PPU is "off", so it never puts anything on the PPU address bus (except for the "vram address"). The counter shouldn't clock by itself then.
Anes wrote:
- Does Vblank scanlines clock the mmc3 counter?
PPU A12 clocks the MMC3 counter, and if left on, the PPU will usually toggle this line 241 times. (I forget whether the pre-render or post-render scanline is the extra one.) But as Dwedit pointed out, the MMC3 watches PPU A12 during blanking (vertical or forced) just as it watches PPU A12 during rendering, so it's possible to clock it through carefully (or carelessly) constructed sequences of writes to $2000, $2005, $2006, and/or $2007.
Quote:
- What does it mean in known terms "acknowledge" an interrupt?
An interrupt service routine "acknowledges" an interrupt when it writes to hardware registers that tell the hardware that the ISR has handled the interrupt. This makes the hardware stop asserting the interrupt signal.
Ok, thanks i got it.
But isn't a good start to clock the counter at cycle 256 at the end of the scanline? and if that counter reaches "0" and irq are enable to fire an IRQ?
Becouse it's what im doing and get no answer. Can someone explain me in a simple way mmc3 operation?
tepples wrote:
Quote:
- What does it mean in known terms "acknowledge" an interrupt?
An interrupt service routine "acknowledges" an interrupt when it writes to hardware registers that tell the hardware that the ISR has handled the interrupt. This makes the hardware stop asserting the interrupt signal.
That was a great answer, both concise and accurate.
I'll just add (in case it isn't obvious) that when the CPU transfers control to the interrupt service routine, it clears the interrupt flag--the interrupt signal is still asserted, but the CPU is now ignoring it. When you return from the handler, the CPU's interrupt flag will get enabled again, which is why you want to "acknowledge" the interrupt before that happens. (This is not NES-specific, it applies to nearly all kinds of CPU out there).
[Edit: after reading the posts below mine, I suspect that the meanings of "clear" and "set" that I used for the interrupt flag are backwards for the 6502... sorry about that.]
Thanks mozz.
Anes wrote:
But isn't a good start to clock the counter at cycle 256 at the end of the scanline?
MMC3 counter logic has nothing to do with pixels. PPU A12 rises when the last PPU address AND $1000 = $0000, and the current PPU address AND $1000 = $1000. In the common application, it happens when the switches from reading background patterns at $0000-$0FFF and nametables at $2000-$2FFF to reading sprite patterns at $1000-$1FFF. You're right that the switch from background fetches to sprite fetches happens soon after HCOUNT=256. But if you implement it the right way the first time (based on PPU A12, not HCOUNT), it will save you grief later on when a game sets the background and sprites "backwards" or depends on a specific number of clocks to happen during the post-render, blanking, and pre-render lines.
Get it right, or some games won't run.
I thought my mapper doc explained it pretty well ;_;
Anyway in simple terms (disregarding all the A12 and technical details)
- Every render scanline (240 rendered scanlines + 1 prerender scanline... but not the 'idle' scanline or VBlank), if rendering is enabled (BG or sprites enabled), and if the BG/Sprites are using opposing pattern tables (can worry about this later, probably), the counter gets clocked.
- when the counter is clocked, if it is zero, it gets reloaded with the reload value. Otherwise it decrements. If it decrements from 1->0, and if IRQs are enabled, then an IRQ is "pending".
- And IRQ remains "pending" until "acknowledged". Acknowledging simply removes "pending" status.
- If at any time the 6502 I flag is clear, and an IRQ is pending, then an interrupt occurs. This isn't like NMIs which just fire once -- IRQs are constantly firing all the time when pending, and the only thing stopping them from occuring is the I flag.
Disch wrote:
I thought my mapper doc explained it pretty well ;_;
Your mapper docs are great, a gold resource to everyone. Anyway, I find some barriers while reading it - probably because of language.
As far as I know, there are two MMC3 IRQ timers, as blargg labeled them A and B. Well, I got B to work, but A is still pending... Be clear, anes, that you'll never get a single code for both types at same time.
ok, thanks a lot.
Disch: your docs? i didn't knew you had written one, where is it? Please tell me!!
I saw somebody post and deleted. I really don't know where the doc is. It is not in nesdev page, nor wiki and don't know if Disch has a web page. I searched google.
I put this becouse about the "lame question" thing.
Anes wrote:
I saw somebody post and deleted. I really don't know where the doc is. It is not in nesdev page, nor wiki and don't know if Disch has a web page. I searched google.
I put this becouse about the "lame question" thing.
I did it. When I do such thing, be clear - you didn't see anything, so it doesn't need any mention. My bad.
tepples wrote:
In my emulator, I have not yet added actual A12 based MMC3 scanline counting. However Kick Master works just fine. What other games supposively won't run?