About MMC3

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
About MMC3
by on (#123199)
1. wiki http://wiki.nesdev.com/w/index.php/MMC3 said MMC3 PRG Banks layout as following:
(-1) : the last bank, in a proper MMC3, the 63rd
(-2) : the penultimate bank; properly the 62nd

How to understand 62nd or 63rd?
For example, SMB3 has 16 INES 16KB-PRG Banks, wiki said PRG ROM bank size: 8 KB, so 8KB-PRG Banks are 16x2 = 32 that far less than 63.

2. Many games write mapper requesting a out of bonds PRG num and/or CHR num.
For example, Babel No Tou (J) can occur this problem when launch it.Following is my emulator's stdout:
8KB PRG 请求12越界 一共4
请按任意键继续. . .
8KB PRG 请求13越界 一共4
请按任意键继续. . .
2KB CHR 请求29越界 一共16
请按任意键继续. . .
2KB CHR 请求28越界 一共16
请按任意键继续. . .
2KB CHR 请求28越界 一共16
Above translate to
8KB PRG request 12 total 4
Press any key to continue...
8KB PRG request 13 total 4
Press any key to continue...
2KB CHR request 29 total 16
Press any key to continue...
2KB CHR request 28 total 16
Press any key to continue...
2KB CHR request 28 total 16
Press any key to continue...

Of course, I press again, emulator will cause Windows dialog popup and terminal process.
Re: About MMC3
by on (#123201)
Mask against the bank total in the rom in question.

For instance, if you have 32 prg banks in a particular rom, then you mask all prg bank numbers with 31:

63 & 31 = 31
62 & 31 => 30

That should answer both of your questions.


In general, this matches the real hardware behavior of ignoring high address lines when an undersize chip rom chip is used.
Re: About MMC3
by on (#123205)
natt wrote:
Mask against the bank total in the rom in question.

For instance, if you have 32 prg banks in a particular rom, then you mask all prg bank numbers with 31:

63 & 31 = 31
62 & 31 => 30

That should answer both of your questions.


In general, this matches the real hardware behavior of ignoring high address lines when an undersize chip rom chip is used.


1. Most of games run properly through that manner.
But there are few games still abnormal, Mighty Final Fight (J) status bar's tiles are incorrect, other games' problem like Mighty Final Fight.
2. I find a second problem, Mighty Final Fight (J) is 768KB actually, but according ines header the size only 256KB(8 x 16 KB PRGs, 16 x 8KB CHRs). There are many other games that files size are bigger that ines header described ones. What are extra file content ?
Re: About MMC3
by on (#123206)
Who knows what random crap someone stuffed in afterwards?

That 768KB dump is a bad dump: http://bootgod.dyndns.org:7777/profile.php?id=3745 says it should be only 256KB.

Anyway, the vast majority of NES games should be a power of 2 of PRG and a power of 2 of CHR.
Re: About MMC3
by on (#123211)
lidnariq wrote:
Who knows what random crap someone stuffed in afterwards?

That 768KB dump is a bad dump: http://bootgod.dyndns.org:7777/profile.php?id=3745 says it should be only 256KB.

Anyway, the vast majority of NES games should be a power of 2 of PRG and a power of 2 of CHR.


There is at least 1 mapper out that has a size that is not to the power of 2. It deals in 4 banks but selecting 0-1 selects the same bank.
Re: About MMC3
by on (#123237)
lidnariq wrote:
Who knows what random crap someone stuffed in afterwards?

That 768KB dump is a bad dump: http://bootgod.dyndns.org:7777/profile.php?id=3745 says it should be only 256KB.

Anyway, the vast majority of NES games should be a power of 2 of PRG and a power of 2 of CHR.


Yes, it's random crap stuffed thing we can ignore.
When I went to that page, I found another thing.
ROM Details
Type Label Size CRC32 x !

PRG0 CAP-SD-0 PRG 128 KB 9B74E080 1
CHR0 CAP-SD-0 CHR 128 KB 8BEE0B63 1

ROMs Combined: 256 KB 2B160BF0 1

When I load a rom file how to calculate the CRC32 value?
Re: About MMC3
by on (#123238)
It's the same CRC32 as what .zip files use. In linux I use the standalone program crc32 (part of CPAN Archive::Zip), but you can find libraries for whatever programming language you're using.
Re: About MMC3
by on (#125587)
Boolean wrote:
natt wrote:
Mask against the bank total in the rom in question.

For instance, if you have 32 prg banks in a particular rom, then you mask all prg bank numbers with 31:

63 & 31 = 31
62 & 31 => 30

That should answer both of your questions.


In general, this matches the real hardware behavior of ignoring high address lines when an undersize chip rom chip is used.


1. Most of games run properly through that way.
But there are few games still abnormal, Mighty Final Fight (J) status bar's tiles are incorrect, other games' problem like Mighty Final Fight.
2. I find a second problem, Mighty Final Fight (J) is 768KB actually, but according ines header the size only 256KB(8 x 16 KB PRGs, 16 x 8KB CHRs). There are many other games that files size are bigger that ines header described ones. What are extra file content ?



I find another problem about above.
When run loopy's SMB2Jhttp://home.comcast.net/~olimar/NES/smb2j_mmc3.zip, the emulator graphics is totally wrong.
The games is a battery-back ROM.When access CPU memory address $6000 ~ $7FFF, the emulator will save game status to local filesystem, which make emulator FPS very low(1 ~ 2 FPS).
I edit ROM header to make it without battery so that game can be run normal speed, then I find the graphics problem.

About MMC3, my understanding must have problem, please correct me.
1. Write $8000, address $8000-$9FFF(or $C000-$DFFF) is fixed to second-last bank
2. Write $8001, anded $07 with data last write to $8000 as command and switch bank according to command
Re: About MMC3
by on (#125605)
WedNESday wrote:
lidnariq wrote:
Who knows what random crap someone stuffed in afterwards?

That 768KB dump is a bad dump: http://bootgod.dyndns.org:7777/profile.php?id=3745 says it should be only 256KB.

Anyway, the vast majority of NES games should be a power of 2 of PRG and a power of 2 of CHR.


There is at least 1 mapper out that has a size that is not to the power of 2. It deals in 4 banks but selecting 0-1 selects the same bank.


I think you might refer to Action 52 whose cart contain 3 x 512KB chips which are spread over 2MB of memory as follows, chip1 - chip2 - 512KB of 0xff - chip3

other not-power-of-two games are some pirate conversions from FDS, which has 32K (or other power of 2) of PRG + 2K of PRG mapped in the $6000-$7fff range
Re: About MMC3
by on (#125698)
Boolean wrote:
The games is a battery-back ROM.When access CPU memory address $6000 ~ $7FFF, the emulator will save game status to local filesystem, which make emulator FPS very low(1 ~ 2 FPS).

If you're saving SRAM to disk on every write, you're doing it wrong - you should only be doing that when you unload the ROM image (i.e. when you close the emulator, or when you load a different game), and possibly also whenever you pause emulation.
Re: About MMC3
by on (#125703)
That and save periodically in a background thread in case the operating system or the power company kills your emulator process.
Re: About MMC3
by on (#125849)
tepples wrote:
That and save periodically in a background thread in case the operating system or the power company kills your emulator process.

That can do it. In fact, the emulator is a Win32 Console Application and only has one thread. It hard to controlling multiple threads. For now, you know, the biggest problem is APU emulated and I am doing it.
Re: About MMC3
by on (#125851)
Quietust wrote:
Boolean wrote:
The games is a battery-back ROM.When access CPU memory address $6000 ~ $7FFF, the emulator will save game status to local filesystem, which make emulator FPS very low(1 ~ 2 FPS).

If you're saving SRAM to disk on every write, you're doing it wrong - you should only be doing that when you unload the ROM image (i.e. when you close the emulator, or when you load a different game), and possibly also whenever you pause emulation.

I know what you mean.
Wiki describes $6000-$7FFF = Battery Backed Save or Work RAM.
What I think as following:
1. If ROM has a battery, then ROM must have a Static RAM(SRAM). The SRAM power is proviced by the battery and maintains its data.
2. If ROM has not a battery, then ROM either contains or doesn't contain a SRAM. If ROM accesses $6000-$7FFF, then it must contain a SRAM, otherwise ROM either contains or doesn't contain a SRAM(We can consider it don't contain). If ROM exists a SRAM, then NES board provides power to the SRAM. Once NES power-off, the SRAM data is missing.
Re: About MMC3
by on (#125854)
Boolean wrote:
If ROM accesses $6000-$7FFF, then it must contain a SRAM
There is at least one game that relies on $6000-$7FFF not containing RAM.
Re: About MMC3
by on (#126004)
lidnariq wrote:
Boolean wrote:
If ROM accesses $6000-$7FFF, then it must contain a SRAM
There is at least one game that relies on $6000-$7FFF not containing RAM.

For emulator CPU address $6000-7FFF, I decide to create one RAM no matter if it will be used. If ROMs contain a battery, save RAM to file when game exit or load saved file (if any) to RAM when game launch.
Re: About MMC3
by on (#126009)
Boolean wrote:
For emulator CPU address $6000-7FFF, I decide to create one RAM no matter if it will be used.

Yes, that's how most emulators work, but the point is that this one game, Low G Man, will not work if it finds RAM at $6000-$7FFF. It's a rudimentary form of copy protection or something like that.
Re: About MMC3
by on (#126021)
Boolean wrote:
For emulator CPU address $6000-7FFF, I decide to create one RAM no matter if it will be used. If ROMs contain a battery, save RAM to file when game exit or load saved file (if any) to RAM when game launch.
The NES 2.0 header can tell you whether or not it has RAM, and how much, if it is less than 8K. Therefore you can tell if it is RAM or not. For older iNES headers, it could be chosen based on which mappers have PRG RAM, and/or to always put RAM if the battery bit is set, since that bit otherwise won't do anything; or you can require Low G Man to be converted to NES 2.0 headers before they will work.
Re: About MMC3
by on (#126042)
Does Low G Man write to the WRAM protection register? I know a lot of emulators that don't support NES 2.0 will ignore writes to the WRAM protection register so that they can support MMC6 games (StarTropics and StarTropics 2).
Re: About MMC3
by on (#126070)
tepples wrote:
Does Low G Man write to the WRAM protection register?
Yes, but with a nonsensical value (0x01).
At address $F43A (file offset 0x1f44a):
Code:
        ldx     #$00
        stx     $2005
        stx     $2005
        stx     $E000
        stx     $4010
        inx
        stx     $A000
        lda     #$0F
        sta     $4015
        lda     #$40
        sta     $4017
        stx     $A001
This is the only location in PRG that matches the regexp '[\x8C-\x8E]\x01\xA0'.
Re: About MMC3
by on (#126075)
Based on how I understand PRG RAM protection, that value isn't nonsensical. Any value in $00-$7F should disable the PRG RAM entirely. Emulators that don't respond are probably applying a hack to run StarTropics without CRCs and without NES 2.0.
Re: About MMC3
by on (#126078)
This is part of the power-on reset code. By proximity, there's no reason to have written 1 instead of 0 (or $15, or $40)...

But, in any case, Low G Man works correctly if I disable nestopia's hash and have it treat the game as TSROM instead of TLROM.

This is actually in Disch's notes.
Re: About MMC3
by on (#126135)
zzo38 wrote:
Boolean wrote:
For emulator CPU address $6000-7FFF, I decide to create one RAM no matter if it will be used. If ROMs contain a battery, save RAM to file when game exit or load saved file (if any) to RAM when game launch.
The NES 2.0 header can tell you whether or not it has RAM, and how much, if it is less than 8K. Therefore you can tell if it is RAM or not. For older iNES headers, it could be chosen based on which mappers have PRG RAM, and/or to always put RAM if the battery bit is set, since that bit otherwise won't do anything; or you can require Low G Man to be converted to NES 2.0 headers before they will work.

Sounds good.I should learn about NES 2.0
Re: About MMC3
by on (#126136)
tokumaru wrote:
Boolean wrote:
For emulator CPU address $6000-7FFF, I decide to create one RAM no matter if it will be used.

Yes, that's how most emulators work, but the point is that this one game, Low G Man, will not work if it finds RAM at $6000-$7FFF. It's a rudimentary form of copy protection or something like that.

Does the game write $6000-7FFF, then read and compare read value with written value?
Re: About MMC3
by on (#126137)
lidnariq wrote:
tepples wrote:
Does Low G Man write to the WRAM protection register?
Yes, but with a nonsensical value (0x01).
At address $F43A (file offset 0x1f44a):
Code:
        ldx     #$00
        stx     $2005
        stx     $2005
        stx     $E000
        stx     $4010
        inx
        stx     $A000
        lda     #$0F
        sta     $4015
        lda     #$40
        sta     $4017
        stx     $A001
This is the only location in PRG that matches the regexp '[\x8C-\x8E]\x01\xA0'.

1. What is the meaning of regexp '[\x8C-\x8E]\x01\xA0' ?
2. This code only write $A001 with $01. Both bit 7 and bit 6 are 0, so write protection will not be triggered.
7 bit 0
---- ----
RWxx xxxx
||
|+-------- Write protection (0: allow writes; 1: deny writes)
+--------- Chip enable (0: disable chip; 1: enable chip)
Re: About MMC3
by on (#126138)
Boolean wrote:
lidnariq wrote:
tepples wrote:
Does Low G Man write to the WRAM protection register?
Yes, but with a nonsensical value (0x01).
At address $F43A (file offset 0x1f44a):
Code:
        ldx     #$00
        stx     $2005
        stx     $2005
        stx     $E000
        stx     $4010
        inx
        stx     $A000
        lda     #$0F
        sta     $4015
        lda     #$40
        sta     $4017
        stx     $A001
This is the only location in PRG that matches the regexp '[\x8C-\x8E]\x01\xA0'.

1. What is the meaning of regexp '[\x8C-\x8E]\x01\xA0' ?
2. This code only write $A001 with $01. Both bit 7 and bit 6 are 0, so write protection will not be triggered.
7 bit 0
---- ----
RWxx xxxx
||
|+-------- Write protection (0: allow writes; 1: deny writes)
+--------- Chip enable (0: disable chip; 1: enable chip)


I understand question 2. Bit 7 is 0, chip is not available.
Re: About MMC3
by on (#126143)
Boolean wrote:
1. What is the meaning of regexp '[\x8C-\x8E]\x01\xA0' ?

regexp (or regex) is short for regular expression (Chinese). The [\x8C-\x8E]\x01\xA0 regex means, in english, "Match a byte that has a value from 0x8C to 0x8E that is followed by 0x01 and 0xA0". Regexes are normally used for text string search but they can be used to find a binary string.
Re: About MMC3
by on (#126221)
Jarhmander wrote:
Boolean wrote:
1. What is the meaning of regexp '[\x8C-\x8E]\x01\xA0' ?

regexp (or regex) is short for regular expression (Chinese). The [\x8C-\x8E]\x01\xA0 regex means, in english, "Match a byte that has a value from 0x8C to 0x8E that is followed by 0x01 and 0xA0". Regexes are normally used for text string search but they can be used to find a binary string.

Thank you.But it seems ...
[\x8C-\x8E]\x01\xA0 stands for 0x8C 0x01 0xA0 or 0x8D 0x01 0xA0 or 0x8E 0x01 0xA0.
To MMC3, only stx $E000(x == 0), stx $A000(x == 1) and stx $A001(x == 1) instructions are useful.
What is the relation between [\x8C-\x8E]\x01\xA0 and the instructions?
Re: About MMC3
by on (#126222)
Boolean wrote:
What is the relation between [\x8C-\x8E]\x01\xA0 and the instructions?
To the 6502, the instructions STY abs, STA abs, and STX abs are represented by the bytes sequence starting with $8C, $8D, and $8E respectively.
That is, 0x8E 0x01 0xA0 = STX $A001
Re: About MMC3
by on (#126255)
lidnariq wrote:
Boolean wrote:
What is the relation between [\x8C-\x8E]\x01\xA0 and the instructions?
To the 6502, the instructions STY abs, STA abs, and STX abs are represented by the bytes sequence starting with $8C, $8D, and $8E respectively.
That is, 0x8E 0x01 0xA0 = STX $A001

Thank you.