mmc3 problems...

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
mmc3 problems...
by on (#2153)
i have some mmc3 problems (well i think they are a lot) and i wanna know if what im doing is alright, can someone help me?

Questions:
- Does 0xE000 and 0xE001 change the interrupt flag in the 6502 i mean the proccesor?

- when 0x8000 is written i check if .6 is set/clear and i swap memory (im actually using CopyMemory()) to the fixed bank

- when the command is 0x07 i always swap in 0xA000

- i dont understand well how interrupts work in mmc3, can someone explain me this topic, please.

I think i dont have cpu problems...
Problemes i have on games:

- a lot of games dont load
- some games throw me invalid opcodes (double dragon 2) does these games use undocumented opcodes?
- some games load, but they hang. (Megaman 3).

by on (#2155)
What about Super Mario Bros 2 ? That game worked perfectly fine here when I had preliminary MMC3 emulation (without interrupts).

by on (#2156)
hap wrote:
What about Super Mario Bros 2 ? That game worked perfectly fine here when I had preliminary MMC3 emulation (without interrupts).


AFAIK, SMB2 does not use MMC3 interrupt capabilities. Correct me if I'm wrong.
Re: mmc3 problems...
by on (#2157)
Anes wrote:
- Does 0xE000 and 0xE001 change the interrupt flag in the 6502 i mean the proccesor?


No. The only way to change the I flag in the 6502 is through opcodes like CLI/SEI/RTI/PLP (and I guess IRQ/NMI/Resets set the I flag -- but you know what I mean). These registers change the MMC3 IRQ enable flag (enabling/disabling MMC3 IRQ generation -- but not affecting the I flag on the 6502).

Quote:
- when 0x8000 is written i check if .6 is set/clear and i swap memory (im actually using CopyMemory()) to the fixed bank


Well I still think copying mem everytime the game bankswaps is a bad idea -- it'd be so much easier to just change a pointer. But anyway...

Anyway:

At any time when $8000.6 is clear:
$8000 is swapped to page X
$C000 is swapped to 2nd last PRG page in the ROM

At any time when $8000.6 is set:
$8000 is swapped to 2nd last PRG page in the ROM
$C000 is swapped to page X

Where "page X" is the value last written to $8001 in mode 6

Quote:
- when the command is 0x07 i always swap in 0xA000


That is correct

Quote:
- i dont understand well how interrupts work in mmc3, can someone explain me this topic, please.


Technically speaking, the IRQ counter decrements on every rising edge (0->1) of A12. Basically, under ideal conditions this happens once every rendered scanline on scanline cycle 260. When the IRQ counter becomes 0, an IRQ is fired. Kevtris doc covers other details quite well.

Every time there's a rising edge (again, basically this happens once a scanline -- but it can happen under other conditions as well):

if IRQ counter is 0, reload IRQ counter with reload value
else
{
decrement IRQ counter
if IRQ counter just became 0 and if MMC3 IRQs are enabled, raise 'IRQ pending' flag
}

if the IRQ pending flag is raised, IRQ are being fired nonstop until the flag is lowered (it is lowered with the IRQ is acknowledged -- as kevtris' doc puts it). Of course, IRQs fired by the MMC3 are ignored if the I flag is set -- but as soon as the I flag is cleared... you fire an IRQ if requested.

There is no way for the game to directly set the IRQ counter -- closest thing it can do is clear the IRQ counter by writing to $C001


EDIT:

Just realized I had my swap modes backwards -- whoopsie! Hopefully I didn't screw you up too much. Anyway I fixed them with this edit. $8000.6 clear makes $8000 swappable! Not the other way around.

by on (#2158)
One thing that needs to be pointed out is that, under normal circumstances, you will generally see eight rising edges on A12 per scanline (once per sprite tile fetch); however, the MMC3 applies some sort of filter so that it only detects the very first one.

by on (#2162)
thanks a lot for the help