https://www.nesdev.org/w/api.php?action=feedcontributions&user=Zeromus&feedformat=atomNESdev Wiki - User contributions [en]2024-03-29T16:00:24ZUser contributionsMediaWiki 1.39.0https://www.nesdev.org/w/index.php?title=INES_Mapper_210&diff=5660INES Mapper 2102021-02-10T03:55:23Z<p>Zeromus: add Naruko's blog's post on mirroring on the 340 from the mapper 019 page, and update the $E000 register mirroring bits to match those docs (which I corroborated by investigating wagyan 2 bugs; I checked dream master and famitsu '92 to ensure still workin</p>
<hr />
<div>{{DEFAULTSORT:210}}{{Infobox_iNES_mapper<br />
|name=Namco 175<br />
|company=Namco<br />
|mapper=210<br />
|nescartdbgames=4<br />
|boards=110F0B<br />
|complexity=ASIC<br />
|prgmax=512K<br />
|prgpage=8Kx3 + 8K fixed<br />
|wrammax=8K<br />
|wrampage=8K<br />
|chrmax=256K<br />
|chrpage=1Kx8<br />
|mirroring=H or V fixed<br />
|busconflicts=No<br />
|irq=No<br />
|audio=No<br />
}}{{Infobox_iNES_mapper<br />
|name=Namco 340<br />
|company=Namco<br />
|mapper=210<br />
|nescartdbgames=8<br />
|boards=CS000x<br />
|complexity=ASIC<br />
|prgmax=512K<br />
|prgpage=8Kx3 + 8K fixed<br />
|wrammax=none<br />
|wrampage=none<br />
|chrmax=256K<br />
|chrpage=1Kx8<br />
|mirroring=H, V, or 1 switchable<br />
|busconflicts=No<br />
|irq=No<br />
|audio=No<br />
}}<br />
iNES Mapper 210 is used to denote Famicom boards bearing either the Namco 175 (Submapper 1) or Namco 340 (Submapper 2) ASIC. Both can be thought of as cost-reduced versions of the [[INES Mapper 019|Namco 163]]:<br />
{| class="wikitable"<br />
! Function !! N163 !! N175 !! N340<br />
|-<br />
|IRQ counter || Yes || No || No<br />
|-<br />
|ROM nametables || Yes || No || No<br />
|-<br />
|Optional WRAM || Yes || Yes || No<br />
|-<br />
|Expansion audio || Yes || No || No<br />
|-<br />
|ASIC-internal RAM || Yes || No || No<br />
|-<br />
|Mirroring || Selectable (extended) || Hard-wired H/V || Selectable H/V/0<br />
|-<br />
|}<br />
<br />
==Game list==<br />
===Namco 175 (Submapper 1)===<br />
{| class="wikitable sortable"<br />
! Name !! Battery !! WRAM !! Mirroring<br />
|-<br />
| Chibi Maruko-chan: Uki Uki Shopping || No || No || V<br />
|-<br />
| Dream Master || No || No || H<br />
|-<br />
| Family Circuit '91 || Yes || 2 KiB || V<br />
|-<br />
| Famista '91 || No || No || V<br />
|-<br />
| Heisei Tensai Bakabon || No || No || V<br />
|}<br />
===Namco 340 (Submapper 2)===<br />
* Famista '92<br />
* Famista '93<br />
* Famista '94<br />
* Splatterhouse: Wanpaku Graffiti<br />
* Top Striker<br />
* Wagyan Land 2<br />
* Wagyan Land 3<br />
<br />
== Banks ==<br />
* CPU $6000-$7FFF: 2 KB PRG RAM bank, mirrored four times (Namco 175 only)<br />
* CPU $8000-$9FFF: 8 KB switchable PRG ROM bank<br />
* CPU $A000-$BFFF: 8 KB switchable PRG ROM bank<br />
* CPU $C000-$DFFF: 8 KB switchable PRG ROM bank<br />
* CPU $E000-$FFFF: 8 KB PRG ROM bank, fixed to the last bank<br />
* PPU $0000-$03FF: 1 KB switchable CHR bank<br />
* PPU $0400-$07FF: 1 KB switchable CHR bank<br />
* PPU $0800-$0BFF: 1 KB switchable CHR bank<br />
* PPU $0C00-$0FFF: 1 KB switchable CHR bank<br />
* PPU $1000-$13FF: 1 KB switchable CHR bank<br />
* PPU $1400-$17FF: 1 KB switchable CHR bank<br />
* PPU $1800-$1BFF: 1 KB switchable CHR bank<br />
* PPU $1C00-$1FFF: 1 KB switchable CHR bank<br />
<br />
== Registers ==<br />
The 175 and 340 have 12 registers within $8000-$FFFF. Each register occupies a range of $800 bytes, so $8000-$87FF all refers to one register, $8800-$8FFF all refers to another register, and so on.<br />
<br />
=== CHR Select ($8000-$BFFF) w ===<br />
{| class="wikitable"<br />
! Value CPU writes !! Behavior<br />
|-<br />
| $00-$FF || Selects 1KB page of CHR-ROM<br />
|}<br />
{| class="wikitable"<br />
! Write to CPU address !! 1KB CHR bank affected<br />
|-<br />
| $8000-$87FF || $0000-$03FF<br />
|-<br />
| $8800-$8FFF || $0400-$07FF<br />
|-<br />
| $9000-$97FF || $0800-$0BFF<br />
|-<br />
| $9800-$9FFF || $0C00-$0FFF<br />
|-<br />
| $A000-$A7FF || $1000-$13FF<br />
|-<br />
| $A800-$AFFF || $1400-$17FF<br />
|-<br />
| $B000-$B7FF || $1800-$1BFF<br />
|-<br />
| $B800-$BFFF || $1C00-$1FFF<br />
|}<br />
<br />
=== External PRG RAM enable ($C000-$C7FF) w (Namco 175 only) ===<br />
7 bit 0<br />
---- ----<br />
.... ...E<br />
|<br />
+- 1: Enable PRG RAM<br />
<br />
=== PRG Select 1 ($E000-$E7FF) w ===<br />
7 bit 0<br />
---- ----<br />
MMPP PPPP<br />
|||| ||||<br />
||++-++++- Select 8KB page of PRG-ROM at $8000<br />
++-------- Namco 340 only: Select mirroring<br />
0: One-screen A<br />
1: Vertical<br />
2: One-screen B<br />
3: Horizontal<br />
<br />
=== PRG Select 2 ($E800-$EFFF) w ===<br />
7 bit 0<br />
---- ----<br />
..PP PPPP<br />
|| ||||<br />
++-++++- Select 8KB page of PRG-ROM at $A000<br />
<br />
=== PRG Select 3 ($F000-$F7FF) w ===<br />
7 bit 0<br />
---- ----<br />
..PP PPPP<br />
|| ||||<br />
++-++++- Select 8KB page of PRG-ROM at $C000<br />
<br />
==Notes==<br />
* ''Family Circuit '91'' relies on its 2 KiB of WRAM being correctly mirrored throughout the $6000-$7FFF address range.<br />
* Many INES Mapper 210 games are incorrectly set to [[INES Mapper 019]].<br />
* In the absence of a NES 2.0 header with submapper 1 or 2 to distinguish between Namco 175 and 340, the following heuristics have been suggested:<br />
** If $E000.6 or $E000.7 are ever set, this should be a Namcot 340.<br />
** If the game ever reads from or writes to PRG RAM, this is a Namco 175 with external RAM.<br />
** If the game ever writes to $C000, this is probably a Namco 175.<br />
<br />
== See also ==<br />
*[http://d.hatena.ne.jp/na6ko/20110501/1304181038 Naruko's blog's post on mirroring on the 340]<br />
<br />
[[Category:ASIC mappers]][[Category:Mappers with single-screen mirroring]]</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_019&diff=3949INES Mapper 0192021-02-10T03:52:53Z<p>Zeromus: moving Naruko's blog's post on mirroring on the 340 to the mapper 210 page</p>
<hr />
<div>{{DEFAULTSORT:019}}[[Category:Mappers with CHR ROM and CHR RAM]]<br />
{{Infobox_iNES_mapper<br />
|name=Namco 129/163<br />
|company=Namco<br />
|mapper=19<br />
|nescartdbgames=20<br />
|boards=11xF0, 111F0S<br />
|pinout=Namcot 163 family pinout<br />
|complexity=ASIC<br />
|prgmax=512K<br />
|prgpage=8Kx3 + 8K fixed<br />
|wrammax=8K<br />
|wrampage=8K<br />
|chrmax=256K<br />
|chrpage=1Kx8 (PT) + 1Kx4 (NT)<br />
|mirroring=arbitrary, up to 226 source nametables<br />
|busconflicts=No<br />
|irq=CPU cycle counter<br />
|audio=[[Namco_163_audio|Yes]]<br />
}}<br />
'''iNES Mapper 019''' is used to denote Famicom boards bearing the '''Namco 129''' and '''Namco 163''' ASICs. These chips contain 128 bytes of internal RAM that can be used either for [[Namco 163 audio|expansion audio]] or, together with a battery, for 128 bytes of save RAM. Games may also come with the regular 8 KiB of additional battery-backed WRAM mapped into CPU address space at $6000-$7FFF. <br />
<br />
In [[NES 2.0]], the 128 bytes of internal chip RAM are not included in the PRG-RAM and PRG-NVRAM fields. NES 2.0 Mapper 19 ROM images therefore either have:<br />
* no battery and no WRAM: battery bit clear, PRG-RAM/PRG-NVRAM both set to zero.<br />
* a battery but no WRAM: battery bit set, PRG-RAM/PRG-NVRAM both set to zero. The game writes its save data into the 128 byte internal RAM.<br />
* a battery and WRAM: battery bit set, PRG-RAM set to zero and PRG-NVRAM set to 8192.<br />
The NES 2.0 submapper is used to specify the mixing resistor that determines the relative volume of the expansion audio channels against the [[APU]]'s audio channels:<br />
{{:INES Mapper 019/Submapper table}}<br />
<br />
==Game list==<br />
{| class="wikitable sortable"<br />
! Name !! Chip !! Battery !! WRAM !! Expansion Audio !! NES 2.0 Submapper<br />
|-<br />
|''Battle Fleet'' || 163 || Yes || No || No || 2<br />
|-<br />
|''Dragon Ninja'' || 163 || No || No || No || 2<br />
|-<br />
|''Digital Devil Story: Megami Tensei II'' || 163 || Yes || Yes || Yes || 3<br />
|-<br />
|''Dokuganryuu Masamune'' || 163 || Yes || No || No || 2<br />
|-<br />
|''Erika to Satoru no Yume Bouken'' || 163 || No || No || Yes || 5<br />
|-<br />
|''Famista '90'' || 163 || Yes || No || No || 2<br />
|-<br />
|''Final Lap'' || 163 || No || No || Yes || 3<br />
|-<br />
|''Hydlide 3: Yami kara no Houmonsha'' || 163 || Yes || No || No || 2<br />
|-<br />
|''Juvei Quest'' || 163 || Yes || Yes || No || 2<br />
|-<br />
|''Kaijuu Monogatari'' || 163 || Yes || No || No || 2<br />
|-<br />
|''King of Kings'' || 163 || Yes || Yes || Yes || 5<br />
|-<br />
|''Mappy Kids'' || 163 || No || No || Yes || 5<br />
|-<br />
|''Mindseeker'' || 163 || Yes || No || No || 2<br />
|-<br />
|''Namco Classic'' || 163 || No || No || No || 2<br />
|-<br />
|''Namco Classic II'' || 163 || No || No || Yes || 3<br />
|-<br />
|''Rolling Thunder'' || 163 || No || No || Yes || 4<br />
|-<br />
|''Sangokushi: Chuugen no Hasha'' || 163 || Yes || Yes || Yes || 5<br />
|-<br />
|''Sangokushi II: Haou no Tairiku'' || 163 || Yes || Yes || Yes || 3<br />
|-<br />
|''Star Wars'' || 129 || No || No || No || 2<br />
|-<br />
|''Youkai Douchuuki'' || 163 || No || No || Yes || 5<br />
|-<br />
|}<br />
<br />
== Banks ==<br />
* CPU $6000-$7FFF: 8 KB PRG RAM bank, if WRAM is present<br />
* CPU $8000-$9FFF: 8 KB switchable PRG ROM bank<br />
* CPU $A000-$BFFF: 8 KB switchable PRG ROM bank<br />
* CPU $C000-$DFFF: 8 KB switchable PRG ROM bank<br />
* CPU $E000-$FFFF: 8 KB PRG ROM bank, fixed to the last bank<br />
* PPU $0000-$03FF: 1 KB switchable CHR bank<br />
* PPU $0400-$07FF: 1 KB switchable CHR bank<br />
* PPU $0800-$0BFF: 1 KB switchable CHR bank<br />
* PPU $0C00-$0FFF: 1 KB switchable CHR bank<br />
* PPU $1000-$13FF: 1 KB switchable CHR bank<br />
* PPU $1400-$17FF: 1 KB switchable CHR bank<br />
* PPU $1800-$1BFF: 1 KB switchable CHR bank<br />
* PPU $1C00-$1FFF: 1 KB switchable CHR bank<br />
* PPU $2000-$23FF: 1 KB switchable CHR bank<br />
* PPU $2400-$27FF: 1 KB switchable CHR bank<br />
* PPU $2800-$2BFF: 1 KB switchable CHR bank<br />
* PPU $2C00-$2FFF: 1 KB switchable CHR bank<br />
<br />
These ASICs have the unusual ability to select the internal 2 KB nametable RAM as a CHR bank page, allowing it to be used as CHR RAM in combination with the existing CHR ROM.<br />
<br />
== Registers ==<br />
The 163 has 19 registers within $4800-$5FFF and $8000-$FFFF. Each register occupies a range of $800 bytes, so $4800-$4FFF all refers to one register, $5000-$57FF all refers to another register, and so on.<br />
<br />
=== Chip RAM Data Port ($4800-$4FFF) r/w ===<br />
See [[Namco 163 audio]].<br />
<br />
=== IRQ Counter (low) ($5000-$57FF) r/w ===<br />
7 bit 0<br />
---- ----<br />
IIII IIII<br />
|||| ||||<br />
++++-++++- Low 8 bits of IRQ counter<br />
<br />
=== IRQ Counter (high) / IRQ Enable ($5800-$5FFF) r/w ===<br />
7 bit 0<br />
---- ----<br />
EIII IIII<br />
|||| ||||<br />
|+++-++++- High 7 bits of IRQ counter<br />
+--------- IRQ Enable: (0: disabled; 1: enabled)<br />
<br />
=== CHR and NT Select ($8000-$DFFF) w ===<br />
<br />
{| class="wikitable"<br />
! Value CPU writes !! Behavior<br />
|-<br />
| $00-$DF || Always selects 1KB page of CHR-ROM<br />
|-<br />
| $E0-$FF || If enabled by bit in $E800, use the NES's internal nametables (even values for A, odd values for B)<br />
|}<br />
{| class="wikitable"<br />
! Write to CPU address !! 1KB CHR bank affected !! Values ≥ $E0 denote NES NTRAM if<br />
|-<br />
| $8000-$87FF || $0000-$03FF || $E800.6 = 0<br />
|-<br />
| $8800-$8FFF || $0400-$07FF || $E800.6 = 0<br />
|-<br />
| $9000-$97FF || $0800-$0BFF || $E800.6 = 0<br />
|-<br />
| $9800-$9FFF || $0C00-$0FFF || $E800.6 = 0<br />
|-<br />
| $A000-$A7FF || $1000-$13FF || $E800.7 = 0<br />
|-<br />
| $A800-$AFFF || $1400-$17FF || $E800.7 = 0<br />
|-<br />
| $B000-$B7FF || $1800-$1BFF || $E800.7 = 0<br />
|-<br />
| $B800-$BFFF || $1C00-$1FFF || $E800.7 = 0<br />
|-<br />
| $C000-$C7FF || $2000-$23FF || always<br />
|-<br />
| $C800-$CFFF || $2400-$27FF || always<br />
|-<br />
| $D000-$D7FF || $2800-$2BFF || always<br />
|-<br />
| $D800-$DFFF || $2C00-$2FFF || always<br />
|}<br />
It is believed, but untested, that a game could add a normal SRAM and use it in lieu of the nametable RAM; if so, a game would be able to get 4-screen mirroring and many more pages of CHR-RAM.<br />
<br />
=== PRG Select 1 ($E000-$E7FF) w ===<br />
7 bit 0<br />
---- ----<br />
AMPP PPPP<br />
|||| ||||<br />
||++-++++- Select 8KB page of PRG-ROM at $8000<br />
|+-------- Disable sound if set<br />
+--------- Pin 22 (open collector) reflects the inverse of this value, unchanged by the address bus inputs.<br />
<br />
=== PRG Select 2 / CHR-RAM Enable ($E800-$EFFF) w ===<br />
7 bit 0<br />
---- ----<br />
HLPP PPPP<br />
|||| ||||<br />
||++-++++- Select 8KB page of PRG-ROM at $A000<br />
|+-------- Disable CHR-RAM at $0000-$0FFF<br />
| 0: Pages $E0-$FF use NT RAM as CHR-RAM<br />
| 1: Pages $E0-$FF are the last $20 banks of CHR-ROM<br />
+--------- Disable CHR-RAM at $1000-$1FFF<br />
0: Pages $E0-$FF use NT RAM as CHR-RAM<br />
1: Pages $E0-$FF are the last $20 banks of CHR-ROM<br />
<br />
=== PRG Select 3 ($F000-$F7FF) w ===<br />
7 bit 0<br />
---- ----<br />
B.PP PPPP<br />
| || ||||<br />
| ++-++++- Select 8KB page of PRG-ROM at $C000<br />
+--------- Pin 44 reflects this value.<br />
<br />
=== Write Protect for External RAM AND Chip RAM Address Port ($F800-$FFFF) w ===<br />
7 bit 0<br />
---- ----<br />
KKKK DCBA<br />
|||| ||||<br />
|||| |||+- 1: Write-protect 2kB window of external RAM from $6000-$67FF (0: write enable)<br />
|||| ||+-- 1: Write-protect 2kB window of external RAM from $6800-$6FFF (0: write enable)<br />
|||| |+--- 1: Write-protect 2kB window of external RAM from $7000-$77FF (0: write enable)<br />
|||| +---- 1: Write-protect 2kB window of external RAM from $7800-$7FFF (0: write enable)<br />
++++------ Additionally the upper nybble must be equal to b0100 to enable writes<br />
<br />
Any value outside of the range $40-$4E will cause all PRG RAM to be read-only.<br />
<br />
Also see [[Namco 163 audio]].<br />
<br />
== IRQ Operation ==<br />
The IRQ is a 15-bit CPU cycle up-counter. $5000 and $5800 provide ''direct'' access to the counter itself (i.e., this isn't a reload value). Games can read and write to these registers in realtime.<br />
<br />
The IRQ counter increments on each CPU cycle. Upon reaching $7FFF, an IRQ is fired, and it stops counting. Writing to $5000 or $5800 will acknowledge any pending IRQs.<br />
<br />
==Notes==<br />
* Many older programs incorrectly identify this mapper by the name Namco 106. Some sources use the name Namcot instead of Namco, as some games and PCBs use this variation on the company name.<br />
* The N163 supports 8k of PRG-RAM but also has 128 bytes of internal memory. If there is a battery, then both will be battery backed. The internal memory is battery backed for several games that have no additional PRG-RAM.<br />
* The only known difference between the Namco 129 and 163 is the 129's faulty implementation of expansion audio. The only known game (Star Wars) using the Namco 129 can also be found in later runs with a Namco 163 ASIC.<br />
* An IC labelled "160" has been found with a copy of ''Dokuganryuu Masamune'': [https://forums.nesdev.org/viewtopic.php?p=248291#p248291]<br />
* Many [[INES Mapper 210]] games are incorrectly set to Mapper 019.<br />
* ''Dokuganryuu Masamune'' is often thought as having WRAM. Tests have indicated however that the fourth glob is not SRAM but a [http://forums.nesdev.org/viewtopic.php?t=7727#p111097 protection circuit for the chip-internal RAM].<br />
<br />
== See also ==<br />
*[http://nesdev.org/namco106.txt Namcot 106] by goroh, fix by ZW4 and nori, english translation by nori.<br />
*[http://nesdev.org/mappers.zip Comprehensive NES Mapper Document] by \Firebug\, information about mapper's initial state is inaccurate.<br />
All of the below are in Japanese:<br />
*[http://nesdev.org/namco.txt Namco mapper] by goroh<br />
*[http://forums.nesdev.org/viewtopic.php?p=77795#77795 Naruko's post to the forum]<br />
*[http://unagi.sourceforge.jp/cgi-bin/hiki/hiki.cgi?163_namco Wiki on same]<br />
*[http://d.hatena.ne.jp/na6ko/20110430/1304099059 Naruko's blog's post on the write protect register at $F800]<br />
[[Category:Mappers using $4020-$5FFF]][[Category:ASIC mappers]][[Category:Mappers with ROM nametables]][[Category:Mappers with cycle IRQs]][[Category:Mappers with single-screen mirroring]]</div>Zeromushttps://www.nesdev.org/w/index.php?title=MMC5&diff=6775MMC52019-10-09T05:57:36Z<p>Zeromus: /* Scanline Detection and Scanline IRQ */</p>
<hr />
<div>{{Infobox iNES mapper<br />
|name=MMC5<br />
|name2=ExROM<br />
|company=Nintendo, Koei, others<br />
|mapper=5<br />
|nescartdbgames=15<br />
|complexity=ASIC<br />
|boards=EKROM, ELROM,<br/>ETROM, EWROM<br />
|pinout=MMC5 pinout<br />
|prgmax=1024K<br />
|prgpage=8K, 16K, or 32K<br />
|wrammax=128K<br />
|wrampage=8K ($6000-$DFFF),<br/>16K (only $8000-$BFFF<br />at PRG mode 1/2)<br />
|chrmax=1024K<br />
|chrpage=1K, 2K, 4K, or 8K<br />
|mirroring=arbitrary, up to 3 source<br />nametables (plus fill mode)<br />
|busconflicts=No<br />
|irq=Yes<br />
|audio=[[MMC5_audio|Yes]]<br />
}}<br />
{{nesdbbox<br />
|ines|5|iNES 005<br />
|unif_wild|-E%ROM|ExROM<br />
|unif_wild|EKROM|EKROM<br />
|unif_wild|ELROM|ELROM<br />
|unif_wild|ETROM|ETROM<br />
|unif_wild|EWROM|EWROM<br />
}}<br />
[[Category:Nintendo licensed mappers]][[Category:Mappers using $4020-$5FFF]][[Category:Mappers with large PRG RAM]][[Category:Mappers with scanline IRQs]][[Category:Mappers with single-screen mirroring]][[Category:Mappers with cycle IRQs]]<br />
The '''Nintendo MMC5''' is a [[mapper]] [[:Category:ASIC mappers|ASIC]] used in Nintendo's [[ExROM]] Game Pak boards. All MMC5 boards are assigned to '''mapper 5'''.<br />
<br />
Example games:<br />
* ''Castlevania 3''<br />
* ''Just Breed''<br />
* ''Uncharted Waters''<br />
* ''Romance of the Three Kingdoms II''<br />
* ''Laser Invasion''<br />
* ''Metal Slader Glory''<br />
* ''Uchuu Keibitai SDF''<br />
* ''Shin 4 Nin Uchi Mahjong - Yakuman Tengoku''<br />
* ''Bandit Kings of Ancient China''<br />
<br />
The first game to use this chip (''Nobunaga's Ambition II'') was released in February 1990. The [http://bootgod.dyndns.org:7777/profile.php?id=3169 date codes on components on early released cartridges] show that manufacturing had started at the end of 1989.<br />
<br />
== Overview ==<br />
The MMC5 is the most powerful mapper ASIC Nintendo made for the NES and Famicom.<br />
<br />
It supports many advanced features, including:<br />
* 4 PRG ROM switching modes<br />
* 4 CHR ROM switching modes<br />
* Up to 128KB of WRAM, mappable not only at $6000-$7FFF but also within $8000-$DFFF<br />
** Supports either one chip (up to 128KB) or two chips (up to 32KB each)<br />
* An 8 bit by 8 bit multiplier with a 16 bit result for performing quick calculations<br />
* Scanline detection with counter and configurable IRQ<br />
* Frame detection with status bit<br />
* The ability to use different CHR banks for background and 8x16 sprites (allowing 256 unique 8x16 sprite tiles, independent of the background).<br />
* 1024 bytes of on-chip memory, which can be used for 4 different purposes:<br />
** An extra general-use nametable<br />
** Attribute and tile index expansion - address 16384 background tiles at once, and allow each individual 8x8 tile to have its own palette setting<br />
** Vertical split-screen<br />
** Extra RAM for storing program variables<br />
* Three extra sound channels<br />
** Two pulse channels, identical to those in the NES APU (except lacking pitch sweeps).<br />
** An 8-bit RAW PCM channel<br />
* A 'fill mode' nametable, which can be instantly set to contain a specific tile in a specific color (useful for screen transitions)<br />
* System reset detection<br />
** Triggered by a positive or negative gap in M2 of at least 11.2 usec.<br />
** Also triggered and latched by absence of AVcc.<br />
** After reapplying AVcc, another gap in M2 is sometimes necessary to clear the latch.<br />
** This feature resets some, but not all, states of the MMC5.<br />
** The PRG RAM +CE pin is a direct reflection of system reset detection state.<br />
<br />
== Banks ==<br />
The MMC5 provides 4 distinct banking modes for both PRG ROM and CHR ROM.<br />
<br />
=== PRG mode 0 ===<br />
* CPU $6000-$7FFF: 8 KB switchable PRG RAM bank<br />
* CPU $8000-$FFFF: 32 KB switchable PRG ROM bank<br />
<br />
=== PRG mode 1 ===<br />
* CPU $6000-$7FFF: 8 KB switchable PRG RAM bank<br />
* CPU $8000-$BFFF: 16 KB switchable PRG ROM/RAM bank<br />
* CPU $C000-$FFFF: 16 KB switchable PRG ROM bank<br />
<br />
=== PRG mode 2 ===<br />
* CPU $6000-$7FFF: 8 KB switchable PRG RAM bank<br />
* CPU $8000-$BFFF: 16 KB switchable PRG ROM/RAM bank<br />
* CPU $C000-$DFFF: 8 KB switchable PRG ROM/RAM bank<br />
* CPU $E000-$FFFF: 8 KB switchable PRG ROM bank<br />
<br />
=== PRG mode 3 ===<br />
* CPU $6000-$7FFF: 8 KB switchable PRG RAM bank<br />
* CPU $8000-$9FFF: 8 KB switchable PRG ROM/RAM bank<br />
* CPU $A000-$BFFF: 8 KB switchable PRG ROM/RAM bank<br />
* CPU $C000-$DFFF: 8 KB switchable PRG ROM/RAM bank<br />
* CPU $E000-$FFFF: 8 KB switchable PRG ROM bank<br />
<br />
=== CHR mode 0 ===<br />
* PPU $0000-$1FFF: 8 KB switchable CHR bank<br />
<br />
=== CHR mode 1 ===<br />
* PPU $0000-$0FFF: 4 KB switchable CHR bank<br />
* PPU $1000-$1FFF: 4 KB switchable CHR bank<br />
<br />
=== CHR mode 2 ===<br />
* PPU $0000-$07FF: 2 KB switchable CHR bank<br />
* PPU $0800-$0FFF: 2 KB switchable CHR bank<br />
* PPU $1000-$17FF: 2 KB switchable CHR bank<br />
* PPU $1800-$1FFF: 2 KB switchable CHR bank<br />
<br />
=== CHR mode 3 ===<br />
* PPU $0000-$03FF: 1 KB switchable CHR bank<br />
* PPU $0400-$07FF: 1 KB switchable CHR bank<br />
* PPU $0800-$0BFF: 1 KB switchable CHR bank<br />
* PPU $0C00-$0FFF: 1 KB switchable CHR bank<br />
* PPU $1000-$13FF: 1 KB switchable CHR bank<br />
* PPU $1400-$17FF: 1 KB switchable CHR bank<br />
* PPU $1800-$1BFF: 1 KB switchable CHR bank<br />
* PPU $1C00-$1FFF: 1 KB switchable CHR bank<br />
<br />
== Registers ==<br />
<br />
=== Sound ===<br />
<br />
For details on sound operation, see [[MMC5 audio]]<br />
<br />
=== NES internal state monitoring ===<br />
All of these registers overlay various registers that are already used inside the NES, and are fully decoded. A game could write to a mirror of a PPU register to get the MMC5 out of sync, but it's not clear how that could be useful.<br />
==== 8x16 mode enable 1 ($2000 = [[PPUCTRL]]) ====<br />
7 bit 0<br />
---- ----<br />
xxZx xxxx<br />
|<br />
+------- Sprite size (0: 8x8 pixels; 1: 8x16 pixels)<br />
<br />
==== 8x16 mode enable 2 ($2001 = [[PPUMASK]]) ====<br />
7 bit 0<br />
---------<br />
xxxE Exxx<br />
| |<br />
+-+--- 1,2,3: Rendering enabled; 0: rendering disabled<br />
<br />
Only when Z is set and at least one E bit is set does the MMC5 [[#CHR_Bankswitching_.28.245120-.245130.29|draw 8x16 sprites from eight independent banks]].<ref>[https://forums.nesdev.org/viewtopic.php?p=229375#p229375 krzysiobal's RE notes]</ref><br />
<br />
==== Unknown ($2002 = [[PPUSTATUS]], read only) ====<br />
Power analysis has detected that both revisions of the MMC5 monitor reads here, purpose unknown.<br />
<br />
==== Unknown ($2005 = [[PPUSCROLL]]) ====<br />
Power analysis has detected that both revisions of the MMC5 monitor writes here, purpose unknown.<br />
<br />
==== Unknown ($2006 = [[PPUADDR]], MMC5A only) ====<br />
Power analysis has detected that the MMC5A monitors writes here, purpose unknown.<br />
<br />
==== Unknown ($4014 = [[OAMDMA]]) ====<br />
Power analysis has detected that both revisions of the MMC5 monitor writes here, purpose unknown.<br />
<br />
=== Configuration ===<br />
<br />
==== PRG mode ($5100) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxPP<br />
||<br />
++- Select PRG banking mode<br />
* 0 - One 32KB bank<br />
* 1 - Two 16KB banks<br />
* 2 - One 16KB bank ($8000-$BFFF) and two 8KB banks ($C000-$DFFF and $E000-$FFFF)<br />
* 3 - Four 8KB banks<br />
<br />
''Castlevania III'' uses mode 2, which is similar to [[VRC6]] PRG banking. All other games use mode 3. The Koei games never write to this register, apparently relying on the MMC5 defaulting to mode 3 at power on.<br />
<br />
==== CHR mode ($5101) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxCC<br />
||<br />
++- Select CHR banking mode<br />
* 0 - 8KB CHR pages<br />
* 1 - 4KB CHR pages<br />
* 2 - 2KB CHR pages<br />
* 3 - 1KB CHR pages<br />
<br />
''Metal Slader Glory'' uses 4KB CHR pages. All other games use 1KB pages.<br />
<br />
==== PRG RAM Protect 1 ($5102) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxWW<br />
||<br />
++- RAM protect 1<br />
<br />
In order to enable writing to PRG RAM, this must be set to binary '10' (e.g. $02).<br />
<br />
==== PRG RAM Protect 2 ($5103) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxWW<br />
||<br />
++- RAM protect 2<br />
<br />
In order to enable writing to PRG RAM, this must be set to binary '01' (e.g. $01).<br />
<br />
==== Extended RAM mode ($5104) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxXX<br />
||<br />
++- Specify extended RAM usage<br />
* 0 - Use as extra nametable (possibly for split mode)<br />
* 1 - Use as extended attribute data (can also be used as extended nametable)<br />
* 2 - Use as ordinary RAM<br />
* 3 - Use as ordinary RAM, write protected<br />
<br />
==== Nametable mapping ($5105) ====<br />
7 bit 0<br />
---- ----<br />
DDCC BBAA<br />
|||| ||||<br />
|||| ||++- Select nametable at PPU $2000-$23FF<br />
|||| ++--- Select nametable at PPU $2400-$27FF<br />
||++------ Select nametable at PPU $2800-$2BFF<br />
++-------- Select nametable at PPU $2C00-$2FFF<br />
Nametable values:<br />
* 0 - On-board VRAM page 0<br />
* 1 - On-board VRAM page 1<br />
* 2 - Internal Expansion RAM, only if the Extended RAM mode allows it ($5104 is 00/01); otherwise, the nametable will read as all zeros,<br />
* 3 - Fill-mode data<br />
<br />
[[Mirroring]] examples:<br />
<br />
{| class="wikitable"<br />
! Mode !! Value !! NTD !! NTC !! NTB !! NTA<br />
|-<br />
| Horizontal || $50 || %01 || %01 || %00 || %00<br />
|-<br />
| Vertical || $44 || %01 || %00 || %01 || %00<br />
|-<br />
| Single-screen CIRAM 0 || $00 || %00 || %00 || %00 || %00<br />
|-<br />
| Single-screen CIRAM 1 || $55 || %01 || %01 || %01 || %01<br />
|-<br />
| Single-screen ExRAM || $AA || %10 || %10 || %10 || %10<br />
|-<br />
| Single-Screen Fill-mode || $FF || %11 || %11 || %11 || %11<br />
|-<br />
| Diagonal || $14 || %00 || %01 || %01 || %00<br />
|-<br />
|}<br />
<br />
==== Fill-mode tile ($5106) ====<br />
All eight bits specify the tile number to use for fill-mode nametable<br />
<br />
==== Fill-mode color ($5107) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxAA<br />
||<br />
++- Specify attribute bits to use for fill-mode nametable<br />
<br />
=== PRG Bankswitching ($5113-$5117)===<br />
In general, when the CPU accesses an address that corresponds to the range of a PRG bank designated by the present PRG mode, the bits of that PRG bank register are applied to the appropriate PRG address buses as follows:<br />
<br />
7 bit 0<br />
---- ----<br />
RAAA AaAA<br />
|||| ||||<br />
|||| |||+- PRG ROM/RAM A13<br />
|||| ||+-- PRG ROM/RAM A14<br />
|||| |+--- PRG ROM/RAM A15, also selecting between PRG RAM /CE 0 and 1<br />
|||| +---- PRG ROM/RAM A16<br />
|||+------ PRG ROM A17<br />
||+------- PRG ROM A18<br />
|+-------- PRG ROM A19<br />
+--------- RAM/ROM toggle (0: RAM; 1: ROM) (registers $5114-$5116 only)<br />
<br />
Conceptual bank register effective areas versus PRG mode:<br />
{| class="wikitable"<br />
! !! colspan=4|CPU memory affected for each mode (see [[#PRG mode ($5100)]])<br />
|-<br />
!Register<br />
!scope="col" style="width: 125px;"|Mode 3 Range<br />
!scope="col" style="width: 125px;"|Mode 2 Range<br />
!scope="col" style="width: 125px;"|Mode 1 Range<br />
!scope="col" style="width: 125px;"|Mode 0 Range<br />
|-<br />
||'''$5113'''|||$6000-$7FFF (RAM)||$6000-$7FFF (RAM)||$6000-$7FFF (RAM)||$6000-$7FFF (RAM)<br />
|-<br />
||'''$5114'''|||$8000-$9FFF||style="background: #cccccc;"|v (none) v||style="background: #cccccc;"|v (none) v||style="background: #cccccc;"|v (none) v<br />
|-<br />
||'''$5115'''|||$A000-$BFFF||$8000-$BFFF||$8000-$BFFF||style="background: #cccccc;"|v (none) v<br />
|-<br />
||'''$5116'''|||$C000-$DFFF||$C000$-DFFF||style="background: #cccccc;"|v (none) v||style="background: #cccccc;"|v (none) v<br />
|-<br />
||'''$5117'''|||$E000-$FFFF (ROM)||$E000-$FFFF (ROM)||$C000-$FFFF (ROM)||$8000-$FFFF (ROM)<br />
|-<br />
|}<br />
<br />
RAM is always mapped at $6000-$7FFF, and the bit $5113.7 is ignored.<br />
ROM is always mapped at the bank controlled by register $5117, and the bit $5117.7 is ignored. This makes it impossible to map RAM at interrupt vectors in any mode.<br />
<br />
Modes 0-2 : The bankswitching registers always hold a value of 8kb bank index numbers. When selecting banks of a "larger" size (16 kb or 32kb), the low bits in the bankswitching register are ignored. In other words, the address lines from the CPU are passed through the mapper directly to the PRG-ROM chip.<br />
<br />
Games seem to expect $5117 to be $FF at power on. All games have their reset vector in the last bank of PRG ROM, and the vector points to an address greater than or equal to $E000.<br />
<br />
==== PRG-RAM bankswitching quirks ====<br />
<br />
Until November 2018, it was thought that the MMC5 supported up to 2 PRG RAM chips, each up to 32KB in length. However, research in 2018 found that two previously-unknown pins act like PRG RAM A15 and A16, allowing up to 128KB RAM support. Either or both chips may be battery-backed; [http://bootgod.dyndns.org:7777/search.php?ines=5&battery=Yes&group=groupid 11 of the 15 MMC5 games] include a battery. The following configurations of PRG-RAM are known to exist in ExROM games:<br />
* 0KB: No PRG-RAM<br />
* 8KB: 1x 8KB chip<br />
* 16KB: 2x 8KB chips<br />
* 32KB: 1x 32KB chip<br />
<br />
In [[iNES|the original .NES format]], byte 8 of the file's header should indicate how many pages are present, but ROM images in the wild that use this mapper may not have byte 8 set correctly, nor do emulators necessarily honor this number.<br />
Byte 10 of the [[NES 2.0]] header should be reliable.<br />
<br />
==== Emulation quirks with commercial games ====<br />
<br />
* ''Bandit Kings of Ancient China'' maps PRG-RAM to the CPU $8000+ area and expects to be able to write to it through there. Failure to emulate this causes corruption when the background is restored on the world map.<br />
* ''Uncharted Waters'' requires emulating bankswitching of PRG RAM: it writes to PRG RAM at one CPU address and expects to be able to read the same data back via a different CPU address.<br />
* No ExROM game is known to write PRG RAM with one bank value and then attempt to read back the same data with a mirror of different bank value. So lacking better information, mirroring can be ignored, 64KB of WRAM could be emulated at all times, and $5113 can be treated as a simple page offset into that 64KB. Emulating 32KB won't work, even if no games used more than that; because 16KB games will expect to see their two distinct pages by toggling bit 2, not bit 0. However, it's not advisable to rely on this fallback behavior for newly produced homebrew because people making a physical reproduction will not know from the header how much RAM to include on the cartridge board.<ref>[https://forums.nesdev.org/viewtopic.php?p=230927#p230927 lidnariq's comment about puNES]</ref><br />
<br />
=== CHR Bankswitching ($5120-$5130) ===<br />
When using 8x8 sprites, only registers $5120-$5127 are used. Registers $5128-$512B are completely ignored.<br />
<br />
When using 8x16 sprites, registers $5120-$5127 specify banks for sprites, registers $5128-$512B apply to background tiles, and the last set of registers written to (either $5120-$5127 or $5128-$512B) will be used for I/O via [[PPUDATA]] ($2007). [https://forums.nesdev.org/viewtopic.php?p=193069#p193069] [http://forums.nesdev.org/viewtopic.php?p=194120#p194120] The MMC5 knows that sprite data is being fetched by counting the number of fetches since the last detected scanline start, similar to how it detects the position for the vertical split.<br />
<br />
''Bandit Kings of Ancient China'' and ''Uchuu Keibitai SDF'' have non-pattern data stored in CHR ROM, read out via $2007.<br />
<br />
The MMC5 is known to listen to the same address as the PPU to find out when to enable the 8x16 sprite mode; see [[#8x16_mode_enable_1_.28.242000_.3D_PPUCTRL.29|above]].<br />
<br />
==== CHR select $5120-$512B ====<br />
{| class="wikitable"<br />
! !! colspan=4|PPU memory affected for each mode (see [[#CHR mode ($5101)]])<br />
|-<br />
! Register !! 1 KiB !! 2 KiB !! 4 KiB !! 8 KiB<br />
|-<br />
| '''$5120''' || $0000-$03FF || none || none || none<br />
|-<br />
| '''$5121''' || $0400-$07FF || $0000-$07FF || none || none<br />
|-<br />
| '''$5122''' || $0800-$0BFF || none || none || none<br />
|-<br />
| '''$5123''' || $0C00-$0FFF || $0800-$0FFF || $0000-$0FFF || none<br />
|-<br />
| '''$5124''' || $1000-$13FF || none || none || none<br />
|-<br />
| '''$5125''' || $1400-$17FF || $1000-$17FF || none || none<br />
|-<br />
| '''$5126''' || $1800-$1BFF || none || none || none<br />
|-<br />
| '''$5127''' || $1C00-$1FFF || $1800-$1FFF || $1000-$1FFF || $0000-$1FFF<br />
|-<br />
| '''$5128''' || $0000-$03FF and $1000-$13FF || none || none || none<br />
|-<br />
| '''$5129''' || $0400-$07FF and $1400-$17FF || $0000-$07FF and $1000-$17FF || none || none<br />
|-<br />
| '''$512A''' || $0800-$0BFF and $1800-$1BFF || none || none || none<br />
|-<br />
| '''$512B''' || $0C00-$0FFF and $1C00-$1FFF || $0800-$0FFF and $1800-$1FFF || $0000-$0FFF and $1000-$1FFF || $0000-$1FFF<br />
|}<br />
<br />
'''Caution:''' Unlike the MMC1 and unlike PRG banking on the MMC5, the banks are always indexed by the ''currently selected size''. When using 2kb, 4kb or 8kb bank sizes, the registers hold bank index of that larger size, and lower bits are *not* ignored.<br />
<br />
==== Upper CHR Bank bits ($5130) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxBB<br />
||<br />
++- Upper bits for subsequent CHR bank writes<br />
<br />
When the MMC5 is using 2KB/1KB CHR banks, only 512KB/256KB of CHR ROM can be selected using the previous registers. To access all 1024KB in those modes, first write the upper bit(s) to register $5130 and then write the lower bits to $5120-$512B.<br />
When the Extended RAM mode is set to 1, this selects which 256KB of CHR ROM is to be used for all background tiles on the screen.<br />
<br />
The only ExROM game with CHR ROM larger than 256KB is ''Metal Slader Glory'', which uses 4KB CHR banks and does not use extended attributes. In other words, no official game relies on this register, and most don't even initialize it.<br />
<br />
=== Other Registers ===<br />
<br />
==== Vertical Split Mode ($5200) ====<br />
7 bit 0<br />
---- ----<br />
ESxW WWWW<br />
|| | ||||<br />
|| +-++++- Specify vertical split start/stop tile<br />
|+-------- Specify vertical split screen side (0:left; 1:right)<br />
+--------- Enable vertical split mode<br />
<br />
When vertical split mode is enabled, all VRAM fetches corresponding to the appropriate screen region will be redirected to Extended RAM (as long as its mode is set to 0 or 1).<br />
<br />
''Uchuu Keibitai SDF'' uses split screen mode during the intro, where it shows ship stats. ''Bandit Kings of Ancient China'' uses split screen mode during the ending sequence<ref>https://forums.nesdev.org/viewtopic.php?f=2&t=12764</ref>.<br />
<br />
===== Operation Notes =====<br />
<br />
34 BG tiles are fetched per scanline. MMC5 performs the split by watching which BG tile is being fetched,<br />
and if it is within the split region, replacing the normal NT data with the split screen data according to<br />
the absolute screen position of the tile (i.e., ignoring the coarse horizontal and vertical scroll output<br />
as part of the VRAM address for the fetch). Since it operates on a per-tile basis, fine horizontal<br />
scrolling "carries into" the split region: setting the horizontal scroll to 1-7 will result in the split<br />
being moved to the left 1-7 pixels. Whenever scrolling exceeds a multiple of 8, the split will "snap" back to its normal<br />
position.<br />
<br />
Left Split:<br />
* Tiles 0 to T-1 are the split.<br />
* Tiles T and on are rendered normally.<br />
<br />
Right Split:<br />
* Tiles 0 to T-1 are rendered normally.<br />
* Tiles T and on are the split.<br />
<br />
There is no coarse horizontal scrolling of any kind for the split. Right-side splits will always show the<br />
right-hand side of the nametable, and left-hand splits will always show the left-hand side of the nametable.<br />
Coarse horizontal scrolling can still be used for the non-split region.<br />
<br />
ExRAM is always used as the nametable in split screen mode.<br />
<br />
Vertical scrolling for the split operates like normal vertical scrolling. 0-239 are valid scroll values,<br />
whereas 240-255 will display Attribute table data as NT data for the first few scanlines. The split nametable<br />
will wrap so that the top of the nametable will appear below as you scroll (just as if vertical mirroring<br />
were employed).<br />
<br />
$5202 selects (yet another) CHR page to use for the BG. This page is used for the split region only.<br />
<br />
==== Vertical Split Scroll ($5201) ====<br />
All eight bits specify the vertical scroll value to use in split region<br />
<br />
MMC5 boards wired in "CL" mode should only use vertical scroll values whose bottom 3 bits match the [[PPU]]'s fine vertical scroll value. Using a mismatched value will cause tiles to seem to "roll" within themselves. In "SL" mode, any values can be used.<br />
<br />
Horizontal scrolling is not allowed within the split region.<br />
<br />
==== Vertical Split Bank ($5202) ====<br />
All eight bits select a 4 KB CHR bank at $0000-$0FFF and $1000-$1FFF while rendering the split region.<br />
<br />
==== IRQ Scanline Compare Value ($5203) ====<br />
All eight bits specify the target scanline number at which to generate a scanline IRQ. Value $00 is a special case that will not produce IRQ pending conditions, though it is possible to get an IRQ while this is set to $00 (due to the pending flag being set already.) You will need to take additional measures to fully suppress the IRQ. See the detailed discussion.<br />
<br />
==== Scanline IRQ Status ($5204, read/write) ====<br />
===== Write =====<br />
7 bit 0<br />
---- ----<br />
Exxx xxxx<br />
|<br />
+--------- Scanline IRQ Enable flag (1=enabled)<br />
<br />
===== Read =====<br />
7 bit 0<br />
---- ----<br />
SVxx xxxx MMC5A default power-on value = $00<br />
||<br />
|+-------- "In Frame" flag<br />
+--------- Scanline IRQ Pending flag<br />
<br />
The Scanline IRQ Pending flag becomes set at any time that the internal scanline counter matches the value written to register $5203. If the scanline IRQ is enabled, it will also generate /IRQ to the system.<br />
<br />
The "In Frame" flag is set when the PPU is rendering a frame and cleared during vertical blank.<br />
<br />
Any time this register is read, the Scanline IRQ Pending flag is cleared (acknowledging the IRQ).<br />
<br />
For details, see [[MMC5#IRQ_Counter_Operation|IRQ counter operation]].<br />
<br />
==== Unsigned 8x8 to 16 Multiplier ($5205, $5206 read/write) ====<br />
The unsigned 16-bit product is available to be read from these registers immediately after writing. All 65536 combinations of multiplicand and multiplier were tested and verified correct on MMC5A here[https://forums.nesdev.org/viewtopic.php?p=226537#p226537].<br />
===== Write =====<br />
*$5205 8-bit Unsigned Multiplicand<br />
*$5206 8-bit Unsigned Multiplier<br />
*MMC5A default power-on write value = $FF for both of these registers.<br />
<br />
===== Read =====<br />
*$5205 Unsigned 16-bit Product (low byte)<br />
*$5206 Unsigned 16-bit Product (high byte)<br />
*MMC5A default power-on read value = $FE01, i.e. $FF * $FF.<br />
<br />
=== MMC5A Only ===<br />
Registers $5207, $5208, $5209, $520A, and range $5800-$5BFF are present only in MMC5A.<br />
==== CL3 / SL3 Data Direction and Output Data Source (MMC5A: $5207 write only) ====<br />
7 bit 0<br />
---- ----<br />
ABxx xxCD MMC5A default power-on write value = 11xx xxxx<br />
|| ||<br />
|| |+- MMC5.97 (CL3) Output Data Source (0 = $5208.6 value written, 1 = !(M2) when CPU is reading in range $5800-$5BFF)<br />
|| +-- MMC5.98 (SL3) Output Data Source (0 = $5208.7 value written, 1 = !(M2) when CPU is writing in range $5800-$5BFF)<br />
|+-------- MMC5.97 (CL3) Data Direction (0 = output, 1 = input)<br />
+--------- MMC5.98 (SL3) Data Direction (0 = output, 1 = input)<br />
<br />
==== CL3 / SL3 Status (MMC5A: $5208 read/write) ====<br />
===== Write =====<br />
7 bit 0<br />
---- ----<br />
ABxx xxxx MMC5A default power-on write value = 00xx xxxx<br />
||<br />
|+-------- Value to be output on MMC5.97 pin (CL3) if/when $5207.0 = 0 and $5207.6 = 0<br />
+--------- Value to be output on MMC5.98 pin (SL3) if/when $5207.1 = 0 and $5207.7 = 0<br />
<br />
===== Read =====<br />
7 bit 0<br />
---- ----<br />
ABxx xxxx<br />
||<br />
|+-------- Input value of MMC5.97 pin (CL3)<br />
+--------- Input value of MMC5.98 pin (SL3)<br />
<br />
==== 16-bit Hardware Timer with IRQ (MMC5A: $5209 read/write, $520A write) ====<br />
===== Read =====<br />
*$5209<br />
7 bit 0<br />
---- ----<br />
Vxxx xxxx MMC5A default power-on read value = $00<br />
|<br />
+--------- Hardware Timer IRQ Flag<br />
<br />
===== Write =====<br />
*$5209<br />
7 bit 0<br />
---- ----<br />
TTTT TTTT MMC5A default power-on write value = $00<br />
|||| ||||<br />
++++-++++- Timer count LSB<br />
<br />
*$520A<br />
7 bit 0<br />
---- ----<br />
TTTT TTTT MMC5A default power-on write value = $00<br />
|||| ||||<br />
++++-++++- Timer count MSB<br />
<br />
Based on findings from krzysiobal:<br />
The timer automatically starts when writing any value to register $5209, if the 16-bit timer value does not equal $0000. For example, to write value $0100, you would first write $01 (MSB) to register $520A, which does not start the timer. Then write $00 (LSB) to register $5209, which at that point will start the timer from value $0100.<br />
<br />
Each 8-bit value is written directly to an internal 16-bit counter that decrements on each rising edge of M2. Additional writes while the timer is running will directly overwrite that portion of the counter. Reading register $5209 while the timer is running reports $00. The transition from counter value $0001 to $0000 generates an IRQ and sets the hardware timer IRQ flag. The timer stops at this point. Reading this register reports the IRQ flag, then automatically clears the IRQ and IRQ flag.<br />
<br />
If the MMC5 detects a reset, it clears the timer if active, and it clears the IRQ and IRQ flag if set. Reset detection works by looking for a gap larger than about 11 usec on M2.<br />
<br />
This register's IRQ operation is completely independent from register $5204. Disabling interrupts through $5204 does not make any effect, also reading $5204 does not report IRQ pending when IRQ is asserted by $5209.<br />
<br />
==== Unknown Address Range (MMC5A: $5800-$5BFF, write only) ====<br />
Reads and writes in this address range are reflected on the CL3 and SL3 pins when register $5207 = $03. The purpose of this function is unknown. Minute VCC current spikes shortly after rising edge of M2 during writes in this range exhibit the same characteristics as writes in expansion RAM range $5C00-$5FFF, suggesting possible existence of RAM in this range, though experimentally reading from this range is always met with open CPU bus.<br />
<br />
Address $5800 is written to by Just Breed. During each V-Blank, it writes value $03, then $01 to this address, reads and writes to PPU registers, then writes value $00 to this address once complete.<br />
<br />
=== Expansion RAM ($5C00-$5FFF, read/write) ===<br />
* Mode 0/1 - Not readable (returns [[open bus]]), can only be written while the PPU is rendering (otherwise, 0 is written)<br />
* Mode 2 - Readable and writable<br />
* Mode 3 - Read-only<br />
<br />
In Mode 1, nametable fetches are processed normally, and can come from CIRAM nametables, fill mode, or even Expansion RAM, but attribute fetches are replaced by data from Expansion RAM.<br />
<br />
Each byte of Expansion RAM is used to enhance the tile at the corresponding address in every nametable (so the extended attributes are 1-screen mirrored):<br />
<br />
7 bit 0<br />
---- ----<br />
AACC CCCC<br />
|||| ||||<br />
||++-++++- Select 4 KB CHR bank to use with specified tile<br />
++-------- Select palette to use with specified tile<br />
<br />
The pattern fetches ignore the standard CHR banking bits, and instead use the top two bits of $5130 and the bottom 6 bits from Expansion RAM to choose a 4KB bank to select the tile from.<br />
<br />
''Just Breed'', ''Yakuman Tengoku'', and the Koei games use extended attributes continuously.<br />
<br />
== Scanline Detection and Scanline IRQ ==<br />
[[File:mmc5_in_frame_status_bit.png|thumb|right|MMC5 'in frame' status bit state diagram]]<br />
The MMC5 detects scanlines by first looking for three consecutive PPU reads from the same nametable address in the range $2xxx. Once this has been seen, the next PPU read, regardless of address, is the point at which the scanline is detected. This works because the PPU does two matching dummy nametable byte reads at the end of each scanline, followed by a third matching nametable byte read at the beginning of the next scanline, followed by an attribute table byte read. So, the scanline gets detected when the PPU does the attribute table byte read, which is at PPU cycle 4.<br />
<br />
Once that occurs, if the "in-frame" flag (register $5204) was clear, it becomes set, and the internal 8-bit scanline counter is reset to zero; but if it was already set, the scanline counter is incremented, then compared against the value written to $5203. If they match, the "irq pending" flag is set.<br />
<br />
The IRQ pending flag is raised when the desired scanline is reached ''regardless'' of whether or not the scanline IRQ is enabled, i.e. even after a 0 was written to the scanline IRQ enable flag. However, an actual IRQ is only sent to the CPU if both the scanline IRQ enable flag and IRQ pending flag are set. A $5203 value of $00 is a special case where the comparison is never true. The MMC5's scanline IRQ occurs at PPU cycle 4, unlike the simpler scanline counter of the MMC3, which usually generates an IRQ around PPU cycle 260. See also [http://forums.nesdev.org/viewtopic.php?t=7653].<br />
<br />
The "in-frame" flag is cleared when the PPU is no longer rendering. This is detected when 3 CPU cycles pass without a PPU read having occurred (PPU /RD has not been low during the last 3 M2 rises). The PPU does this in these conditions:<br />
* the PPU begins the post-render scanline 240<br />
* the PPU stops rendering because the user program wrote to CPU address $2001 with bits 3 and 4 clear.<br />
* note: the MMC5 does not listen directly to writes to $2001 for this behavior.<br />
<br />
The "in frame" flag is cleared, scanline IRQ is automatically acknowledged, and the internal scanline counter is reset in any of these conditions:<br />
* the V-blank NMI occurs, i.e. CPU reads the interrupt vector from addresses $FFFA and $FFFB<br />
* the user program intentionally reads from CPU addresses $FFFA or $FFFB<br />
* the 241st scanline is detected.<br />
<br />
The scanline IRQ is acknowledged, but the "in frame" flag is not cleared and the scanline counter is not reset in any of these conditions:<br />
* the user program reads register $5204<br />
* scanline 0 is detected<br />
<br />
When system reset detection occurs, the only thing that happens is scanline IRQ becomes disabled. All other operation continues unaffected. These things happen any time that scanline IRQ becomes disabled:<br />
* if /IRQ was low due to scanline IRQ pending flag, /IRQ returns high<br />
* the scanline IRQ pending flag remains unaffected<br />
* register $5203 value remains unaffected<br />
* scanline counter remains unaffected<br />
* enabling the scanline IRQ will cause immediate /IRQ low if IRQ pending flag is set, but will not affect anything else<br />
<br />
This means in pseudo-code:<br />
(On every PPU read -- PPU /RD falling edge)<br />
if address >= $2000 and address <= $2FFF and address == lastAddress<br />
matchCount := matchCount +1<br />
if matchCount == 2<br />
if inFrame == false<br />
inFrame := true<br />
scanline := 0<br />
else<br />
scanline := scanline +1<br />
if scanline == [$5203]<br />
irqPending := true<br />
else<br />
matchCount := 0<br />
lastAddress := address<br />
ppuIsReading := true<br />
<br />
(On every CPU cycle -- M2 rising edge)<br />
if ppuIsReading<br />
idleCount := 0<br />
else<br />
idleCount := idleCount +1 <br />
if idleCount == 3<br />
inFrame := false<br />
lastAddress := undefined<br />
ppuIsReading := false<br />
<br />
(On every CPU write)<br />
if address == $2001 and (value & $18) == 0<br />
inFrame := false<br />
lastAddress := undefined<br />
<br />
(On every CPU read)<br />
if address == $FFFA or address == $FFFB<br />
inFrame := false<br />
lastAddress := undefined<br />
<br />
Please refer to the state diagrams on the right for a more formal description of the scanline and in-frame detection counters.<br />
<br />
The system reset detection observed in the 16-bit software timer does not appear to have any effect on the 'in frame' status bit or the state diagram on the right. It is unknown if reset detection clears the scanline counter or a pending scanline IRQ.<br />
<br />
== Hardware ==<br />
<br />
The MMC5 exists in a 100-pin rectangular QFP package, see [[MMC5 pinout]] for details.<br />
<br />
MMC5 cartridge PCBs can be configured to different modes, see [[ExROM]] for details.<br />
<br />
At least two different versions of the MMC5 are known to exist: MMC5, and MMC5A. MMC5A has the addition of registers $5207, $5208, $5209, and $520A: SL3/CL3 control and hardware timer.<br />
<br />
== References ==<br />
<references /><br />
<br />
== External links ==<br />
* NES Mapper list by Disch [http://www.romhacking.net/documents/362/]<br />
* Nintendo MMC5 by goroh, translated by Sgt. Bowhack [//nesdev.org/mmc5-e.txt]<br />
* Nintendo MMC5 Bankswitching by Kevin Horton [//nesdev.org/mmc5_bank_switch.txt]</div>Zeromushttps://www.nesdev.org/w/index.php?title=MMC5&diff=6774MMC52019-10-09T05:56:56Z<p>Zeromus: /* Scanline Number IRQ ($5203) */</p>
<hr />
<div>{{Infobox iNES mapper<br />
|name=MMC5<br />
|name2=ExROM<br />
|company=Nintendo, Koei, others<br />
|mapper=5<br />
|nescartdbgames=15<br />
|complexity=ASIC<br />
|boards=EKROM, ELROM,<br/>ETROM, EWROM<br />
|pinout=MMC5 pinout<br />
|prgmax=1024K<br />
|prgpage=8K, 16K, or 32K<br />
|wrammax=128K<br />
|wrampage=8K ($6000-$DFFF),<br/>16K (only $8000-$BFFF<br />at PRG mode 1/2)<br />
|chrmax=1024K<br />
|chrpage=1K, 2K, 4K, or 8K<br />
|mirroring=arbitrary, up to 3 source<br />nametables (plus fill mode)<br />
|busconflicts=No<br />
|irq=Yes<br />
|audio=[[MMC5_audio|Yes]]<br />
}}<br />
{{nesdbbox<br />
|ines|5|iNES 005<br />
|unif_wild|-E%ROM|ExROM<br />
|unif_wild|EKROM|EKROM<br />
|unif_wild|ELROM|ELROM<br />
|unif_wild|ETROM|ETROM<br />
|unif_wild|EWROM|EWROM<br />
}}<br />
[[Category:Nintendo licensed mappers]][[Category:Mappers using $4020-$5FFF]][[Category:Mappers with large PRG RAM]][[Category:Mappers with scanline IRQs]][[Category:Mappers with single-screen mirroring]][[Category:Mappers with cycle IRQs]]<br />
The '''Nintendo MMC5''' is a [[mapper]] [[:Category:ASIC mappers|ASIC]] used in Nintendo's [[ExROM]] Game Pak boards. All MMC5 boards are assigned to '''mapper 5'''.<br />
<br />
Example games:<br />
* ''Castlevania 3''<br />
* ''Just Breed''<br />
* ''Uncharted Waters''<br />
* ''Romance of the Three Kingdoms II''<br />
* ''Laser Invasion''<br />
* ''Metal Slader Glory''<br />
* ''Uchuu Keibitai SDF''<br />
* ''Shin 4 Nin Uchi Mahjong - Yakuman Tengoku''<br />
* ''Bandit Kings of Ancient China''<br />
<br />
The first game to use this chip (''Nobunaga's Ambition II'') was released in February 1990. The [http://bootgod.dyndns.org:7777/profile.php?id=3169 date codes on components on early released cartridges] show that manufacturing had started at the end of 1989.<br />
<br />
== Overview ==<br />
The MMC5 is the most powerful mapper ASIC Nintendo made for the NES and Famicom.<br />
<br />
It supports many advanced features, including:<br />
* 4 PRG ROM switching modes<br />
* 4 CHR ROM switching modes<br />
* Up to 128KB of WRAM, mappable not only at $6000-$7FFF but also within $8000-$DFFF<br />
** Supports either one chip (up to 128KB) or two chips (up to 32KB each)<br />
* An 8 bit by 8 bit multiplier with a 16 bit result for performing quick calculations<br />
* Scanline detection with counter and configurable IRQ<br />
* Frame detection with status bit<br />
* The ability to use different CHR banks for background and 8x16 sprites (allowing 256 unique 8x16 sprite tiles, independent of the background).<br />
* 1024 bytes of on-chip memory, which can be used for 4 different purposes:<br />
** An extra general-use nametable<br />
** Attribute and tile index expansion - address 16384 background tiles at once, and allow each individual 8x8 tile to have its own palette setting<br />
** Vertical split-screen<br />
** Extra RAM for storing program variables<br />
* Three extra sound channels<br />
** Two pulse channels, identical to those in the NES APU (except lacking pitch sweeps).<br />
** An 8-bit RAW PCM channel<br />
* A 'fill mode' nametable, which can be instantly set to contain a specific tile in a specific color (useful for screen transitions)<br />
* System reset detection<br />
** Triggered by a positive or negative gap in M2 of at least 11.2 usec.<br />
** Also triggered and latched by absence of AVcc.<br />
** After reapplying AVcc, another gap in M2 is sometimes necessary to clear the latch.<br />
** This feature resets some, but not all, states of the MMC5.<br />
** The PRG RAM +CE pin is a direct reflection of system reset detection state.<br />
<br />
== Banks ==<br />
The MMC5 provides 4 distinct banking modes for both PRG ROM and CHR ROM.<br />
<br />
=== PRG mode 0 ===<br />
* CPU $6000-$7FFF: 8 KB switchable PRG RAM bank<br />
* CPU $8000-$FFFF: 32 KB switchable PRG ROM bank<br />
<br />
=== PRG mode 1 ===<br />
* CPU $6000-$7FFF: 8 KB switchable PRG RAM bank<br />
* CPU $8000-$BFFF: 16 KB switchable PRG ROM/RAM bank<br />
* CPU $C000-$FFFF: 16 KB switchable PRG ROM bank<br />
<br />
=== PRG mode 2 ===<br />
* CPU $6000-$7FFF: 8 KB switchable PRG RAM bank<br />
* CPU $8000-$BFFF: 16 KB switchable PRG ROM/RAM bank<br />
* CPU $C000-$DFFF: 8 KB switchable PRG ROM/RAM bank<br />
* CPU $E000-$FFFF: 8 KB switchable PRG ROM bank<br />
<br />
=== PRG mode 3 ===<br />
* CPU $6000-$7FFF: 8 KB switchable PRG RAM bank<br />
* CPU $8000-$9FFF: 8 KB switchable PRG ROM/RAM bank<br />
* CPU $A000-$BFFF: 8 KB switchable PRG ROM/RAM bank<br />
* CPU $C000-$DFFF: 8 KB switchable PRG ROM/RAM bank<br />
* CPU $E000-$FFFF: 8 KB switchable PRG ROM bank<br />
<br />
=== CHR mode 0 ===<br />
* PPU $0000-$1FFF: 8 KB switchable CHR bank<br />
<br />
=== CHR mode 1 ===<br />
* PPU $0000-$0FFF: 4 KB switchable CHR bank<br />
* PPU $1000-$1FFF: 4 KB switchable CHR bank<br />
<br />
=== CHR mode 2 ===<br />
* PPU $0000-$07FF: 2 KB switchable CHR bank<br />
* PPU $0800-$0FFF: 2 KB switchable CHR bank<br />
* PPU $1000-$17FF: 2 KB switchable CHR bank<br />
* PPU $1800-$1FFF: 2 KB switchable CHR bank<br />
<br />
=== CHR mode 3 ===<br />
* PPU $0000-$03FF: 1 KB switchable CHR bank<br />
* PPU $0400-$07FF: 1 KB switchable CHR bank<br />
* PPU $0800-$0BFF: 1 KB switchable CHR bank<br />
* PPU $0C00-$0FFF: 1 KB switchable CHR bank<br />
* PPU $1000-$13FF: 1 KB switchable CHR bank<br />
* PPU $1400-$17FF: 1 KB switchable CHR bank<br />
* PPU $1800-$1BFF: 1 KB switchable CHR bank<br />
* PPU $1C00-$1FFF: 1 KB switchable CHR bank<br />
<br />
== Registers ==<br />
<br />
=== Sound ===<br />
<br />
For details on sound operation, see [[MMC5 audio]]<br />
<br />
=== NES internal state monitoring ===<br />
All of these registers overlay various registers that are already used inside the NES, and are fully decoded. A game could write to a mirror of a PPU register to get the MMC5 out of sync, but it's not clear how that could be useful.<br />
==== 8x16 mode enable 1 ($2000 = [[PPUCTRL]]) ====<br />
7 bit 0<br />
---- ----<br />
xxZx xxxx<br />
|<br />
+------- Sprite size (0: 8x8 pixels; 1: 8x16 pixels)<br />
<br />
==== 8x16 mode enable 2 ($2001 = [[PPUMASK]]) ====<br />
7 bit 0<br />
---------<br />
xxxE Exxx<br />
| |<br />
+-+--- 1,2,3: Rendering enabled; 0: rendering disabled<br />
<br />
Only when Z is set and at least one E bit is set does the MMC5 [[#CHR_Bankswitching_.28.245120-.245130.29|draw 8x16 sprites from eight independent banks]].<ref>[https://forums.nesdev.org/viewtopic.php?p=229375#p229375 krzysiobal's RE notes]</ref><br />
<br />
==== Unknown ($2002 = [[PPUSTATUS]], read only) ====<br />
Power analysis has detected that both revisions of the MMC5 monitor reads here, purpose unknown.<br />
<br />
==== Unknown ($2005 = [[PPUSCROLL]]) ====<br />
Power analysis has detected that both revisions of the MMC5 monitor writes here, purpose unknown.<br />
<br />
==== Unknown ($2006 = [[PPUADDR]], MMC5A only) ====<br />
Power analysis has detected that the MMC5A monitors writes here, purpose unknown.<br />
<br />
==== Unknown ($4014 = [[OAMDMA]]) ====<br />
Power analysis has detected that both revisions of the MMC5 monitor writes here, purpose unknown.<br />
<br />
=== Configuration ===<br />
<br />
==== PRG mode ($5100) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxPP<br />
||<br />
++- Select PRG banking mode<br />
* 0 - One 32KB bank<br />
* 1 - Two 16KB banks<br />
* 2 - One 16KB bank ($8000-$BFFF) and two 8KB banks ($C000-$DFFF and $E000-$FFFF)<br />
* 3 - Four 8KB banks<br />
<br />
''Castlevania III'' uses mode 2, which is similar to [[VRC6]] PRG banking. All other games use mode 3. The Koei games never write to this register, apparently relying on the MMC5 defaulting to mode 3 at power on.<br />
<br />
==== CHR mode ($5101) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxCC<br />
||<br />
++- Select CHR banking mode<br />
* 0 - 8KB CHR pages<br />
* 1 - 4KB CHR pages<br />
* 2 - 2KB CHR pages<br />
* 3 - 1KB CHR pages<br />
<br />
''Metal Slader Glory'' uses 4KB CHR pages. All other games use 1KB pages.<br />
<br />
==== PRG RAM Protect 1 ($5102) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxWW<br />
||<br />
++- RAM protect 1<br />
<br />
In order to enable writing to PRG RAM, this must be set to binary '10' (e.g. $02).<br />
<br />
==== PRG RAM Protect 2 ($5103) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxWW<br />
||<br />
++- RAM protect 2<br />
<br />
In order to enable writing to PRG RAM, this must be set to binary '01' (e.g. $01).<br />
<br />
==== Extended RAM mode ($5104) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxXX<br />
||<br />
++- Specify extended RAM usage<br />
* 0 - Use as extra nametable (possibly for split mode)<br />
* 1 - Use as extended attribute data (can also be used as extended nametable)<br />
* 2 - Use as ordinary RAM<br />
* 3 - Use as ordinary RAM, write protected<br />
<br />
==== Nametable mapping ($5105) ====<br />
7 bit 0<br />
---- ----<br />
DDCC BBAA<br />
|||| ||||<br />
|||| ||++- Select nametable at PPU $2000-$23FF<br />
|||| ++--- Select nametable at PPU $2400-$27FF<br />
||++------ Select nametable at PPU $2800-$2BFF<br />
++-------- Select nametable at PPU $2C00-$2FFF<br />
Nametable values:<br />
* 0 - On-board VRAM page 0<br />
* 1 - On-board VRAM page 1<br />
* 2 - Internal Expansion RAM, only if the Extended RAM mode allows it ($5104 is 00/01); otherwise, the nametable will read as all zeros,<br />
* 3 - Fill-mode data<br />
<br />
[[Mirroring]] examples:<br />
<br />
{| class="wikitable"<br />
! Mode !! Value !! NTD !! NTC !! NTB !! NTA<br />
|-<br />
| Horizontal || $50 || %01 || %01 || %00 || %00<br />
|-<br />
| Vertical || $44 || %01 || %00 || %01 || %00<br />
|-<br />
| Single-screen CIRAM 0 || $00 || %00 || %00 || %00 || %00<br />
|-<br />
| Single-screen CIRAM 1 || $55 || %01 || %01 || %01 || %01<br />
|-<br />
| Single-screen ExRAM || $AA || %10 || %10 || %10 || %10<br />
|-<br />
| Single-Screen Fill-mode || $FF || %11 || %11 || %11 || %11<br />
|-<br />
| Diagonal || $14 || %00 || %01 || %01 || %00<br />
|-<br />
|}<br />
<br />
==== Fill-mode tile ($5106) ====<br />
All eight bits specify the tile number to use for fill-mode nametable<br />
<br />
==== Fill-mode color ($5107) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxAA<br />
||<br />
++- Specify attribute bits to use for fill-mode nametable<br />
<br />
=== PRG Bankswitching ($5113-$5117)===<br />
In general, when the CPU accesses an address that corresponds to the range of a PRG bank designated by the present PRG mode, the bits of that PRG bank register are applied to the appropriate PRG address buses as follows:<br />
<br />
7 bit 0<br />
---- ----<br />
RAAA AaAA<br />
|||| ||||<br />
|||| |||+- PRG ROM/RAM A13<br />
|||| ||+-- PRG ROM/RAM A14<br />
|||| |+--- PRG ROM/RAM A15, also selecting between PRG RAM /CE 0 and 1<br />
|||| +---- PRG ROM/RAM A16<br />
|||+------ PRG ROM A17<br />
||+------- PRG ROM A18<br />
|+-------- PRG ROM A19<br />
+--------- RAM/ROM toggle (0: RAM; 1: ROM) (registers $5114-$5116 only)<br />
<br />
Conceptual bank register effective areas versus PRG mode:<br />
{| class="wikitable"<br />
! !! colspan=4|CPU memory affected for each mode (see [[#PRG mode ($5100)]])<br />
|-<br />
!Register<br />
!scope="col" style="width: 125px;"|Mode 3 Range<br />
!scope="col" style="width: 125px;"|Mode 2 Range<br />
!scope="col" style="width: 125px;"|Mode 1 Range<br />
!scope="col" style="width: 125px;"|Mode 0 Range<br />
|-<br />
||'''$5113'''|||$6000-$7FFF (RAM)||$6000-$7FFF (RAM)||$6000-$7FFF (RAM)||$6000-$7FFF (RAM)<br />
|-<br />
||'''$5114'''|||$8000-$9FFF||style="background: #cccccc;"|v (none) v||style="background: #cccccc;"|v (none) v||style="background: #cccccc;"|v (none) v<br />
|-<br />
||'''$5115'''|||$A000-$BFFF||$8000-$BFFF||$8000-$BFFF||style="background: #cccccc;"|v (none) v<br />
|-<br />
||'''$5116'''|||$C000-$DFFF||$C000$-DFFF||style="background: #cccccc;"|v (none) v||style="background: #cccccc;"|v (none) v<br />
|-<br />
||'''$5117'''|||$E000-$FFFF (ROM)||$E000-$FFFF (ROM)||$C000-$FFFF (ROM)||$8000-$FFFF (ROM)<br />
|-<br />
|}<br />
<br />
RAM is always mapped at $6000-$7FFF, and the bit $5113.7 is ignored.<br />
ROM is always mapped at the bank controlled by register $5117, and the bit $5117.7 is ignored. This makes it impossible to map RAM at interrupt vectors in any mode.<br />
<br />
Modes 0-2 : The bankswitching registers always hold a value of 8kb bank index numbers. When selecting banks of a "larger" size (16 kb or 32kb), the low bits in the bankswitching register are ignored. In other words, the address lines from the CPU are passed through the mapper directly to the PRG-ROM chip.<br />
<br />
Games seem to expect $5117 to be $FF at power on. All games have their reset vector in the last bank of PRG ROM, and the vector points to an address greater than or equal to $E000.<br />
<br />
==== PRG-RAM bankswitching quirks ====<br />
<br />
Until November 2018, it was thought that the MMC5 supported up to 2 PRG RAM chips, each up to 32KB in length. However, research in 2018 found that two previously-unknown pins act like PRG RAM A15 and A16, allowing up to 128KB RAM support. Either or both chips may be battery-backed; [http://bootgod.dyndns.org:7777/search.php?ines=5&battery=Yes&group=groupid 11 of the 15 MMC5 games] include a battery. The following configurations of PRG-RAM are known to exist in ExROM games:<br />
* 0KB: No PRG-RAM<br />
* 8KB: 1x 8KB chip<br />
* 16KB: 2x 8KB chips<br />
* 32KB: 1x 32KB chip<br />
<br />
In [[iNES|the original .NES format]], byte 8 of the file's header should indicate how many pages are present, but ROM images in the wild that use this mapper may not have byte 8 set correctly, nor do emulators necessarily honor this number.<br />
Byte 10 of the [[NES 2.0]] header should be reliable.<br />
<br />
==== Emulation quirks with commercial games ====<br />
<br />
* ''Bandit Kings of Ancient China'' maps PRG-RAM to the CPU $8000+ area and expects to be able to write to it through there. Failure to emulate this causes corruption when the background is restored on the world map.<br />
* ''Uncharted Waters'' requires emulating bankswitching of PRG RAM: it writes to PRG RAM at one CPU address and expects to be able to read the same data back via a different CPU address.<br />
* No ExROM game is known to write PRG RAM with one bank value and then attempt to read back the same data with a mirror of different bank value. So lacking better information, mirroring can be ignored, 64KB of WRAM could be emulated at all times, and $5113 can be treated as a simple page offset into that 64KB. Emulating 32KB won't work, even if no games used more than that; because 16KB games will expect to see their two distinct pages by toggling bit 2, not bit 0. However, it's not advisable to rely on this fallback behavior for newly produced homebrew because people making a physical reproduction will not know from the header how much RAM to include on the cartridge board.<ref>[https://forums.nesdev.org/viewtopic.php?p=230927#p230927 lidnariq's comment about puNES]</ref><br />
<br />
=== CHR Bankswitching ($5120-$5130) ===<br />
When using 8x8 sprites, only registers $5120-$5127 are used. Registers $5128-$512B are completely ignored.<br />
<br />
When using 8x16 sprites, registers $5120-$5127 specify banks for sprites, registers $5128-$512B apply to background tiles, and the last set of registers written to (either $5120-$5127 or $5128-$512B) will be used for I/O via [[PPUDATA]] ($2007). [https://forums.nesdev.org/viewtopic.php?p=193069#p193069] [http://forums.nesdev.org/viewtopic.php?p=194120#p194120] The MMC5 knows that sprite data is being fetched by counting the number of fetches since the last detected scanline start, similar to how it detects the position for the vertical split.<br />
<br />
''Bandit Kings of Ancient China'' and ''Uchuu Keibitai SDF'' have non-pattern data stored in CHR ROM, read out via $2007.<br />
<br />
The MMC5 is known to listen to the same address as the PPU to find out when to enable the 8x16 sprite mode; see [[#8x16_mode_enable_1_.28.242000_.3D_PPUCTRL.29|above]].<br />
<br />
==== CHR select $5120-$512B ====<br />
{| class="wikitable"<br />
! !! colspan=4|PPU memory affected for each mode (see [[#CHR mode ($5101)]])<br />
|-<br />
! Register !! 1 KiB !! 2 KiB !! 4 KiB !! 8 KiB<br />
|-<br />
| '''$5120''' || $0000-$03FF || none || none || none<br />
|-<br />
| '''$5121''' || $0400-$07FF || $0000-$07FF || none || none<br />
|-<br />
| '''$5122''' || $0800-$0BFF || none || none || none<br />
|-<br />
| '''$5123''' || $0C00-$0FFF || $0800-$0FFF || $0000-$0FFF || none<br />
|-<br />
| '''$5124''' || $1000-$13FF || none || none || none<br />
|-<br />
| '''$5125''' || $1400-$17FF || $1000-$17FF || none || none<br />
|-<br />
| '''$5126''' || $1800-$1BFF || none || none || none<br />
|-<br />
| '''$5127''' || $1C00-$1FFF || $1800-$1FFF || $1000-$1FFF || $0000-$1FFF<br />
|-<br />
| '''$5128''' || $0000-$03FF and $1000-$13FF || none || none || none<br />
|-<br />
| '''$5129''' || $0400-$07FF and $1400-$17FF || $0000-$07FF and $1000-$17FF || none || none<br />
|-<br />
| '''$512A''' || $0800-$0BFF and $1800-$1BFF || none || none || none<br />
|-<br />
| '''$512B''' || $0C00-$0FFF and $1C00-$1FFF || $0800-$0FFF and $1800-$1FFF || $0000-$0FFF and $1000-$1FFF || $0000-$1FFF<br />
|}<br />
<br />
'''Caution:''' Unlike the MMC1 and unlike PRG banking on the MMC5, the banks are always indexed by the ''currently selected size''. When using 2kb, 4kb or 8kb bank sizes, the registers hold bank index of that larger size, and lower bits are *not* ignored.<br />
<br />
==== Upper CHR Bank bits ($5130) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxBB<br />
||<br />
++- Upper bits for subsequent CHR bank writes<br />
<br />
When the MMC5 is using 2KB/1KB CHR banks, only 512KB/256KB of CHR ROM can be selected using the previous registers. To access all 1024KB in those modes, first write the upper bit(s) to register $5130 and then write the lower bits to $5120-$512B.<br />
When the Extended RAM mode is set to 1, this selects which 256KB of CHR ROM is to be used for all background tiles on the screen.<br />
<br />
The only ExROM game with CHR ROM larger than 256KB is ''Metal Slader Glory'', which uses 4KB CHR banks and does not use extended attributes. In other words, no official game relies on this register, and most don't even initialize it.<br />
<br />
=== Other Registers ===<br />
<br />
==== Vertical Split Mode ($5200) ====<br />
7 bit 0<br />
---- ----<br />
ESxW WWWW<br />
|| | ||||<br />
|| +-++++- Specify vertical split start/stop tile<br />
|+-------- Specify vertical split screen side (0:left; 1:right)<br />
+--------- Enable vertical split mode<br />
<br />
When vertical split mode is enabled, all VRAM fetches corresponding to the appropriate screen region will be redirected to Extended RAM (as long as its mode is set to 0 or 1).<br />
<br />
''Uchuu Keibitai SDF'' uses split screen mode during the intro, where it shows ship stats. ''Bandit Kings of Ancient China'' uses split screen mode during the ending sequence<ref>https://forums.nesdev.org/viewtopic.php?f=2&t=12764</ref>.<br />
<br />
===== Operation Notes =====<br />
<br />
34 BG tiles are fetched per scanline. MMC5 performs the split by watching which BG tile is being fetched,<br />
and if it is within the split region, replacing the normal NT data with the split screen data according to<br />
the absolute screen position of the tile (i.e., ignoring the coarse horizontal and vertical scroll output<br />
as part of the VRAM address for the fetch). Since it operates on a per-tile basis, fine horizontal<br />
scrolling "carries into" the split region: setting the horizontal scroll to 1-7 will result in the split<br />
being moved to the left 1-7 pixels. Whenever scrolling exceeds a multiple of 8, the split will "snap" back to its normal<br />
position.<br />
<br />
Left Split:<br />
* Tiles 0 to T-1 are the split.<br />
* Tiles T and on are rendered normally.<br />
<br />
Right Split:<br />
* Tiles 0 to T-1 are rendered normally.<br />
* Tiles T and on are the split.<br />
<br />
There is no coarse horizontal scrolling of any kind for the split. Right-side splits will always show the<br />
right-hand side of the nametable, and left-hand splits will always show the left-hand side of the nametable.<br />
Coarse horizontal scrolling can still be used for the non-split region.<br />
<br />
ExRAM is always used as the nametable in split screen mode.<br />
<br />
Vertical scrolling for the split operates like normal vertical scrolling. 0-239 are valid scroll values,<br />
whereas 240-255 will display Attribute table data as NT data for the first few scanlines. The split nametable<br />
will wrap so that the top of the nametable will appear below as you scroll (just as if vertical mirroring<br />
were employed).<br />
<br />
$5202 selects (yet another) CHR page to use for the BG. This page is used for the split region only.<br />
<br />
==== Vertical Split Scroll ($5201) ====<br />
All eight bits specify the vertical scroll value to use in split region<br />
<br />
MMC5 boards wired in "CL" mode should only use vertical scroll values whose bottom 3 bits match the [[PPU]]'s fine vertical scroll value. Using a mismatched value will cause tiles to seem to "roll" within themselves. In "SL" mode, any values can be used.<br />
<br />
Horizontal scrolling is not allowed within the split region.<br />
<br />
==== Vertical Split Bank ($5202) ====<br />
All eight bits select a 4 KB CHR bank at $0000-$0FFF and $1000-$1FFF while rendering the split region.<br />
<br />
==== IRQ Scanline Compare Value ($5203) ====<br />
All eight bits specify the target scanline number at which to generate a scanline IRQ. Value $00 is a special case that will not produce IRQ pending conditions, though it is possible to get an IRQ while this is set to $00 (due to the pending flag being set already.) You will need to take additional measures to fully suppress the IRQ. See the detailed discussion.<br />
<br />
==== Scanline IRQ Status ($5204, read/write) ====<br />
===== Write =====<br />
7 bit 0<br />
---- ----<br />
Exxx xxxx<br />
|<br />
+--------- Scanline IRQ Enable flag (1=enabled)<br />
<br />
===== Read =====<br />
7 bit 0<br />
---- ----<br />
SVxx xxxx MMC5A default power-on value = $00<br />
||<br />
|+-------- "In Frame" flag<br />
+--------- Scanline IRQ Pending flag<br />
<br />
The Scanline IRQ Pending flag becomes set at any time that the internal scanline counter matches the value written to register $5203. If the scanline IRQ is enabled, it will also generate /IRQ to the system.<br />
<br />
The "In Frame" flag is set when the PPU is rendering a frame and cleared during vertical blank.<br />
<br />
Any time this register is read, the Scanline IRQ Pending flag is cleared (acknowledging the IRQ).<br />
<br />
For details, see [[MMC5#IRQ_Counter_Operation|IRQ counter operation]].<br />
<br />
==== Unsigned 8x8 to 16 Multiplier ($5205, $5206 read/write) ====<br />
The unsigned 16-bit product is available to be read from these registers immediately after writing. All 65536 combinations of multiplicand and multiplier were tested and verified correct on MMC5A here[https://forums.nesdev.org/viewtopic.php?p=226537#p226537].<br />
===== Write =====<br />
*$5205 8-bit Unsigned Multiplicand<br />
*$5206 8-bit Unsigned Multiplier<br />
*MMC5A default power-on write value = $FF for both of these registers.<br />
<br />
===== Read =====<br />
*$5205 Unsigned 16-bit Product (low byte)<br />
*$5206 Unsigned 16-bit Product (high byte)<br />
*MMC5A default power-on read value = $FE01, i.e. $FF * $FF.<br />
<br />
=== MMC5A Only ===<br />
Registers $5207, $5208, $5209, $520A, and range $5800-$5BFF are present only in MMC5A.<br />
==== CL3 / SL3 Data Direction and Output Data Source (MMC5A: $5207 write only) ====<br />
7 bit 0<br />
---- ----<br />
ABxx xxCD MMC5A default power-on write value = 11xx xxxx<br />
|| ||<br />
|| |+- MMC5.97 (CL3) Output Data Source (0 = $5208.6 value written, 1 = !(M2) when CPU is reading in range $5800-$5BFF)<br />
|| +-- MMC5.98 (SL3) Output Data Source (0 = $5208.7 value written, 1 = !(M2) when CPU is writing in range $5800-$5BFF)<br />
|+-------- MMC5.97 (CL3) Data Direction (0 = output, 1 = input)<br />
+--------- MMC5.98 (SL3) Data Direction (0 = output, 1 = input)<br />
<br />
==== CL3 / SL3 Status (MMC5A: $5208 read/write) ====<br />
===== Write =====<br />
7 bit 0<br />
---- ----<br />
ABxx xxxx MMC5A default power-on write value = 00xx xxxx<br />
||<br />
|+-------- Value to be output on MMC5.97 pin (CL3) if/when $5207.0 = 0 and $5207.6 = 0<br />
+--------- Value to be output on MMC5.98 pin (SL3) if/when $5207.1 = 0 and $5207.7 = 0<br />
<br />
===== Read =====<br />
7 bit 0<br />
---- ----<br />
ABxx xxxx<br />
||<br />
|+-------- Input value of MMC5.97 pin (CL3)<br />
+--------- Input value of MMC5.98 pin (SL3)<br />
<br />
==== 16-bit Hardware Timer with IRQ (MMC5A: $5209 read/write, $520A write) ====<br />
===== Read =====<br />
*$5209<br />
7 bit 0<br />
---- ----<br />
Vxxx xxxx MMC5A default power-on read value = $00<br />
|<br />
+--------- Hardware Timer IRQ Flag<br />
<br />
===== Write =====<br />
*$5209<br />
7 bit 0<br />
---- ----<br />
TTTT TTTT MMC5A default power-on write value = $00<br />
|||| ||||<br />
++++-++++- Timer count LSB<br />
<br />
*$520A<br />
7 bit 0<br />
---- ----<br />
TTTT TTTT MMC5A default power-on write value = $00<br />
|||| ||||<br />
++++-++++- Timer count MSB<br />
<br />
Based on findings from krzysiobal:<br />
The timer automatically starts when writing any value to register $5209, if the 16-bit timer value does not equal $0000. For example, to write value $0100, you would first write $01 (MSB) to register $520A, which does not start the timer. Then write $00 (LSB) to register $5209, which at that point will start the timer from value $0100.<br />
<br />
Each 8-bit value is written directly to an internal 16-bit counter that decrements on each rising edge of M2. Additional writes while the timer is running will directly overwrite that portion of the counter. Reading register $5209 while the timer is running reports $00. The transition from counter value $0001 to $0000 generates an IRQ and sets the hardware timer IRQ flag. The timer stops at this point. Reading this register reports the IRQ flag, then automatically clears the IRQ and IRQ flag.<br />
<br />
If the MMC5 detects a reset, it clears the timer if active, and it clears the IRQ and IRQ flag if set. Reset detection works by looking for a gap larger than about 11 usec on M2.<br />
<br />
This register's IRQ operation is completely independent from register $5204. Disabling interrupts through $5204 does not make any effect, also reading $5204 does not report IRQ pending when IRQ is asserted by $5209.<br />
<br />
==== Unknown Address Range (MMC5A: $5800-$5BFF, write only) ====<br />
Reads and writes in this address range are reflected on the CL3 and SL3 pins when register $5207 = $03. The purpose of this function is unknown. Minute VCC current spikes shortly after rising edge of M2 during writes in this range exhibit the same characteristics as writes in expansion RAM range $5C00-$5FFF, suggesting possible existence of RAM in this range, though experimentally reading from this range is always met with open CPU bus.<br />
<br />
Address $5800 is written to by Just Breed. During each V-Blank, it writes value $03, then $01 to this address, reads and writes to PPU registers, then writes value $00 to this address once complete.<br />
<br />
=== Expansion RAM ($5C00-$5FFF, read/write) ===<br />
* Mode 0/1 - Not readable (returns [[open bus]]), can only be written while the PPU is rendering (otherwise, 0 is written)<br />
* Mode 2 - Readable and writable<br />
* Mode 3 - Read-only<br />
<br />
In Mode 1, nametable fetches are processed normally, and can come from CIRAM nametables, fill mode, or even Expansion RAM, but attribute fetches are replaced by data from Expansion RAM.<br />
<br />
Each byte of Expansion RAM is used to enhance the tile at the corresponding address in every nametable (so the extended attributes are 1-screen mirrored):<br />
<br />
7 bit 0<br />
---- ----<br />
AACC CCCC<br />
|||| ||||<br />
||++-++++- Select 4 KB CHR bank to use with specified tile<br />
++-------- Select palette to use with specified tile<br />
<br />
The pattern fetches ignore the standard CHR banking bits, and instead use the top two bits of $5130 and the bottom 6 bits from Expansion RAM to choose a 4KB bank to select the tile from.<br />
<br />
''Just Breed'', ''Yakuman Tengoku'', and the Koei games use extended attributes continuously.<br />
<br />
== Scanline Detection and Scanline IRQ ==<br />
[[File:mmc5_in_frame_status_bit.png|thumb|right|MMC5 'in frame' status bit state diagram]]<br />
The MMC5 detects scanlines by first looking for three consecutive PPU reads from the same nametable address in the range $2xxx. Once this has been seen, the next PPU read, regardless of address, is the point at which the scanline is detected. This works because the PPU does two matching dummy nametable byte reads at the end of each scanline, followed by a third matching nametable byte read at the beginning of the next scanline, followed by an attribute table byte read. So, the scanline gets detected when the PPU does the attribute table byte read, which is at PPU cycle 4.<br />
<br />
Once that occurs, if the "in-frame" flag (register $5204) was clear, it becomes set, and the internal 8-bit scanline counter is reset to zero; but if it was already set, the scanline counter is incremented, then compared against the value written to $5203. If they match, the "irq pending" flag is set.<br />
<br />
The IRQ pending flag is raised when the desired scanline is reached ''regardless'' of whether or not the scanline IRQ is enabled, i.e. even after a 0 was written to the scanline IRQ enable flag. However, an actual IRQ is only sent to the CPU if both the scanline IRQ enable flag and IRQ pending flag are set. A $5203 value of $00 is a special case that will never generate an IRQ. The MMC5's scanline IRQ occurs at PPU cycle 4, unlike the simpler scanline counter of the MMC3, which usually generates an IRQ around PPU cycle 260. See also [http://forums.nesdev.org/viewtopic.php?t=7653].<br />
<br />
The "in-frame" flag is cleared when the PPU is no longer rendering. This is detected when 3 CPU cycles pass without a PPU read having occurred (PPU /RD has not been low during the last 3 M2 rises). The PPU does this in these conditions:<br />
* the PPU begins the post-render scanline 240<br />
* the PPU stops rendering because the user program wrote to CPU address $2001 with bits 3 and 4 clear.<br />
* note: the MMC5 does not listen directly to writes to $2001 for this behavior.<br />
<br />
The "in frame" flag is cleared, scanline IRQ is automatically acknowledged, and the internal scanline counter is reset in any of these conditions:<br />
* the V-blank NMI occurs, i.e. CPU reads the interrupt vector from addresses $FFFA and $FFFB<br />
* the user program intentionally reads from CPU addresses $FFFA or $FFFB<br />
* the 241st scanline is detected.<br />
<br />
The scanline IRQ is acknowledged, but the "in frame" flag is not cleared and the scanline counter is not reset in any of these conditions:<br />
* the user program reads register $5204<br />
* scanline 0 is detected<br />
<br />
When system reset detection occurs, the only thing that happens is scanline IRQ becomes disabled. All other operation continues unaffected. These things happen any time that scanline IRQ becomes disabled:<br />
* if /IRQ was low due to scanline IRQ pending flag, /IRQ returns high<br />
* the scanline IRQ pending flag remains unaffected<br />
* register $5203 value remains unaffected<br />
* scanline counter remains unaffected<br />
* enabling the scanline IRQ will cause immediate /IRQ low if IRQ pending flag is set, but will not affect anything else<br />
<br />
This means in pseudo-code:<br />
(On every PPU read -- PPU /RD falling edge)<br />
if address >= $2000 and address <= $2FFF and address == lastAddress<br />
matchCount := matchCount +1<br />
if matchCount == 2<br />
if inFrame == false<br />
inFrame := true<br />
scanline := 0<br />
else<br />
scanline := scanline +1<br />
if scanline == [$5203]<br />
irqPending := true<br />
else<br />
matchCount := 0<br />
lastAddress := address<br />
ppuIsReading := true<br />
<br />
(On every CPU cycle -- M2 rising edge)<br />
if ppuIsReading<br />
idleCount := 0<br />
else<br />
idleCount := idleCount +1 <br />
if idleCount == 3<br />
inFrame := false<br />
lastAddress := undefined<br />
ppuIsReading := false<br />
<br />
(On every CPU write)<br />
if address == $2001 and (value & $18) == 0<br />
inFrame := false<br />
lastAddress := undefined<br />
<br />
(On every CPU read)<br />
if address == $FFFA or address == $FFFB<br />
inFrame := false<br />
lastAddress := undefined<br />
<br />
Please refer to the state diagrams on the right for a more formal description of the scanline and in-frame detection counters.<br />
<br />
The system reset detection observed in the 16-bit software timer does not appear to have any effect on the 'in frame' status bit or the state diagram on the right. It is unknown if reset detection clears the scanline counter or a pending scanline IRQ.<br />
<br />
== Hardware ==<br />
<br />
The MMC5 exists in a 100-pin rectangular QFP package, see [[MMC5 pinout]] for details.<br />
<br />
MMC5 cartridge PCBs can be configured to different modes, see [[ExROM]] for details.<br />
<br />
At least two different versions of the MMC5 are known to exist: MMC5, and MMC5A. MMC5A has the addition of registers $5207, $5208, $5209, and $520A: SL3/CL3 control and hardware timer.<br />
<br />
== References ==<br />
<references /><br />
<br />
== External links ==<br />
* NES Mapper list by Disch [http://www.romhacking.net/documents/362/]<br />
* Nintendo MMC5 by goroh, translated by Sgt. Bowhack [//nesdev.org/mmc5-e.txt]<br />
* Nintendo MMC5 Bankswitching by Kevin Horton [//nesdev.org/mmc5_bank_switch.txt]</div>Zeromushttps://www.nesdev.org/w/index.php?title=Action_53_mapper&diff=735Action 53 mapper2017-02-28T02:10:55Z<p>Zeromus: /* Reference implementations */ edit bizhawk rSVN to commit hash</p>
<hr />
<div>The '''Action 53 mapper''' allows making a multicart of games that use multiple discrete mappers. It was assigned to [[iNES Mapper 028]].<br />
<br />
Examples:<br />
* ''[[Action 53|STREEMERZ: Action 53 Function 16 Volume One]]''<br />
* ''[[Action 53|Double Action 53]]''<br />
<br />
<br />
<br />
== Registers ==<br />
;$5000-$5FFF: Register select<br />
;$8000-$FFFF: Register value<br />
<br />
=== $5000: Register select ===<br />
<pre><br />
7654 3210<br />
S R<br />
| +- Select register<br />
+--------- 0: User registers; 1: Supervisor registers<br />
</pre><br />
In a multicart, registers $00 and $01 change the bank within a game, and registers $80 and $81 remain constant throughout a given game's execution.<br />
Some games ported from [[SxROM|SGROM]] may rewrite register $80, usually to change mirroring.<br />
<br />
=== $00: CHR bank ===<br />
<pre><br />
7654 3210<br />
M BB<br />
| ++- Set CHR RAM A14-A13<br />
+------ Set mirroring mode bit 0 if H/V mirroring is disabled<br />
</pre><br />
<br />
=== $01: Inner bank ===<br />
<pre><br />
7654 3210<br />
M BBBB<br />
| ++++- Set current PRG ROM bank<br />
+------ Set mirroring mode bit 0 if H/V mirroring is disabled<br />
</pre><br />
If the current mirroring mode is one of the 1-screen modes (0 or 1), writes to registers $00 and $01 change bit 0 of the mirroring mode to D4 of the written value.<br />
(This simulates the mirroring control of [[AxROM]].)<br />
If the current mirroring mode is vertical or horizontal (2 or 3), D4 is ignored.<br />
<br />
=== $80: Mode ===<br />
<pre><br />
7654 3210<br />
SS PPMM<br />
|| ||++- Nametable mirroring mode<br />
|| ++--- PRG bank mode<br />
++------ PRG outer bank size<br />
</pre><br />
{| class="tabular"<br />
|+ Mirroring modes<br />
! Mode || Effect || A10 output || Effect of write to register $00 or $01<br />
|-<br />
| 0 || 1-screen lower bank || 0 || D4 changes bit 0 of the mirroring mode<br />
|-<br />
| 1 || 1-screen upper bank || 1 || D4 changes bit 0 of the mirroring mode<br />
|-<br />
| 2 || Vertical || PPU A10 || D4 is ignored<br />
|-<br />
| 3 || Horizontal || PPU A11 || D4 is ignored<br />
|}<br />
While the mirroring mode is 0 or 1 (1-screen), bit 0 is can be written in three places: bit 0 of $80, bit 4 of $00, or bit 4 of $01.<br />
<br />
[[File:Multi-discrete PRG bank.png|frame|right|Logic table, with o = $81 value and i = $01 value]]<br />
{| class="tabular"<br />
|+ PRG bank mode<br />
! Mode || Simulates || Effect<br />
|-<br />
| 0, 1 || BNROM/AOROM || Current 32 KiB bank in $8000-$FFFF<br />
|-<br />
| 2 || UNROM (#180) || Fixed bottom half of outer bank in $8000-$BFFF<br>Current bank in $C000-$FFFF<br />
|-<br />
| 3 || UNROM (#2) || Current bank in $8000-$BFFF<br>Fixed top half of outer bank in $C000-$FFFF<br />
|}<br />
When the fixed bank ($8000-$BFFF in mode 2 or $C000-$FFFF in mode 3) is accessed, it treats accesses to the fixed bank the same way as accesses in mode 0 with 32K: the outer bank bits are passed straight through.<br />
For example, this would allow the fixed $C000 bank in mode 3 128K to be set to 16K bank 7 (as in mapper 2) or 1, 3, or 5.<br />
In mode 2 128K, the fixed $8000 bank could be configured as 16K bank 0 (as in mapper 180) or 2, 4, or 6.<br />
<br />
{| class="tabular"<br />
|+ PRG outer bank size<br />
! Size || Effect<br />
|-<br />
| 0 || A15 and up controlled by outer bank (32 KiB)<br />
|-<br />
| 1 || A16 and up controlled by outer bank (64 KiB)<br />
|-<br />
| 2 || A17 and up controlled by outer bank (128 KiB)<br />
|-<br />
| 3 || A18 and up controlled by outer bank (256 KiB)<br />
|}<br />
Again, when a fixed bank is being accessed, this is temporarily forced to 32K, allowing all outer bank bits to come through.<br />
<br />
These are the outputs on A22-A14 in each of the 12 combinations of mode and size, with '''o''' used for outer bank bits and '''i''' used for inner bank bits:<br />
{| class="tabular"<br />
! Mode value || PRG bank mode || Outer bank size || Bank in $8000 || Bank in $C000<br />
|-<br />
| $00-$07 || 32 KiB || 32 KiB || <code>oooooooo<span style="background:#FF6">0</span></code> || <code>oooooooo<span style="background:#FF6">1</span></code><br />
|-<br />
| $08-$0B || Fixed $8000 || 32 KiB || <code>oooooooo<span style="background:#FF6">0</span></code> || <code>ooooooooi</code><br />
|-<br />
| $0C-$0F || Fixed $C000 || 32 KiB || <code>ooooooooi</code> || <code>oooooooo<span style="background:#FF6">1</span></code><br />
|-<br />
| $10-$17 || 32 KiB || 64 KiB || <code>oooooooi<span style="background:#FF6">0</span></code> || <code>oooooooi<span style="background:#FF6">1</span></code><br />
|-<br />
| $18-$1B || Fixed $8000 || 64 KiB || <code>oooooooo<span style="background:#FF6">0</span></code> || <code>oooooooii</code><br />
|-<br />
| $1C-$1F || Fixed $C000 || 64 KiB || <code>oooooooii</code> || <code>oooooooo<span style="background:#FF6">1</span></code><br />
|-<br />
| $20-$27 || 32 KiB || 128 KiB || <code>ooooooii<span style="background:#FF6">0</span></code> || <code>ooooooii<span style="background:#FF6">1</span></code><br />
|-<br />
| $28-$2B || Fixed $8000 || 128 KiB || <code>oooooooo<span style="background:#FF6">0</span></code> || <code>ooooooiii</code><br />
|-<br />
| $2C-$2F || Fixed $C000 || 128 KiB || <code>ooooooiii</code> || <code>oooooooo<span style="background:#FF6">1</span></code><br />
|-<br />
| $30-$37 || 32 KiB || 256 KiB || <code>oooooiii<span style="background:#FF6">0</span></code> || <code>oooooiii<span style="background:#FF6">1</span></code><br />
|-<br />
| $38-$3B || Fixed $8000 || 256 KiB || <code>oooooooo<span style="background:#FF6">0</span></code> || <code>oooooiiii</code><br />
|-<br />
| $3C-$3F || Fixed $C000 || 256 KiB || <code>oooooiiii</code> || <code>oooooooo<span style="background:#FF6">1</span></code><br />
|}<br />
For all of these cases, the "o"s come from the '''topmost''' outer bank bits and the "i"s come from the '''bottommost''' inner bank bits.<br />
<br />
=== $81: Outer bank ===<br />
<pre><br />
7654 3210<br />
BBBB BBBB<br />
++++-++++- Set outer PRG ROM bank<br />
</pre><br />
When the outer bank size is set greater than 32K, the bank number is not barrel shifted.<br />
Instead, the least significant bits are ignored.<br />
Bits 5 through 3, for example, always control PRG ROM A20 through A18.<br />
<br />
Many implementations recognize only the lower 4 or 6 bits for two reasons: memory cost and the practical limit of 2 MiB PRG ROM in an [[iNES]] ROM image.<br />
The PowerPak uses only the low 4 bits, as it has only 512 KiB of RAM for PRG ROM.<br />
And by the 2010s, 5-volt 8-bit parallel flash memories larger than 2Mx8 had become hard to find.<br />
An implementation supporting [[NES 2.0#Byte 9 (Upper bits of ROM size)|NES 2.0 large ROMs]] should [[Oversize|recognize all bits]] for a maximum of 8 MiB.<br />
<br />
== Power up state ==<br />
At power on, the last 16 KiB of the ROM is mapped into $C000-$FFFF.<br />
The rest of the state is unspecified.<br />
The mapper state is unchanged on reset.<br />
<br />
''Non-normative:''<br />
One possible init sequence involves setting reg $81 = $FF and reg $80 = $02 to get into oversize-BNROM mode.<br />
<br />
''Non-normative:''<br />
If desired, games in a multicart can be patched with an appropriate reset stub to allow returning to the menu.<br />
The Action 53 build tool does this semi-automatically for NROM games.<br />
<br />
== Configurations ==<br />
;NROM-128 ([[iNES Mapper 000|#0]]): Outer bank size 0, PRG mode 2 or 3, mirroring H or V, select $01<br />
;NROM-256 ([[iNES Mapper 000|#0]]): Outer bank size 0, PRG mode 0, mirroring H or V, select $01<br />
;CNROM ([[iNES Mapper 003|#3]]): Outer bank size 0, PRG mode 0, mirroring H or V, select $00<br />
;BNROM ([[iNES Mapper 034|#34]]): Outer bank size 1-3, PRG mode 0, mirroring H or V, select $01<br />
;BNROM oversize ([[iNES Mapper 034|#34]] as emulated): Outer bank size 0, PRG mode 0, mirroring H or V, select $81, and modify bus-conflict-avoidance table for position within multicart<br />
;UNROM (common) ([[iNES Mapper 002|#2]]): Outer bank size 1-3, PRG mode 3, mirroring H or V, select $01<br />
;UNROM (Crazy Climber and MGC 2011) ([[iNES Mapper 180|#180]]): Outer bank size 1-3, PRG mode 2, mirroring H or V, select $01<br />
;AOROM ([[iNES Mapper 007|#7]]): Outer bank size 1-3, PRG mode 0, mirroring 1-screen, select $01<br />
<br />
== Reference implementations ==<br />
See [[Action 53 mapper/Reference implementations]] for functions in Python and 6502 assembly language that calculate the bank number output to PRG ROM A20-A14 as described above. These may be used to verify emulator or hardware implementations.<br />
<br />
Supported in the following emulators:<br />
* FCEUX (2.2.2)<br />
* Bizhawk [https://github.com/TASVideos/BizHawk/commit/c217768871617ba9d6343896a47123f7027e392d c217768]<br />
* Nintendulator<br />
<br />
== <span id="Verilog_Code">Hardware implementations</span> ==<br />
<br />
Two [[Action 53 mapper/Verilog|implementations in Verilog]] are designed for use on a CPLD.<br />
One has been tested on a PowerPak as [http://forums.nesdev.org/viewtopic.php?p=102718#p102718 MAP1C.MAP].<br />
<br />
The MiST FPGA computer includes an [https://github.com/mist-devel/mist-board/blob/master/cores/nes/src/mmu.v implementation in Verilog].<br />
<br />
== Implementation notes ==<br />
Input pins: 2 power, 16 signal<br />
* Power and ground<br />
* CPU D7, D5-D0 (D6 used only in 4-8 MB version)<br />
* CPU A14-A12, /PRGSEL, M2, R/W<br />
* PPU A12-A10<br />
Output pins: 12 signal<br />
* CHR RAM A14-A13<br />
* CIRAM A10<br />
* PRG ROM A20-A14, /CE<br />
* Optional PRG RAM enable ($6000-$7FFF)<br />
<br />
A CPLD requires one macrocell per bit of state and one for each output pin controlled by a multiplexer, plus possibly a couple more for more complex operations.<br />
When configured for PRG ROM up to 2 MB, this mapper requires 20 bits of state and 7 multiplexed outputs, which fits comfortably in a 32- or 36-cell CPLD.<br />
* Register select: 2 bits<br />
* Register $00: 2 bits (D4 is directed to register $80)<br />
* Register $01: 4 bits (D4 is directed to register $80)<br />
* Register $80: 6 bits<br />
* Register $81: 6 bits<br />
* A17-A14: 4 multiplexed outputs<br />
* CIRAM A10: 1 multiplexed output<br />
* PRG ROM /CE: 1 multiplexed output<br />
* PRG RAM /CE: 1 multiplexed output<br />
<br />
After synthesizing and laying fitting within a XC9536XL CPLD 27/36 Macrocells were consumed (75%).<br />
Additionally this design requires 25/34 available pins on the XC9536XL.<br />
<br />
Adding WRAM control requires 2 Macrocells and 2 pins.<br />
<br />
Lowering to 1 MB by shaving off PRG ROM A20 would save 1 Macrocell and 1 pin, if desired.<br />
<br />
== See Also ==<br />
*[[Action 53 manual]]<br />
<br />
== External links ==<br />
*[http://forums.nesdev.org/viewtopic.php?p=102693#p102693 test28], a comprehensive test ROM<br />
*[http://forums.nesdev.org/viewtopic.php?p=101111#p101111 Forum post announcing reservation of #28]<br />
*[http://forums.nesdev.org/viewtopic.php?p=101970#p101970 Forum post announcing implementation in NESICIDE]<br />
<br />
[[Category:Multicart mappers]]<br />
[[Category:Mappers using $4020-$5FFF]]</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_190&diff=5454INES Mapper 1902017-02-12T05:48:19Z<p>Zeromus: categorize</p>
<hr />
<div>{{DEFAULTSORT:190}}[[Category:iNES Mappers]]<br />
<br />
This mapper was assigned by Kevtris for a newly-dumped game from 1992: Magic Kid GooGoo<br />
<br />
Here's a page discussing it: http://forums.lostlevels.org/viewtopic.php?p=35234<br />
<br />
Mednafen supported it with [[0.9.42|http://forum.fobby.net/index.php?t=msg&th=1483]]<br />
<br />
FCEUX supported it with [[r3334|https://sourceforge.net/p/fceultra/code/3334/ ]]<br />
<br />
Finally, I will attach Kevtris's notes on the mapper:<br />
<br />
<pre><br />
<br />
Magic Kid GooGoo<br />
----------------<br />
<br />
012517<br />
Kevtris<br />
<br />
<br />
I have assigned this game mapper 190. Fortunately the mapper is fairly<br />
simple, being composed of two 74LS670 4*4 register file chips, a PAL16R4,<br />
some pullup resistors, two ROMs and an 8K WRAM.<br />
<br />
The mapper is fairly straight forward, but kind of weird. <br />
<br />
PRG switching:<br />
--------------<br />
<br />
There's 16 16K PRG ROM banks, but a combination of address and data lines are used<br />
to select it.<br />
<br />
C000-FFFF is set to the *first* bank of ROM at all times (vs. the more common<br />
last bank of ROM).<br />
<br />
8000-BFFF is selectable by writing to either 8000-9FFF or C000-DFFF.<br />
<br />
Writing to 8000-9FFF will select bank 0-7 depending on D0-D2.<br />
Writing to C000-DFFF will select bank 8-15 depending on D0-D2.<br />
<br />
So the 4 bank bits are formed like so:<br />
<br />
A14, D2, D1, D0 (highest bit to lowest bit)<br />
<br />
I don't know why they did it this way but they did.<br />
<br />
There is also 8K of RAM mapped in at 6000-7FFF. This RAM is always enabled and is<br />
not battery backed.<br />
<br />
<br />
CHR Switching:<br />
--------------<br />
<br />
CHR is composed of 4 2K banks at 0000-07FF, 0800-0FFF, 1000-17FF, 1800-1FFF.<br />
<br />
Writing to A000 selects the bank at 0000-07FF in PPU space,<br />
A001 selects the bank at 0800-0FFF<br />
A002 selects the bank at 1000-17FF<br />
A003 selects the bank at 1800-1FFF<br />
<br />
Only A0, A1, A13, 14, and 15 are used to select the CHR bank and match the following mask:<br />
<br />
101x xxxx xxxx xxbb<br />
<br />
b = CHR bank # to change. <br />
<br />
This means that A000, A004, A008, A00C, ... BFF8, BFFC all set the first 2K CHR bank.<br />
</pre></div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_190&diff=5453INES Mapper 1902017-02-12T05:47:00Z<p>Zeromus: add mapper 190</p>
<hr />
<div>This mapper was assigned by Kevtris for a newly-dumped game from 1992: Magic Kid GooGoo<br />
<br />
Here's a page discussing it: http://forums.lostlevels.org/viewtopic.php?p=35234<br />
<br />
Mednafen supported it with [[0.9.42|http://forum.fobby.net/index.php?t=msg&th=1483]]<br />
<br />
FCEUX supported it with [[r3334|https://sourceforge.net/p/fceultra/code/3334/ ]]<br />
<br />
Finally, I will attach Kevtris's notes on the mapper:<br />
<br />
<pre><br />
<br />
Magic Kid GooGoo<br />
----------------<br />
<br />
012517<br />
Kevtris<br />
<br />
<br />
I have assigned this game mapper 190. Fortunately the mapper is fairly<br />
simple, being composed of two 74LS670 4*4 register file chips, a PAL16R4,<br />
some pullup resistors, two ROMs and an 8K WRAM.<br />
<br />
The mapper is fairly straight forward, but kind of weird. <br />
<br />
PRG switching:<br />
--------------<br />
<br />
There's 16 16K PRG ROM banks, but a combination of address and data lines are used<br />
to select it.<br />
<br />
C000-FFFF is set to the *first* bank of ROM at all times (vs. the more common<br />
last bank of ROM).<br />
<br />
8000-BFFF is selectable by writing to either 8000-9FFF or C000-DFFF.<br />
<br />
Writing to 8000-9FFF will select bank 0-7 depending on D0-D2.<br />
Writing to C000-DFFF will select bank 8-15 depending on D0-D2.<br />
<br />
So the 4 bank bits are formed like so:<br />
<br />
A14, D2, D1, D0 (highest bit to lowest bit)<br />
<br />
I don't know why they did it this way but they did.<br />
<br />
There is also 8K of RAM mapped in at 6000-7FFF. This RAM is always enabled and is<br />
not battery backed.<br />
<br />
<br />
CHR Switching:<br />
--------------<br />
<br />
CHR is composed of 4 2K banks at 0000-07FF, 0800-0FFF, 1000-17FF, 1800-1FFF.<br />
<br />
Writing to A000 selects the bank at 0000-07FF in PPU space,<br />
A001 selects the bank at 0800-0FFF<br />
A002 selects the bank at 1000-17FF<br />
A003 selects the bank at 1800-1FFF<br />
<br />
Only A0, A1, A13, 14, and 15 are used to select the CHR bank and match the following mask:<br />
<br />
101x xxxx xxxx xxbb<br />
<br />
b = CHR bank # to change. <br />
<br />
This means that A000, A004, A008, A00C, ... BFF8, BFFC all set the first 2K CHR bank.<br />
</pre></div>Zeromushttps://www.nesdev.org/w/index.php?title=Talk:NES_2.0_submappers/Proposals&diff=14836Talk:NES 2.0 submappers/Proposals2015-09-03T03:20:40Z<p>Zeromus: </p>
<hr />
<div>== Bus conflict submapper 0 ==<br />
<br />
[http://wiki.nesdev.org/w/index.php?title=NES_2.0_submappers/Proposals&oldid=11603#002.2C_003.2C_007:_UxROM.2C_CNROM.2C_AxROM This revision] makes the following suggestion:<br />
:''0: Normal (The game is believed to never elicit a bus conflict. In the event of a bus conflict, the emulator should warn, abort, or produce random values; the exact behavior is not known)''<br />
<br />
I think the goal for submapper 0 should usually be the greatest compatibility, and backwards compatibility with iNES. Setting the NES 2.0 identifier shouldn't change the behaviour of submapper 0 (if all other fields are otherwise "equivalent"). Validation tools to "warn" or "abort" could work nicely with submapper 2 (i.e. emulate bus conflicts), but I don't think they would do anything except reduce compatibility if used for submapper 0. A validation tool really shouldn't be part of the submapper definition (that's its own tool with its own goal, e.g. like nintendulator DX's thing to warn on use of uninitialized memory).<br />
<br />
Cases 1 and 2 are good, it separates two things with specific conflicting needs. I think case 0 should just delegate a recommendation for 1 or 2.<br />
<br />
* 002:0 = 002:1 ? [[UxROM]] says that mapper 002 shares UxROM with compatible boards that require no bus conflicts. (Also, that DK pie factory hack?)<br />
* 003:0 = 003:2 ? [[INES Mapper 003]] lists 1 game (Cybernoid) that requires bus conflicts, and 1 (Colorful Dragon, UNL) that requires none. Does Cybernoid get priority?<br />
* 007:0 = 007:1 ? a lack of bus conflicts is required for some existing games, but it seems that none require bus conflicts.<br />
<br />
Alternatively I would just propose that submapper 0 be used for no bus conflicts, and submapper 1 be used for AND bus conflicts, since a lack of bus conflicts might just generally produce greater compatibility? If your goal is to give homebrewers a nice testing environment that will emulate bus conflicts for them, submapper 2 does that job great, it doesn't need to be the default. The only case I've seen listed so far is Cybernoid?<br />
<br />
I was wondering about other mappers besides 002/003/007 but I am guessing that the other bus-conflicting mappers don't have the ambiguity problems and can safely always have bus conflicts on?<br />
<br />
- [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:53, 31 August 2015 (MDT)<br />
<br />
: The default for any mapper that physically has bus conflicts (even if never elicited) must not be "no bus conflicts" for reasons we have already discussed and you find uncompelling. <br />
: FCEUX has already decided that the iNES1 handler is "produce bogus values (always 0) for CNROM and UNROM" (although it used to be AND) and "no bus conflicts for other data-bus latch mappers". Nestopia has codified bus conflicts as AND, for the "standard" version of specific discrete-logic mappers (UNROM, UOROM, CNROM, BNROM) and none otherwise.<br />
:—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 18:31, 31 August 2015 (MDT)<br />
<br />
:: I'm confused by this response? We're not discussing any mappers that always had bus conflicts here. We're discussing iNES mappers 2, 3, and 7, none of which unambiguously represents a physical mapper that had bus conflicts. Mapper 2 seems to include many obscure boards, some of which reputedly require a lack of bus conflicts? (I have no source for this other than statements found on the wiki; what are the actual compatibility cases?) Mapper 3 appears to be have the only compatibility conflict among these 3 mappers, and from the two cases listed a bus-conflicts submapper 0 seems valid to me. Mapper 7 submapper 0 requires no bus conflicts for compatibility. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 19:31, 31 August 2015 (MDT)<br />
<br />
::: Your central thesis appears to be that compatibility is the foremost goal, and my argument (from experience) is that prioritizing compatibility produces homebrew that can't run on hardware, so the default must be the strictest narrowest definition instead (and that people must explicitly opt into more lenient behavior). We've already had this argument. What's the point in having it again? —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 20:41, 31 August 2015 (MDT)<br />
<br />
:::: I'm not very much interested in restating opinions about ideological concerns for the format either, but I ''am'' interested in the specific definition of mappers 2, 3, and 7 here, in response to the submapper 0 text you just proposed. I strongly feel that mapper 7's submapper 0 should not break the existing ANROM games. Are you really arguing that it should? I don't remember you ever responding about mapper 7. We don't actually seem to have a dispute about mapper 3 (i.e. submapper 0 with bus conflicts), but I am unsure about it because I can't find much information about the non-CNROM games that use this mapper? Mapper 2 there is even less knowledge about, but the Disch notes for mapper 2 state ''"UxROM has bus conflicts, however mapper 002 is meant to be UxROM and compatible. So some mappers which were similar in function, but did not have bus conflicts are included"'', but again I can't find any existing research about the games/boards involved. Is the best we can do for this an emulator survey? - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:40, 1 September 2015 (MDT)<br />
<br />
Hi guys, just thought I'd mention some ideas here even though I don't have a lot of time for this kind of stuff and probably won't be back to debate it. IMO, ines 1 mapper numbers arent strict definitions but rather a vague guide for organizing a family of functionality. Moving forward, I would like to see 'submapper 0' for mapper N to be 'do what you can to get the game to boot' without increasing the strictness of the legacy mapper's definition. Then, exceptions can be written by forwarding to a submapper. For instance, we might see: "Mapper N Submapper 0 = Mapper N Legacy Mode: A game with this submapper can't be safely run without a game-specific logic. It might have bus conflicts (handle as Submapper 1) or no bus conflicts (handle as Submapper 2)." Essentially leave submapper 0 as flexible legacy hack zone ghetto. This allows us the latitude to actually prescribe as part of the specification how legacy garbage is to be interpreted as well as set a simple rule for how to define submapper 0. If there's a channel besides #nesdev I wouldnt mind lurking and giving further feedback, but I don't have time to take a strong stance [[User:Zeromus|Zeromus]] ([[User talk:Zeromus|talk]]) 21:25, 1 September 2015 (MDT)<br />
<br />
<br />
Ok, here's a pragmatic argument: What's the ''practical'' difference between:<br />
* 300 games as submapper 0 (the ones where the hardware has bus conflicts, but the games have a bus conflict prevention table)<br />
* 2 games as submapper 1<br />
* 2 games as submapper 2<br />
And<br />
* 302 games as submapper 0<br />
* 2 games as submapper 1<br />
Especially when the size of the two minority groups is comparable? —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 12:27, 2 September 2015 (MDT)<br />
<br />
: Scenario the First has four games which can be emulated unambiguously without hacks keyed to hashes. Scenario the Second has two games which can be emulated unamiguously without hacks keyed to hashes--so two of the games won't work on every emulator listing itself as in complete Mapper N compliance without the emulator having special cases for them. . . . . . . . . . . . Now that I've thought about it one more day, I have another proposition. Using submapper 0 as a catch-all for legacy behaviour is a bad idea. We should use iNES1 headers as an indicator that legacy behaviour is required. A rom should not be graduated to iNES2 until it can be assigned to a submapper that precisely defines it. In that scenario, we have 2 games as submapper 0, 2 games as submapper 1, and 300 games in iNES1 that cannot be legally turned into iNES2 without simultaneously encoding their bus conflict needs. Now, from an organizational perspective, this would require namespacing and maybe even documenting iNES1 and iNES2 mappers separately. You could resolve this by declaring that iNES2 is a strict superset defined as enclosing iNES1 within submapper 0 (which was my original proposition). Another way of writing the rule might be: "For mappers with >1 submapper, submapper 0 means, select another submapper using a database" [[User:Zeromus|Zeromus]] ([[User talk:Zeromus|talk]]) 21:14, 2 September 2015 (MDT)</div>Zeromushttps://www.nesdev.org/w/index.php?title=Talk:NES_2.0_submappers/Proposals&diff=14835Talk:NES 2.0 submappers/Proposals2015-09-03T03:14:46Z<p>Zeromus: </p>
<hr />
<div>== Bus conflict submapper 0 ==<br />
<br />
[http://wiki.nesdev.org/w/index.php?title=NES_2.0_submappers/Proposals&oldid=11603#002.2C_003.2C_007:_UxROM.2C_CNROM.2C_AxROM This revision] makes the following suggestion:<br />
:''0: Normal (The game is believed to never elicit a bus conflict. In the event of a bus conflict, the emulator should warn, abort, or produce random values; the exact behavior is not known)''<br />
<br />
I think the goal for submapper 0 should usually be the greatest compatibility, and backwards compatibility with iNES. Setting the NES 2.0 identifier shouldn't change the behaviour of submapper 0 (if all other fields are otherwise "equivalent"). Validation tools to "warn" or "abort" could work nicely with submapper 2 (i.e. emulate bus conflicts), but I don't think they would do anything except reduce compatibility if used for submapper 0. A validation tool really shouldn't be part of the submapper definition (that's its own tool with its own goal, e.g. like nintendulator DX's thing to warn on use of uninitialized memory).<br />
<br />
Cases 1 and 2 are good, it separates two things with specific conflicting needs. I think case 0 should just delegate a recommendation for 1 or 2.<br />
<br />
* 002:0 = 002:1 ? [[UxROM]] says that mapper 002 shares UxROM with compatible boards that require no bus conflicts. (Also, that DK pie factory hack?)<br />
* 003:0 = 003:2 ? [[INES Mapper 003]] lists 1 game (Cybernoid) that requires bus conflicts, and 1 (Colorful Dragon, UNL) that requires none. Does Cybernoid get priority?<br />
* 007:0 = 007:1 ? a lack of bus conflicts is required for some existing games, but it seems that none require bus conflicts.<br />
<br />
Alternatively I would just propose that submapper 0 be used for no bus conflicts, and submapper 1 be used for AND bus conflicts, since a lack of bus conflicts might just generally produce greater compatibility? If your goal is to give homebrewers a nice testing environment that will emulate bus conflicts for them, submapper 2 does that job great, it doesn't need to be the default. The only case I've seen listed so far is Cybernoid?<br />
<br />
I was wondering about other mappers besides 002/003/007 but I am guessing that the other bus-conflicting mappers don't have the ambiguity problems and can safely always have bus conflicts on?<br />
<br />
- [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:53, 31 August 2015 (MDT)<br />
<br />
: The default for any mapper that physically has bus conflicts (even if never elicited) must not be "no bus conflicts" for reasons we have already discussed and you find uncompelling. <br />
: FCEUX has already decided that the iNES1 handler is "produce bogus values (always 0) for CNROM and UNROM" (although it used to be AND) and "no bus conflicts for other data-bus latch mappers". Nestopia has codified bus conflicts as AND, for the "standard" version of specific discrete-logic mappers (UNROM, UOROM, CNROM, BNROM) and none otherwise.<br />
:—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 18:31, 31 August 2015 (MDT)<br />
<br />
:: I'm confused by this response? We're not discussing any mappers that always had bus conflicts here. We're discussing iNES mappers 2, 3, and 7, none of which unambiguously represents a physical mapper that had bus conflicts. Mapper 2 seems to include many obscure boards, some of which reputedly require a lack of bus conflicts? (I have no source for this other than statements found on the wiki; what are the actual compatibility cases?) Mapper 3 appears to be have the only compatibility conflict among these 3 mappers, and from the two cases listed a bus-conflicts submapper 0 seems valid to me. Mapper 7 submapper 0 requires no bus conflicts for compatibility. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 19:31, 31 August 2015 (MDT)<br />
<br />
::: Your central thesis appears to be that compatibility is the foremost goal, and my argument (from experience) is that prioritizing compatibility produces homebrew that can't run on hardware, so the default must be the strictest narrowest definition instead (and that people must explicitly opt into more lenient behavior). We've already had this argument. What's the point in having it again? —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 20:41, 31 August 2015 (MDT)<br />
<br />
:::: I'm not very much interested in restating opinions about ideological concerns for the format either, but I ''am'' interested in the specific definition of mappers 2, 3, and 7 here, in response to the submapper 0 text you just proposed. I strongly feel that mapper 7's submapper 0 should not break the existing ANROM games. Are you really arguing that it should? I don't remember you ever responding about mapper 7. We don't actually seem to have a dispute about mapper 3 (i.e. submapper 0 with bus conflicts), but I am unsure about it because I can't find much information about the non-CNROM games that use this mapper? Mapper 2 there is even less knowledge about, but the Disch notes for mapper 2 state ''"UxROM has bus conflicts, however mapper 002 is meant to be UxROM and compatible. So some mappers which were similar in function, but did not have bus conflicts are included"'', but again I can't find any existing research about the games/boards involved. Is the best we can do for this an emulator survey? - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:40, 1 September 2015 (MDT)<br />
<br />
Hi guys, just thought I'd mention some ideas here even though I don't have a lot of time for this kind of stuff and probably won't be back to debate it. IMO, ines 1 mapper numbers arent strict definitions but rather a vague guide for organizing a family of functionality. Moving forward, I would like to see 'submapper 0' for mapper N to be 'do what you can to get the game to boot' without increasing the strictness of the legacy mapper's definition. Then, exceptions can be written by forwarding to a submapper. For instance, we might see: "Mapper N Submapper 0 = Mapper N Legacy Mode: A game with this submapper can't be safely run without a game-specific logic. It might have bus conflicts (handle as Submapper 1) or no bus conflicts (handle as Submapper 2)." Essentially leave submapper 0 as flexible legacy hack zone ghetto. This allows us the latitude to actually prescribe as part of the specification how legacy garbage is to be interpreted as well as set a simple rule for how to define submapper 0. If there's a channel besides #nesdev I wouldnt mind lurking and giving further feedback, but I don't have time to take a strong stance [[User:Zeromus|Zeromus]] ([[User talk:Zeromus|talk]]) 21:25, 1 September 2015 (MDT)<br />
<br />
<br />
Ok, here's a pragmatic argument: What's the ''practical'' difference between:<br />
* 300 games as submapper 0 (the ones where the hardware has bus conflicts, but the games have a bus conflict prevention table)<br />
* 2 games as submapper 1<br />
* 2 games as submapper 2<br />
And<br />
* 302 games as submapper 0<br />
* 2 games as submapper 1<br />
Especially when the size of the two minority groups is comparable? —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 12:27, 2 September 2015 (MDT)<br />
<br />
: Scenario the First has four games which can be emulated unambiguously without hacks keyed to hashes. Scenario the Second has two games which can be emulated unamiguously without hacks keyed to hashes--so two of the games won't work on every emulator listing itself as in complete Mapper N compliance without the emulator having special cases for them. . . . . . . . . . . . Now that I've thought about it one more day, I have another proposition. Using submapper 0 as a catch-all for legacy behaviour is a bad idea. We should use iNES1 headers as an indicator that legacy behaviour is required. A rom should not be graduated to iNES2 until it can be assigned to a submapper that precisely defines it. In that scenario, we have 2 games as submapper 0, 2 games as submapper 1, and 300 games in iNES1 that cannot be legally turned into iNES2 without simultaneously encoding their bus conflict needs. Now, from an organizational perspective, this would require namespacing and maybe even documenting iNES1 and iNES2 mappers separately. You could resolve this by declaring that iNES2 is a strict superset defined as enclosing iNES1 within submapper 0 (which was my original proposition) [[User:Zeromus|Zeromus]] ([[User talk:Zeromus|talk]]) 21:14, 2 September 2015 (MDT)</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_202&diff=5549INES Mapper 2022015-09-02T03:39:47Z<p>Zeromus: </p>
<hr />
<div>[[Category:iNES Mappers|202]][[Category:Multicart mappers|202]]<br />
<br />
Implemented in BizHawk as of commit f72875b584abd79201ad9d3d0131fa5afcf0c429<br />
<br />
Used for the 150-in-1 pirate cart. <br />
<br />
Registers:<br />
$8000-FFFF: A~[.... .... .... O..O]<br />
[.... .... .... RRRM]<br />
<br />
<br />
O = PRG Mode, if 3, will use 32 PRG mode, else 16<br />
R = Page registers, used for both CHR 8k banks, and PRG banks (in both 16k and 32k modes)<br />
M = Mirroring, 0 = Vertical, 1 = Horizontal<br />
<br />
CHR Setup:<br />
<br />
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00 <br />
+-------------------------------+-------------------------------+<br />
CHR-ROM: | { 0 } |<br />
+-------------------------------+-------------------------------+<br />
<br />
<br />
<br />
PRG Setup:<br />
------------------------------<br />
32k Mode:<br />
<br />
$8000 $A000 $C000 $E000<br />
+-------------------------------------+<br />
| {0} |<br />
+-------------------------------------+<br />
<br />
<br />
16k Mode:<br />
<br />
In 16k mode both regions are mapped to the same PRG bank<br />
<br />
$8000 $A000 $C000 $E000 <br />
+--------------------------------------+<br />
| {0} | {0} |<br />
+--------------------------------------+</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_202&diff=5548INES Mapper 2022015-09-02T03:32:17Z<p>Zeromus: </p>
<hr />
<div>[[Category:iNES Mappers|202]][[Category:Multicart mappers|202]]<br />
<br />
Implemented in BizHawk as of commit f72875b584abd79201ad9d3d0131fa5afcf0c429<br />
<br />
========================<br />
= Mapper 202 =<br />
========================<br />
<br />
Used for the 150-in-1 pirate cart<br />
<br />
Registers:<br />
$8000-FFFF: A~[.... .... .... O..O]<br />
[.... .... .... RRRM]<br />
<br />
<br />
O = PRG Mode, if 3, will use 32 PRG mode, else 16<br />
R = page registers, used for both chr 8k banks, and prg banks (in both 16k and 32k modes)<br />
M = Mirroring, 0 = Vertical, 1 = Horizontal<br />
<br />
CHR Setup:<br />
<br />
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00 <br />
+-------------------------------+-------------------------------+<br />
CHR-ROM: | { 0 } |<br />
+-------------------------------+-------------------------------+<br />
<br />
<br />
<br />
PRG Setup:<br />
------------------------------<br />
<br />
32k Mode:<br />
<br />
$8000 $A000 $C000 $E000<br />
+-------------------------------------+<br />
| {0} |<br />
+-------------------------------------+<br />
<br />
<br />
16k Mode:<br />
<br />
In 16k mode both regions are mapped to the same PRG bank<br />
<br />
$8000 $A000 $C000 $E000 <br />
+--------------------------------------+<br />
| {0} | {0} |<br />
+--------------------------------------+</div>Zeromushttps://www.nesdev.org/w/index.php?title=Talk:NES_2.0_submappers/Proposals&diff=14833Talk:NES 2.0 submappers/Proposals2015-09-02T03:27:16Z<p>Zeromus: </p>
<hr />
<div>== Bus conflict submapper 0 ==<br />
<br />
[http://wiki.nesdev.org/w/index.php?title=NES_2.0_submappers/Proposals&oldid=11603#002.2C_003.2C_007:_UxROM.2C_CNROM.2C_AxROM This revision] makes the following suggestion:<br />
:''0: Normal (The game is believed to never elicit a bus conflict. In the event of a bus conflict, the emulator should warn, abort, or produce random values; the exact behavior is not known)''<br />
<br />
I think the goal for submapper 0 should usually be the greatest compatibility, and backwards compatibility with iNES. Setting the NES 2.0 identifier shouldn't change the behaviour of submapper 0 (if all other fields are otherwise "equivalent"). Validation tools to "warn" or "abort" could work nicely with submapper 2 (i.e. emulate bus conflicts), but I don't think they would do anything except reduce compatibility if used for submapper 0. A validation tool really shouldn't be part of the submapper definition (that's its own tool with its own goal, e.g. like nintendulator DX's thing to warn on use of uninitialized memory).<br />
<br />
Cases 1 and 2 are good, it separates two things with specific conflicting needs. I think case 0 should just delegate a recommendation for 1 or 2.<br />
<br />
* 002:0 = 002:1 ? [[UxROM]] says that mapper 002 shares UxROM with compatible boards that require no bus conflicts. (Also, that DK pie factory hack?)<br />
* 003:0 = 003:2 ? [[INES Mapper 003]] lists 1 game (Cybernoid) that requires bus conflicts, and 1 (Colorful Dragon, UNL) that requires none. Does Cybernoid get priority?<br />
* 007:0 = 007:1 ? a lack of bus conflicts is required for some existing games, but it seems that none require bus conflicts.<br />
<br />
Alternatively I would just propose that submapper 0 be used for no bus conflicts, and submapper 1 be used for AND bus conflicts, since a lack of bus conflicts might just generally produce greater compatibility? If your goal is to give homebrewers a nice testing environment that will emulate bus conflicts for them, submapper 2 does that job great, it doesn't need to be the default. The only case I've seen listed so far is Cybernoid?<br />
<br />
I was wondering about other mappers besides 002/003/007 but I am guessing that the other bus-conflicting mappers don't have the ambiguity problems and can safely always have bus conflicts on?<br />
<br />
- [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:53, 31 August 2015 (MDT)<br />
<br />
: The default for any mapper that physically has bus conflicts (even if never elicited) must not be "no bus conflicts" for reasons we have already discussed and you find uncompelling. <br />
: FCEUX has already decided that the iNES1 handler is "produce bogus values (always 0) for CNROM and UNROM" (although it used to be AND) and "no bus conflicts for other data-bus latch mappers". Nestopia has codified bus conflicts as AND, for the "standard" version of specific discrete-logic mappers (UNROM, UOROM, CNROM, BNROM) and none otherwise.<br />
:—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 18:31, 31 August 2015 (MDT)<br />
<br />
:: I'm confused by this response? We're not discussing any mappers that always had bus conflicts here. We're discussing iNES mappers 2, 3, and 7, none of which unambiguously represents a physical mapper that had bus conflicts. Mapper 2 seems to include many obscure boards, some of which reputedly require a lack of bus conflicts? (I have no source for this other than statements found on the wiki; what are the actual compatibility cases?) Mapper 3 appears to be have the only compatibility conflict among these 3 mappers, and from the two cases listed a bus-conflicts submapper 0 seems valid to me. Mapper 7 submapper 0 requires no bus conflicts for compatibility. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 19:31, 31 August 2015 (MDT)<br />
<br />
::: Your central thesis appears to be that compatibility is the foremost goal, and my argument (from experience) is that prioritizing compatibility produces homebrew that can't run on hardware, so the default must be the strictest narrowest definition instead (and that people must explicitly opt into more lenient behavior). We've already had this argument. What's the point in having it again? —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 20:41, 31 August 2015 (MDT)<br />
<br />
:::: I'm not very much interested in restating opinions about ideological concerns for the format either, but I ''am'' interested in the specific definition of mappers 2, 3, and 7 here, in response to the submapper 0 text you just proposed. I strongly feel that mapper 7's submapper 0 should not break the existing ANROM games. Are you really arguing that it should? I don't remember you ever responding about mapper 7. We don't actually seem to have a dispute about mapper 3 (i.e. submapper 0 with bus conflicts), but I am unsure about it because I can't find much information about the non-CNROM games that use this mapper? Mapper 2 there is even less knowledge about, but the Disch notes for mapper 2 state ''"UxROM has bus conflicts, however mapper 002 is meant to be UxROM and compatible. So some mappers which were similar in function, but did not have bus conflicts are included"'', but again I can't find any existing research about the games/boards involved. Is the best we can do for this an emulator survey? - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:40, 1 September 2015 (MDT)<br />
<br />
Hi guys, just thought I'd mention some ideas here even though I don't have a lot of time for this kind of stuff and probably won't be back to debate it. IMO, ines 1 mapper numbers arent strict definitions but rather a vague guide for organizing a family of functionality. Moving forward, I would like to see 'submapper 0' for mapper N to be 'do what you can to get the game to boot' without increasing the strictness of the legacy mapper's definition. Then, exceptions can be written by forwarding to a submapper. For instance, we might see: "Mapper N Submapper 0 = Mapper N Legacy Mode: A game with this submapper can't be safely run without a game-specific logic. It might have bus conflicts (handle as Submapper 1) or no bus conflicts (handle as Submapper 2)." Essentially leave submapper 0 as flexible legacy hack zone ghetto. This allows us the latitude to actually prescribe as part of the specification how legacy garbage is to be interpreted as well as set a simple rule for how to define submapper 0. If there's a channel besides #nesdev I wouldnt mind lurking and giving further feedback, but I don't have time to take a strong stance [[User:Zeromus|Zeromus]] ([[User talk:Zeromus|talk]]) 21:25, 1 September 2015 (MDT)</div>Zeromushttps://www.nesdev.org/w/index.php?title=Talk:NES_2.0_submappers/Proposals&diff=14832Talk:NES 2.0 submappers/Proposals2015-09-02T03:25:50Z<p>Zeromus: </p>
<hr />
<div>== Bus conflict submapper 0 ==<br />
<br />
[http://wiki.nesdev.org/w/index.php?title=NES_2.0_submappers/Proposals&oldid=11603#002.2C_003.2C_007:_UxROM.2C_CNROM.2C_AxROM This revision] makes the following suggestion:<br />
:''0: Normal (The game is believed to never elicit a bus conflict. In the event of a bus conflict, the emulator should warn, abort, or produce random values; the exact behavior is not known)''<br />
<br />
I think the goal for submapper 0 should usually be the greatest compatibility, and backwards compatibility with iNES. Setting the NES 2.0 identifier shouldn't change the behaviour of submapper 0 (if all other fields are otherwise "equivalent"). Validation tools to "warn" or "abort" could work nicely with submapper 2 (i.e. emulate bus conflicts), but I don't think they would do anything except reduce compatibility if used for submapper 0. A validation tool really shouldn't be part of the submapper definition (that's its own tool with its own goal, e.g. like nintendulator DX's thing to warn on use of uninitialized memory).<br />
<br />
Cases 1 and 2 are good, it separates two things with specific conflicting needs. I think case 0 should just delegate a recommendation for 1 or 2.<br />
<br />
* 002:0 = 002:1 ? [[UxROM]] says that mapper 002 shares UxROM with compatible boards that require no bus conflicts. (Also, that DK pie factory hack?)<br />
* 003:0 = 003:2 ? [[INES Mapper 003]] lists 1 game (Cybernoid) that requires bus conflicts, and 1 (Colorful Dragon, UNL) that requires none. Does Cybernoid get priority?<br />
* 007:0 = 007:1 ? a lack of bus conflicts is required for some existing games, but it seems that none require bus conflicts.<br />
<br />
Alternatively I would just propose that submapper 0 be used for no bus conflicts, and submapper 1 be used for AND bus conflicts, since a lack of bus conflicts might just generally produce greater compatibility? If your goal is to give homebrewers a nice testing environment that will emulate bus conflicts for them, submapper 2 does that job great, it doesn't need to be the default. The only case I've seen listed so far is Cybernoid?<br />
<br />
I was wondering about other mappers besides 002/003/007 but I am guessing that the other bus-conflicting mappers don't have the ambiguity problems and can safely always have bus conflicts on?<br />
<br />
- [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:53, 31 August 2015 (MDT)<br />
<br />
: The default for any mapper that physically has bus conflicts (even if never elicited) must not be "no bus conflicts" for reasons we have already discussed and you find uncompelling. <br />
: FCEUX has already decided that the iNES1 handler is "produce bogus values (always 0) for CNROM and UNROM" (although it used to be AND) and "no bus conflicts for other data-bus latch mappers". Nestopia has codified bus conflicts as AND, for the "standard" version of specific discrete-logic mappers (UNROM, UOROM, CNROM, BNROM) and none otherwise.<br />
:—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 18:31, 31 August 2015 (MDT)<br />
<br />
:: I'm confused by this response? We're not discussing any mappers that always had bus conflicts here. We're discussing iNES mappers 2, 3, and 7, none of which unambiguously represents a physical mapper that had bus conflicts. Mapper 2 seems to include many obscure boards, some of which reputedly require a lack of bus conflicts? (I have no source for this other than statements found on the wiki; what are the actual compatibility cases?) Mapper 3 appears to be have the only compatibility conflict among these 3 mappers, and from the two cases listed a bus-conflicts submapper 0 seems valid to me. Mapper 7 submapper 0 requires no bus conflicts for compatibility. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 19:31, 31 August 2015 (MDT)<br />
<br />
::: Your central thesis appears to be that compatibility is the foremost goal, and my argument (from experience) is that prioritizing compatibility produces homebrew that can't run on hardware, so the default must be the strictest narrowest definition instead (and that people must explicitly opt into more lenient behavior). We've already had this argument. What's the point in having it again? —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 20:41, 31 August 2015 (MDT)<br />
<br />
:::: I'm not very much interested in restating opinions about ideological concerns for the format either, but I ''am'' interested in the specific definition of mappers 2, 3, and 7 here, in response to the submapper 0 text you just proposed. I strongly feel that mapper 7's submapper 0 should not break the existing ANROM games. Are you really arguing that it should? I don't remember you ever responding about mapper 7. We don't actually seem to have a dispute about mapper 3 (i.e. submapper 0 with bus conflicts), but I am unsure about it because I can't find much information about the non-CNROM games that use this mapper? Mapper 2 there is even less knowledge about, but the Disch notes for mapper 2 state ''"UxROM has bus conflicts, however mapper 002 is meant to be UxROM and compatible. So some mappers which were similar in function, but did not have bus conflicts are included"'', but again I can't find any existing research about the games/boards involved. Is the best we can do for this an emulator survey? - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:40, 1 September 2015 (MDT)<br />
<br />
Hi guys, just thought I'd mention some ideas here even though I don't have a lot of time for this kind of stuff and probably won't be back to debate it. IMO, ines 1 mapper numbers arent strict definitions but rather a vague guide for organizing a family of functionality. Moving forward, I would like to see 'submapper 0' for mapper N to be 'do what you can to get the game to boot' without increasing the strictness of the legacy mapper's definition. Then, exceptions can be written by forwarding to a submapper. For instance, we might see: "Mapper N Submapper 0 = Mapper N Legacy Mode: A game with this submapper can't be safely run without a game-specific logic. It might have bus conflicts (handle as Submapper 1) or no bus conflicts (handle as Submapper 2)." Essentially leave submapper 0 as flexible legacy hack zone ghetto. If there's a channel besides #nesdev I wouldnt mind lurking and giving further feedback, but I don't have time to take a strong stance [[User:Zeromus|Zeromus]] ([[User talk:Zeromus|talk]]) 21:25, 1 September 2015 (MDT)</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_030&diff=4095INES Mapper 0302014-04-09T05:50:29Z<p>Zeromus: fceux support m030</p>
<hr />
<div>mapper 30 is used to designate [[UNROM_512]]. <br />
<br />
The mapper supports up to 512 KB of PRG ROM and up to 32 KB of CHR RAM. <br />
<br />
The [[UNIF]] names for this board are UNROM-512-8, UNRROM-512-16 and UNROM-512-32, depending on how much CHR RAM is present.<br />
<br />
[[NES_2.0|NES 2.0]] is used for specifying how much CHR RAM the rom uses. Default behavior for a iNES headered rom is to enable 32 KB of CHR RAM.<br />
<br />
If the Battery flag is set, which indicates the mapper is flashable, then no bus conflicts should be emulated. On the other hand, bus conflicts should be emulated if the battery flag is cleared.<br />
<br />
Mapper controlled one-screen mirroring is only emulated if the Four-Screen mirroring flag is set, otherwise, it is hard-locked on either horizontal or vertical mirroring.<br />
<br />
mapper 30 is currently only using sub mapper 0. The other sub mappers are reserved for future use.<br />
<br />
Supported in FCEUX as of r3071</div>Zeromushttps://www.nesdev.org/w/index.php?title=Emulators&diff=2223Emulators2014-01-11T20:47:37Z<p>Zeromus: /* Under development */ - natt wasnt working on an FDS emulator, that was in reference to bizhawk</p>
<hr />
<div>This is a '''list of NES emulators'''.<br />
<br />
__TOC__<br />
<br />
== Commercial ==<br />
{| class="wikitable sortable"<br />
! Emulator name<br />
! Author<br />
! Platform(s)<br />
! Ports and/or other details<br />
|-<br />
| acNES<br />
| Nintendo<br />
| GameCube, Game Boy Advance<br />
| Used for Animal Crossing, e-Reader, and Classic NES Series<br />
|-<br />
| Virtual Console<br />
| Nintendo<br />
| Wii/3DS<br />
| Most games cost 500 Nintendo Points in Wii Shop Channel<br />
|-<br />
| PocketNES<br />
| Atlus, Jaleco, Konami<br />
| Game Boy Advance, Nintendo DS<br />
| source: [[wikipedia:PocketNES#Commercial_use|Wikipedia]]<br />
|}<br />
<br />
== Popular ==<br />
These are commonly used or well-established.<br />
<br />
{| class="wikitable sortable"<br />
! Emulator name<br />
! Author<br />
! Platform(s)<br />
! Ports and/or other details<br />
|-<br />
| [http://code.google.com/p/bizhawk/ BizHawk] || Multiple authors || Win32, MacOS<br />
|-<br />
| [http://wiibrew.org/wiki/FCE_Ultra_GX FCE Ultra GX] || Tantric || Wii, GameCube<br />
|-<br />
| [http://fceux.com/web/home.html FCEUX] || Anthony Giorgio / Mark Doliner || Win32, Linux<br />
|-<br />
| [http://www.the-interweb.com/serendipity/index.php?/categories/9-FCEUXD-SP FCEUXD SP] || sp || Win32<br />
|-<br />
| [http://jabosoft.com/?categoryid=1 Jnes] || Jabosoft || Win32<br />
|-<br />
| [http://www.nemulator.com nemulator] || James Slepicka || Win32 (Vista/7)<br />
|-<br />
| [http://www.nesemu2.com/ nesemu2] || holodnak || Win32, OS X, Linux || [https://github.com/holodnak/nesemu2 github source]<br />
|-<br />
| [http://tnse.zophar.net/NESten.htm NESten] || TNSe || Win32<br />
|-<br />
| [http://nestopia.sourceforge.net/ NEStopia] || Martin Freij || Win32 || [http://rbelmont.mameworld.info/?page_id=200 Linux], [http://www.bannister.org/software/nestopia.htm MacOS]<br />
|-<br />
| [https://github.com/rdanbrook/nestopia NEStopia] || rdanbrook || Win32 || a.k.a. Nestopia Undead Edition. Contains bugfixes/etc.<br />Win32 binaries are available [http://www.emucr.com/2013/07/nestopia-v145.html via EmuCR]<br />
|-<br />
| [http://www.qmtpro.com/~nes/nintendulator/ Nintendulator] || Quietust || Win32<br />
|-<br />
| [http://nocash.emubase.de/nes.htm NO$NES] || Martin Korth || Win32<br />
|-<br />
| [http://pocketnes.org/ PocketNES] || loopy, FluBBa, and Dwedit || Game Boy Advance || Updates on [http://www.dwedit.org/dwedit_board/viewtopic.php?id=409 Dwedit's board]<br />
|-<br />
| [http://rocknes.web.fc2.com RockNES] || Zepper || Win32<br />
|-<br />
| [http://www.ubernes.com/ UberNES] || M \ K Productions || Win32<br />
|-<br />
| [http://virtuanes.s1.xrea.com/ VirtuaNES] || Norix || Win32<br />
|}<br />
<br />
== Under development ==<br />
<br />
The following is a list of NES emulators that are supposedly under development, who their authors are, relevant home pages/sites, and the source of the announcement (direct or indirect).<br />
<br />
{{mbox<br />
| type = warning<br />
| text = '''Before considering developing your own NES emulator, ask yourself if your efforts may be better spent helping out those who already have emulators in development!'''<br />
}}<br />
<br />
{| class="wikitable sortable"<br />
! Emulator name<br />
! Author<br />
! Platform(s)<br />
! Ports and/or other details<br />
|-<br />
| [http://nesicide1.nesicide.com/ NESICIDE (version 1)] || NESICIDE || Win32<br />
|-<br />
| [http://nesicide2.nesicide.com/ NESICIDE (version 2)] || NESICIDE/essial || Win32/64, Linux32/64, MacOS<br />
|-<br />
| [http://fpganes.blogspot.se/ FPGA NES] || Ludde || FPGA (hardware)<br />
|-<br />
| [https://rm-rfroot.net/nes_fpga/ VeriNES] || jwdonal || FPGA (hardware) || [http://forums.nesdev.org/viewtopic.php?t=6157 Announcement]<br />
|-<br />
| [http://kevtris.org/Projects/console/sections/index.html FPGA NES] || kevtris || FPGA (hardware)<br />
|-<br />
| [http://danstrother.com/fpga-nes/ FPGA NES] || Dan Strother || FPGA (hardware)<br />
|-<br />
| [http://code.google.com/p/nesface/ NESFaCE] || 6T4 || Win32 || [http://forums.nesdev.org/viewtopic.php?t=7499 Announcement]<br />
|-<br />
| [http://www.crazysmart.net.au/kindred kindred] || Overload || Win32 || [http://forums.nesdev.org/viewtopic.php?f=3&t=10429 Announcement]<br />
|-<br />
| ? || allthatremains || Win32 || [http://forums.nesdev.org/viewtopic.php?t=5108 Announcement]<br />
|-<br />
| [http://www.aminlab.cn/app/nes/ ?] || amin2312 || Flash || [http://forums.nesdev.org/viewtopic.php?t=5678 Announcement]<br />
|-<br />
| ModNES || Petruza || Portable, mainly MacOS & Win32 || [http://forums.nesdev.org/viewtopic.php?t=6159 Announcement]<br />
|-<br />
| [http://www.anes.se/ A/NES] || Morgan Johansson || AmigaOS || [http://forums.nesdev.org/viewtopic.php?t=1279 Announcement]<br />
|-<br />
| puNES || FHorse || Linux32/64, Win32/64 || [http://forums.nesdev.org/viewtopic.php?t=6928 Announcement]<br />
|-<br />
| famique || sahib || Mac OS X, Win32, Linux || [http://forums.nesdev.org/viewtopic.php?t=5922 Announcement]<br />
|-<br />
| FooNES || aphex || Win32 || [http://forums.nesdev.org/viewtopic.php?p=75152#p75152 Announcement]<br />
|-<br />
| nesemu1 || Bisqwit || libSDL (portable), testing under Linux || [http://forums.nesdev.org/viewtopic.php?t=8385 Announcement]<br />
|-<br />
| [http://forums.nesdev.org/viewtopic.php?t=8400 MoarNES] || miker00lz || Win32 || [http://forums.nesdev.org/viewtopic.php?t=6972 Announcement]<br />
|-<br />
| jaNES || crudelios || Win32 || [http://forums.nesdev.org/viewtopic.php?p=89751 Announcement]<br />
|-<br />
| ? || neet || ? || [http://forums.nesdev.org/viewtopic.php?p=89437#p89437 Announcement]<br />
|-<br />
| ? || foobaz || Java || [http://forums.nesdev.org/viewtopic.php?t=8559 Announcement]<br />
|-<br />
| ? || MottZilla || ? || [http://forums.nesdev.org/viewtopic.php?t=8491 Announcement]<br />
|-<br />
| ? || runaway pancake || ? || [http://forums.nesdev.org/viewtopic.php?p=88478#p88478 Announcement]<br />
|-<br />
| ? || Vegenad || ? || [http://forums.nesdev.org/viewtopic.php?t=3593 Announcement]<br />
|-<br />
| ? || johnathonrh || ? || [http://forums.nesdev.org/viewtopic.php?t=5780 Announcement]<br />
|-<br />
| [http://yaneseland.com.ar/ Yanese] || Anes || Win32 || [http://forums.nesdev.org/viewtopic.php?p=713 Announcement]<br />
|-<br />
| ? || nesemuguy || ? || [http://forums.nesdev.org/viewtopic.php?t=2798 Announcement]<br />
|-<br />
| ? || Coldberg || ? || [http://forums.nesdev.org/viewtopic.php?t=4231 Announcement]<br />
|-<br />
| ? || pops || ? || [http://forums.nesdev.org/viewtopic.php?t=6260 Announcement]<br />
|-<br />
| ? || beannaich || ? || [http://forums.nesdev.org/viewtopic.php?t=6240 Announcement]<br />
|-<br />
| ? || windwakr || ? || [http://forums.nesdev.org/viewtopic.php?t=6294 Announcement]<br />
|-<br />
| ? || JuniorZ || ? || [http://forums.nesdev.org/viewtopic.php?t=896 Announcement]<br />
|-<br />
| ? || NesHackR || ? || [http://forums.nesdev.org/viewtopic.php?t=6102 Announcement]<br />
|-<br />
| ? || Snaer || ? || [http://forums.nesdev.org/viewtopic.php?t=6064 Announcement]<br />
|-<br />
| ? || BeTheDuck || ? || [http://forums.nesdev.org/viewtopic.php?t=5869 Announcement]<br />
|-<br />
| ? || Luke || ? || [http://forums.nesdev.org/viewtopic.php?t=5821 Announcement]<br />
|-<br />
| ? || The Lord || ? || [http://forums.nesdev.org/viewtopic.php?t=5795 Announcement]<br />
|-<br />
| ? || essial || ? || [http://forums.nesdev.org/viewtopic.php?t=5791 Announcement]<br />
|-<br />
| ? || JamesK89 || ? || [http://forums.nesdev.org/viewtopic.php?t=5787 Announcement]<br />
|-<br />
| ? || yaazz || OS X || [http://forums.nesdev.org/viewtopic.php?t=5723 Announcement]<br />
|-<br />
| ? || blanham || OS X || [http://forums.nesdev.org/viewtopic.php?t=5312 Announcement]<br />
|-<br />
| ? || magicphenix || ? || [http://forums.nesdev.org/viewtopic.php?t=5703 Announcement]<br />
|-<br />
| ? || happymaomao || ? || [http://forums.nesdev.org/viewtopic.php?t=5678 Announcement]<br />
|-<br />
| ? || someone_somewhere || ? || [http://forums.nesdev.org/viewtopic.php?t=5638 Announcement]<br />
|-<br />
| ? || Undubbed || ? || [http://forums.nesdev.org/viewtopic.php?t=5482 Announcement]<br />
|-<br />
| ? || Muchaserres || ? || [http://forums.nesdev.org/viewtopic.php?t=3665 Announcement]<br />
|-<br />
| ? || takeda || ? || [http://forums.nesdev.org/viewtopic.php?t=5530 Announcement]<br />
|-<br />
| ? || albailey || ? || [http://forums.nesdev.org/viewtopic.php?t=5512 Announcement]<br />
|-<br />
| ? || CaptainMuscles || ? || [http://forums.nesdev.org/viewtopic.php?t=5419 Announcement]<br />
|-<br />
| ? || hatorijr || ? || [http://forums.nesdev.org/viewtopic.php?t=5408 Announcement]<br />
|-<br />
| ? || tanoatnd || ? || [http://forums.nesdev.org/viewtopic.php?t=5189 Announcement]<br />
|-<br />
| ? || max_sweat || ? || [http://forums.nesdev.org/viewtopic.php?t=5388 Announcement]<br />
|-<br />
| ? || jjpeerless || ? || [http://forums.nesdev.org/viewtopic.php?t=5281 Announcement]<br />
|-<br />
| ? || Cloudy || ? || [http://forums.nesdev.org/viewtopic.php?t=5109 Announcement]<br />
|-<br />
| ? || meatloaf69 || ? || [http://forums.nesdev.org/viewtopic.php?p=62817#p62817 Announcement]<br />
|-<br />
| ? || parth || FPGA (hardware) || [http://forums.nesdev.org/viewtopic.php?t=4502 Announcement]<br />
|-<br />
| ? || oRBIT2002 || ? || [http://forums.nesdev.org/viewtopic.php?t=1279 Announcement]<br />
|-<br />
| ? || Elessar || ? || [http://forums.nesdev.org/viewtopic.php?t=7862 Announcement]<br />
|-<br />
| ? || cmoh89 || ? || [http://forums.nesdev.org/viewtopic.php?t=7521 Announcement]<br />
|-<br />
| [http://forums.nesdev.org/viewtopic.php?f=3&t=9935 HDNes] || mkwong98 || Win32 || [http://forums.nesdev.org/viewtopic.php?t=7848 Announcement]<br />
|-<br />
| ? || ehguacho || ? || [http://forums.nesdev.org/viewtopic.php?t=7936 Announcement]<br />
|-<br />
| ? || nop || Java || [http://forums.nesdev.org/viewtopic.php?t=8876 Announcement]<br />
|-<br />
| [https://github.com/Alegend45/MSE MSE] || Alegend45 || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=8853 Announcement]<br />
|-<br />
| ? || emu_enthusiast || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=5826 Announcement]<br />
|-<br />
| ? || HLorenzi || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=9054 Announcement]<br />
|-<br />
| ? || haydenmuhl || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=9101 Announcement]<br />
|-<br />
| ? || urbanspr1nter || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=9227 Announcement]<br />
|-<br />
| Fergulator || fergus_maximus || Mac OS X or X Windows || [http://forums.nesdev.org/viewtopic.php?f=3&t=9292 Announcement]<br />
|-<br />
| ? || ermular || Win32 || [http://forums.nesdev.org/viewtopic.php?f=3&t=9353 Announcement]<br />
|-<br />
| [http://www.kryptonware.com/ Kryptonware] || rubenhbaca || Java || [http://forums.nesdev.org/viewtopic.php?f=3&t=9395 Announcement]<br />
|-<br />
| ? || alexwy || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=9608 Announcement]<br />
|-<br />
| ? || caiiio || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=9625 Announcement]<br />
|-<br />
| ? || miguelsfp || Win32 || [http://forums.nesdev.org/viewtopic.php?f=3&t=9726 Announcement]<br />
|-<br />
| ? || ember || FPGA (hardware) || [http://forums.nesdev.org/viewtopic.php?f=3&t=9653 Announcement]<br />
|-<br />
| ? || ninjis || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=9829 Announcement]<br />
|-<br />
| [http://www.geocities.jp/submarine600/html/p8/nesemu.html ?] || submarine600 || PC-8801 || [http://forums.nesdev.org/viewtopic.php?f=3&t=9921 Announcement]<br />
|-<br />
| [http://alike.se/yane/ Yane] || roku6185 || libSDL (portable), testing under Linux || [http://forums.nesdev.org/viewtopic.php?f=3&t=9969 Announcement]<br />
|-<br />
| [http://vpnes.googlecode.com/ VPNES] || x0000 || Win32 || [http://forums.nesdev.org/viewtopic.php?f=3&t=9989 Announcement]<br />
|-<br />
| ? || proxy || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=10045 Announcement]<br />
|-<br />
| ? || samfoo || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=10070 Announcement]<br />
|-<br />
| ? || LightStruk || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=10071 Announcement]<br />
|-<br />
| [http://zelex.net/nezulator Nezulator] || Zelex || JavaScript || [http://forums.nesdev.org/viewtopic.php?f=3&t=7704 Announcement]<br />
|-<br />
| [http://www.oriku.com/emuya.html EMUya] || Zelex || Ouya || [http://forums.nesdev.org/viewtopic.php?f=3&t=10002 Announcement]<br />
|-<br />
| ? || dreampeppers99 || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=10130 Announcement]<br />
|-<br />
| ? || Skypher || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=10193 Announcement]<br />
|-<br />
<!--<br />
|-<br />
| ? || Dartht33bagger || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=10266 Announcement]<br />
|-<br />
--><br />
|-<br />
| [http://eigenbloom.com/projects/nes/nestest.php?version=1 ?] || graham || JavaScript || [http://forums.nesdev.org/viewtopic.php?f=3&t=10243 Announcement]<br />
|-<br />
| ? || ArsonIzer || Java || [http://forums.nesdev.org/viewtopic.php?f=3&t=10297 Announcement]<br />
|-<br />
| ? || SuperFXMaster || FPGA (hardware) || [http://forums.nesdev.org/viewtopic.php?f=10&t=10308 Announcement]<br />
|-<br />
| ? || Choz || Win32 w/ SDL || [http://forums.nesdev.org/viewtopic.php?f=3&t=10333 Announcement]<br />
|-<br />
| ? || sronsse || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=10348 Announcement]<br />
|-<br />
| ? || Emu6502Writer || ? || [http://forums.nesdev.org/viewtopic.php?p=116397#p116397 Announcement]<br />
|-<br />
| ? || fred || ? || [http://forums.nesdev.org/viewtopic.php?p=117245#p117245 Announcement]<br />
|-<br />
| ? || janzdott || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=10558 Announcement]<br />
|-<br />
| ? || d15ea5e || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=10569 Announcement]<br />
|-<br />
| ? || mrhyde || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=10751 Announcement]<br />
|-<br />
| ? || codeblox || ? || [http://forums.nesdev.org/viewtopic.php?f=3&t=10781 Announcement]<br />
|-<br />
| FC87 || Boolean || Win32 || [http://forums.nesdev.org/viewtopic.php?f=3&t=10839 Announcement]<br />
|-<br />
|}</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_029&diff=4091INES Mapper 0292013-11-17T00:35:45Z<p>Zeromus: </p>
<hr />
<div>This mapper was allocated on 15-nov-2013 by a mysterious jerkface to implement some homebrew games, including Glider. FCEUX acquired support on r3029.<br />
<br />
The example board in question was marked as follows: "Sealie Computing", "RET-CUFROM revD", "2/29/08"<br />
<br />
The board includes 4x banks worth of full 8KB CHR ram, and 8x 16KB PRG banks. <br />
<br />
It is hard-wired for vertical mirroring, and contains 8KB of WRAM mounted in the usual place. There is no battery, but pads are present and suitable for such a purpose if anyone were so inclined. There are no bus conflicts; presumably the other half of the 7420 in the [[PRG RAM circuit]] disables the chip's output on writes.<br />
<br />
The board contains logic designed for reprogramming from a CopyNES. If EXP0 and R/W go low, /WR reaches the flash ROM. When EXP0 is high, the internal bankswitching register gets accessed.<br />
<br />
Registers:<br />
---------------------------<br />
<br />
Range,Mask: $8000-FFFF, $8000<br />
<br />
$8000: [...P PPCC]<br />
C = CHR RAM bank<br />
P = PRG ROM bank<br />
<br />
PRG Setup:<br />
---------------------------<br />
$8000 $A000 $C000 $E000 <br />
+-------------------------------+<br />
| $8000 | { -1} |<br />
+---------------+---------------+<br />
<br />
CHR Setup:<br />
---------------------------<br />
$0000 $1000 <br />
+-------+-------+<br />
| $8000 |<br />
+-------+-------+<br />
<br />
Here's a schematic of the board:<br />
<br />
<pre><br />
377 O0 --- CRAM A13<br />
<br />
377 O1 --- CRAM A14<br />
____<br />
A14 ---------\ \<br />
) >--- ROM A14<br />
377 O2 ------/____/<br />
<br />
____<br />
A14 ---------\ \<br />
) >--- ROM A15<br />
377 O3 ------/____/<br />
<br />
____<br />
A14 ---------\ \<br />
) >--- ROM A16<br />
377 O4 ------/____/<br />
<br />
____<br />
EXP0 --------\ \<br />
) >--- ROM /WE<br />
R/W ---------/____/<br />
<br />
,--------------- 377 CLK<br />
|<br />
+--------------- ROM /CE<br />
| ____<br />
/ROMSEL --+--| \<br />
| )--,<br />
M2 ----------|____/ |<br />
,-----------'<br />
| ____<br />
`--| `-.<br />
| \<br />
A14 ---------| )o-- RAM /CE<br />
| /<br />
A13 ---------|____,-'<br />
<br />
____<br />
EXP0 --------| `-.<br />
| \<br />
+5V ---------| )o-- 377 /G<br />
| /<br />
,------|____,-'<br />
|<br />
`------------------,<br />
____ |<br />
+5V ------+--| `-. +-- RAM /OE<br />
| | \ |<br />
`--| )o-+-- ROM /OE<br />
| /<br />
R/W ------+--|____,-'<br />
|<br />
`--------------- RAM /WE<br />
</pre></div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_029&diff=4090INES Mapper 0292013-11-16T23:47:18Z<p>Zeromus: </p>
<hr />
<div>This mapper was allocated on 15-nov-2013 by a mysterious jerkface to implement some homebrew games, including Glider. FCEUX acquired support on r3029.<br />
<br />
The example board in question was marked as follows: "Sealie Computing", "RET-CUFROM revD", "2/29/08"<br />
<br />
The board includes 4x banks worth of full 8KB CHR ram, and 8x 16KB PRG banks. <br />
<br />
It is hard-wired for vertical mirroring, and contains 8KB of WRAM mounted in the usual place. There is no battery, but pads are present and suitable for such a purpose if anyone were so inclined. There are no bus conflicts; presumably the other half of the 7420 in the [[PRG RAM circuit]] disables the chip's output on writes.<br />
<br />
The board contains logic designed for reprogramming from a CopyNES. If EXP0 and R/W go low, /WR reaches the flash ROM. When EXP0 is high, the internal bankswitching register gets accessed.<br />
<br />
Registers:<br />
---------------------------<br />
<br />
Range,Mask: $8000-FFFF, $8000<br />
<br />
$8000: [...P PPCC]<br />
C = CHR RAM bank<br />
P = PRG ROM bank<br />
<br />
PRG Setup:<br />
---------------------------<br />
$8000 $A000 $C000 $E000 <br />
+-------------------------------+<br />
| $8000 | { -1} |<br />
+---------------+---------------+<br />
<br />
CHR Setup:<br />
---------------------------<br />
$0000 $1000 <br />
+-------+-------+<br />
| $8000 |<br />
+-------+-------+<br />
<br />
Here's a schematic of the board:<br />
<br />
<pre><br />
377 O0 --- CRAM A13<br />
<br />
377 O1 --- CRAM A14<br />
____<br />
A14 ---------\ \<br />
) >--- ROM A14<br />
377 O2 ------/____/<br />
<br />
____<br />
A14 ---------\ \<br />
) >--- ROM A15<br />
377 O4 ------/____/<br />
<br />
____<br />
A14 ---------\ \<br />
) >--- ROM A16<br />
377 O3 ------/____/<br />
<br />
____<br />
EXP0 --------\ \<br />
) >--- ROM /WE<br />
R/W ---------/____/<br />
<br />
,--------------- 377 CLK<br />
|<br />
+--------------- ROM /CE<br />
| ____<br />
/ROMSEL --+--| \<br />
| )--,<br />
M2 ----------|____/ |<br />
,-----------'<br />
| ____<br />
`--| `-.<br />
| \<br />
A14 ---------| )o-- RAM /CE<br />
| /<br />
A13 ---------|____,-'<br />
<br />
____<br />
EXP0 --------| `-.<br />
| \<br />
+5V ---------| )o-- 377 /G<br />
| /<br />
,------|____,-'<br />
|<br />
`------------------,<br />
____ |<br />
+5V ------+--| `-. +-- RAM /OE<br />
| | \ |<br />
`--| )o-+-- ROM /OE<br />
| /<br />
R/W ------+--|____,-'<br />
|<br />
`--------------- RAM /WE<br />
</pre></div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_029&diff=4088INES Mapper 0292013-11-16T20:43:40Z<p>Zeromus: </p>
<hr />
<div>This mapper was allocated on 15-nov-2013 by a mysterious jerkface to implement some homebrew games, including Glider. FCEUX acquired support on r3029.<br />
<br />
The example board in question was marked as follows: "Sealie Computing", "RET-CUFROM revD", "2/29/08"<br />
<br />
The board includes 4x banks worth of full 8KB CHR ram, and 8x 16KB PRG banks. <br />
<br />
It is hard-wired for vertical mirroring, and contains 8KB of WRAM mounted in the usual place. There is no battery, but pads are present and suitable for such a purpose if anyone were so inclined. There are no bus conflicts.<br />
<br />
The board contains logic designed for reprogramming from a CopyNES. If EXP0 and R/W go low, /WR reaches the flash ROM. When EXP0 is high, the internal bankswitching register gets accessed.<br />
<br />
Registers:<br />
---------------------------<br />
<br />
Range,Mask: $8000-FFFF, $8000<br />
<br />
$8000: [...P PPCC]<br />
C = CHR RAM bank<br />
P = PRG ROM bank<br />
<br />
PRG Setup:<br />
---------------------------<br />
$8000 $A000 $C000 $E000 <br />
+-------------------------------+<br />
| $8000 | { -1} |<br />
+---------------+---------------+<br />
<br />
CHR Setup:<br />
---------------------------<br />
$0000 $1000 <br />
+-------+-------+<br />
| $8000 |<br />
+-------+-------+</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_029&diff=4087INES Mapper 0292013-11-16T06:08:49Z<p>Zeromus: </p>
<hr />
<div>This mapper was allocated on 15-nov-2013 by a mysterious jerkface to implement some homebrew games, including Glider. FCEUX acquired support on r3029.<br />
<br />
The example board in question was marked as follows: "Sealie Computing", "RET-CUFROM revD", "2/29/08"<br />
<br />
The board includes 4x banks worth of full 8KB CHR ram, and 8x 16KB PRG banks. <br />
<br />
It is hard-wired for vertical mirroring, and contains 8KB of WRAM mounted in the usual place. There is no battery, but pads are present and suitable for such a purpose if anyone were so inclined.<br />
<br />
The board contains logic designed for reprogramming from a CopyNES. If EXP0 and R/W go low, /WR reaches the flash ROM. When EXP0 is high, the internal bankswitching register gets accessed.<br />
<br />
Registers:<br />
---------------------------<br />
<br />
Range,Mask: $8000-FFFF, $8000<br />
<br />
$8000: [...P PPCC]<br />
C = CHR RAM bank<br />
P = PRG ROM bank<br />
<br />
PRG Setup:<br />
---------------------------<br />
$8000 $A000 $C000 $E000 <br />
+-------------------------------+<br />
| $8000 | { -1} |<br />
+---------------+---------------+<br />
<br />
CHR Setup:<br />
---------------------------<br />
$0000 $1000 <br />
+-------+-------+<br />
| $8000 |<br />
+-------+-------+</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_029&diff=4086INES Mapper 0292013-11-16T05:52:07Z<p>Zeromus: </p>
<hr />
<div>This mapper was allocated on 15-nov-2013 by a mysterious jerkface to implement some homebrew games, including Glider. FCEUX acquired support on r3029.<br />
<br />
The example board in question was marked as follows: "Sealie Computing", "RET-CUFROM revD", "2/29/08"<br />
<br />
The board includes 4x banks worth of full 8KB CHR ram, and 8x 16KB PRG banks. <br />
<br />
It is hard-wired for vertical mirroring, and contains 8KB of WRAM mounted in the usual place. There is no battery, but pads are present and suitable for such a purpose if anyone were so inclined.<br />
<br />
The board contains some sketchy provisions for reprogramming the flash via the flash /WE being wired to EXPO<br />
<br />
Registers:<br />
---------------------------<br />
<br />
Range,Mask: $8000-FFFF, $8000<br />
<br />
$8000: [...P PPCC]<br />
C = CHR RAM bank<br />
P = PRG ROM bank<br />
<br />
PRG Setup:<br />
---------------------------<br />
$8000 $A000 $C000 $E000 <br />
+-------------------------------+<br />
| $8000 | { -1} |<br />
+---------------+---------------+<br />
<br />
CHR Setup:<br />
---------------------------<br />
$0000 $1000 <br />
+-------+-------+<br />
| $8000 |<br />
+-------+-------+</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_029&diff=4085INES Mapper 0292013-11-16T05:36:53Z<p>Zeromus: </p>
<hr />
<div>This mapper was allocated on 15-nov-2013 by a mysterious jerkface to implement some homebrew games, including Glider. FCEUX acquired support on r3029.<br />
<br />
The board includes 4x banks worth of full 8KB CHR ram, and 8x 16KB PRG banks. <br />
<br />
It is hard-wired for vertical mirroring, and contains 8KB of WRAM mounted in the usual place. There is no battery, but pads are present and suitable for such a purpose if anyone were so inclined.<br />
<br />
The board contains some sketchy provisions for reprogramming the flash via the flash /WE being wired to EXPO<br />
<br />
Registers:<br />
---------------------------<br />
<br />
Range,Mask: $8000-FFFF, $8000<br />
<br />
$8000: [...P PPCC]<br />
C = CHR RAM bank<br />
P = PRG ROM bank<br />
<br />
PRG Setup:<br />
---------------------------<br />
$8000 $A000 $C000 $E000 <br />
+-------------------------------+<br />
| $8000 | { -1} |<br />
+---------------+---------------+<br />
<br />
CHR Setup:<br />
---------------------------<br />
$0000 $1000 <br />
+-------+-------+<br />
| $8000 |<br />
+-------+-------+</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_029&diff=4084INES Mapper 0292013-11-16T05:10:22Z<p>Zeromus: add mapper029 docs</p>
<hr />
<div>This mapper was allocated on 15-nov-2013 by a mysterious jerkface to implement some homebrew games, including Glider. FCEUX acquired support on r3029.<br />
<br />
The board includes 4x banks worth of full 8KB CHR ram, and 8x 16KB PRG banks. <br />
<br />
It is hard-wired for vertical mirroring, and contains 8KB of WRAM mounted in the usual place, with no battery.<br />
<br />
The board contains some sketchy provisions for reprogramming the flash via the flash /WE being wired to EXPO<br />
<br />
Registers:<br />
---------------------------<br />
<br />
Range,Mask: $8000-FFFF, $8000<br />
<br />
$8000: [...P PPCC]<br />
C = CHR RAM bank<br />
P = PRG ROM bank<br />
<br />
PRG Setup:<br />
---------------------------<br />
$8000 $A000 $C000 $E000 <br />
+-------------------------------+<br />
| $8000 | { -1} |<br />
+---------------+---------------+<br />
<br />
CHR Setup:<br />
---------------------------<br />
$0000 $1000 <br />
+-------+-------+<br />
| $8000 |<br />
+-------+-------+</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_227&diff=5771INES Mapper 2272012-11-30T05:55:28Z<p>Zeromus: m227-little note on emulator support</p>
<hr />
<div>[[Category:iNES Mappers|227]][[Category:Multicart mappers|227]]<br />
The Chinese unlicensed game <i>[NJXXX] Xiang Shuai Chuan Qi</i> will fail to load pattern data if the below notes on write protection are employed. Is this feature only on some 227 carts (more likely multicarts)? The write protection has been temporarily disabled in fceux and bizhawk until more evidence is gathered. It should be noted that VirtuaNES doesn't use the write protection.<br />
<br />
In r2750 of fceux this support was rewritten; it should still work. It supposedly works in nestopia as well.<br />
<br />
Here are Disch's original notes: <br />
========================<br />
= Mapper 227 =<br />
========================<br />
<br />
<br />
Example Game:<br />
--------------------------<br />
1200-in-1<br />
<br />
<br />
Notes:<br />
---------------------------<br />
This mapper has 8k CHR-RAM, and also has the ability to write protect it's CHR-RAM!<br />
<br />
<br />
Registers:<br />
---------------------------<br />
<br />
$8000-FFFF: A~[.... ..LP OPPP PPMS]<br />
L = Last PRG Page Mode<br />
P = PRG Reg<br />
O = Mode<br />
M = Mirroring (0=Vert, 1=Horz)<br />
S = PRG Size<br />
<br />
<br />
Setup:<br />
---------------------------<br />
<br />
When 'O' is set, CHR-RAM is write protected (writes have no effect). 'O' also changes the PRG mode.<br />
<br />
Note there is funky ANDs and ORs going on below depending on the modes:<br />
<br />
<br />
$8000 $A000 $C000 $E000 <br />
+---------------+---------------+<br />
O=1, S=0: | P | P |<br />
+-------------------------------+<br />
O=1, S=1: | < P > |<br />
+-------------------------------+<br />
O=0, S=0, L=0: | P | P AND $38 |<br />
+---------------+---------------+<br />
O=0, S=1, L=0: | P AND $3E | P AND $38 |<br />
+---------------+---------------+<br />
O=0, S=0, L=1: | P | P OR $07 |<br />
+---------------+---------------+<br />
O=0, S=1, L=1: | P AND $3E | P OR $07 |<br />
+---------------+---------------+</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_027&diff=4049INES Mapper 0272012-11-26T22:15:12Z<p>Zeromus: m027 - seems to be mostly a dupe of m023 (vrc4) with tweaks used by some pirate/multicart/unlicensed VRC variants</p>
<hr />
<div>[[Category:iNES Mappers|027]]<br />
GoodNES thinks this is used for ''World Hero''.<br />
<br />
We should discover whether this mapper number is used for any other unlicensed/pirate/multicart VRC2/4 games.<br />
<br />
This is supported by BizHawk as of r3975 and FCEUX for some time prior but definitely as of 26-nov-2012.<br />
<br />
Formerly FCEUX emulated this with unique code, but as of r2722 cah4e3 asserts that it is a dupe for [[INES Mapper 023]]. However, FCEUX's VRC2/4 emulation is filled with hacks for pirate and multicart games which are otherwise similar to VRC2/4.<br />
<br />
In particular, ''World Hero'' is a VRC4-compatible but depends on the 9-bit CHR banking described below, where the most significant nibble of the CHR banks are actually 5 bits instead.<br />
<br />
The below notes are left until the author agrees they are describing VRC4.<br />
<br />
<pre><br />
Mask = F00F<br />
<br />
Writes:<br />
9002: ......x. = If bit 2 is set, next write to register 8000 affects PRG C000-BFFF instead of PRG 8000-AFFF<br />
8000: xxxxxxxx = Switches 8k PRG bank 8000-9FFF (or C000-DFFF)<br />
9000: ......xx = Select mirroring (0 = Vertical, 1 = Horizontal, 2 = Single screen 0, 3 = Single screen 1)<br />
A000: xxxxxxxx = Switches 8K PRG bank A000-BFFF<br />
B000-E003: CHR banks. They appear to have 9 bits. If address written to is even (least significant bit is zero), sets the low 4 bits of the value.<br />
If address is odd (least significant bit is one), sets the 5 high bits of the value.<br />
CHR Bank number affected = Top nibble of address - B, times 2, plus 1 if address & 2.<br />
(B000 = 4 low bits of bank 0, B001 = 5 high bits of bank 0, B002 = 4 low bits of bank 1, B003 = 5 high bits of bank 1, C000 = 4 low bits of bank 2, etc...)<br />
Selects the 1K CHR bank.<br />
F000: 4 low bits of IRQ latch<br />
F001: 4 high bits of IRQ latch<br />
F002: ......ER = 2 bit IRQ register, bit E = enable, bit R = enable on next acknowledgement (retrigger), then sets value of IRQ counter to IRQ latch - 1.<br />
F003: Writing here acknowledges the IRQ, and sets bit E (enable) to bit R (retrigger).<br />
<br />
IRQ behavior:<br />
IRQ counter is triggered by A12, just like MMC3, and happens once per scanline.<br />
If enabled, IRQ counter counts up to FF. If it would count up when the counter is at FF, it triggers an interrupt, then resets the IRQ counter to IRQ Latch + 1.<br />
If disabled, IRQ does not count at all.<br />
<br />
PRG E000-FFFF is probably fixed to the last bank.<br />
</pre></div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_074&diff=4509INES Mapper 0742012-11-26T21:13:36Z<p>Zeromus: m074 - add emulator compatibility notes</p>
<hr />
<div>[[Category:iNES Mappers|074]][[Category:MMC3 with CHR ROM and CHR RAM|074]]<br />
'''iNES Mapper 074''' is a [[MMC3]] clone used in Eastern games.<br />
It's identical to [[iNES Mapper 192]] and used for the same reason, except that only pages 8 and 9 are RAM.<br />
If the [[NES 2.0]] header is present, 74 and 192 should be emulated identically, as NES 2.0 specifies CHR RAM size elsewhere.<br />
<br />
BizHawk supports this mapper as of r3973; FCEUX and FCEU-MM have supported them for a long time but definitely as of 26-nov-2012, although CRC checks for m192<->m074 may be lacking.<br />
<br />
Some games will be mis-headered as m074 but should really be m192 and will either need to be changed to the correct mapper, or changed to the correct amount of CHR RAM and handled by unified code.<br />
<br />
Here are Disch's original notes:<br />
========================<br />
= Mapper 074 =<br />
========================<br />
<br />
<br />
aka:<br />
--------------------------<br />
Pirate MMC3 variant<br />
<br />
<br />
Example Games:<br />
--------------------------<br />
Di 4 Ci - Ji Qi Ren Dai Zhan<br />
Ji Jia Zhan Shi<br />
<br />
<br />
Notes:<br />
--------------------------<br />
This mapper is a modified MMC3 (or is based on MMC3?).<br />
<br />
In addition to any CHR-ROM present, there is also an additional 2k of CHR-RAM which is selectable. CHR pages<br />
$08 and $09 select CHR-RAM, other pages select CHR-ROM<br />
<br />
Apart from that, this mapper behaves exactly like your typical MMC3. See mapper 004 for details.</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_192&diff=5477INES Mapper 1922012-11-26T21:12:45Z<p>Zeromus: m192 - add emulator support notes</p>
<hr />
<div>[[Category:iNES Mappers|192]][[Category:MMC3 with CHR ROM and CHR RAM|192]]<br />
'''iNES Mapper 192''' is used to designate a board, used by Chinese developers, similar in capability to TQROM ([[iNES Mapper 119]]).<br />
It uses a clone of the [[MMC3]] but uses the CHR bank number in such a way so as to allow [[MMC3 with CHR ROM and CHR RAM|both CHR ROM and CHR RAM to be used simultaneously]] for displaying Chinese characters.<br />
<br />
BizHawk supports this mapper as of r3973; FCEUX and FCEU-MM have supported them for a long time but definitely as of 26-nov-2012, although CRC checks for m192<->m074 may be lacking.<br />
<br />
== Registers ==<br />
Registers resemble [[MMC3]], except CHR ROM banks 8, 9, 10, and 11 are replaced with CHR RAM.<br />
Other (unknown) inaccuracies compared to an authentic MMC3 may be present.<br />
This is effectively the same as [[INES Mapper 074]] but with twice as much CHR RAM.<br />
If the [[NES 2.0]] header is present, 74 and 192 should be emulated identically, as NES 2.0 specifies CHR RAM size elsewhere.<br />
<br />
<br />
Here are Disch's original notes: <br />
========================<br />
= Mapper 192 =<br />
========================<br />
<br />
<br />
aka:<br />
--------------------------<br />
Pirate MMC3 variant<br />
<br />
<br />
Example Game:<br />
--------------------------<br />
Ying Lie Qun Xia Zhuan<br />
<br />
<br />
Notes:<br />
--------------------------<br />
This mapper is a modified MMC3 (or is based on MMC3?).<br />
<br />
In addition to any CHR-ROM present, there is also an additional 4k of CHR-RAM which is selectable.<br />
<br />
CHR Pages $08-$0B are CHR-RAM, other pages are CHR-ROM.<br />
<br />
Apart from that, this mapper behaves exactly like your typical MMC3. See mapper 004 for details.</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_074&diff=4508INES Mapper 0742012-11-26T20:57:17Z<p>Zeromus: </p>
<hr />
<div>[[Category:iNES Mappers|074]][[Category:MMC3 with CHR ROM and CHR RAM|074]]<br />
'''iNES Mapper 074''' is a [[MMC3]] clone used in Eastern games.<br />
It's identical to [[iNES Mapper 192]] and used for the same reason, except that only pages 8 and 9 are RAM.<br />
If the [[NES 2.0]] header is present, 74 and 192 should be emulated identically, as NES 2.0 specifies CHR RAM size elsewhere.<br />
<br />
Some games will be mis-headered as m074 but should really be m192 and will either need to be changed to the correct mapper, or changed to the correct amount of CHR RAM and handled by unified code.<br />
<br />
Here are Disch's original notes:<br />
========================<br />
= Mapper 074 =<br />
========================<br />
<br />
<br />
aka:<br />
--------------------------<br />
Pirate MMC3 variant<br />
<br />
<br />
Example Games:<br />
--------------------------<br />
Di 4 Ci - Ji Qi Ren Dai Zhan<br />
Ji Jia Zhan Shi<br />
<br />
<br />
Notes:<br />
--------------------------<br />
This mapper is a modified MMC3 (or is based on MMC3?).<br />
<br />
In addition to any CHR-ROM present, there is also an additional 2k of CHR-RAM which is selectable. CHR pages<br />
$08 and $09 select CHR-RAM, other pages select CHR-ROM<br />
<br />
Apart from that, this mapper behaves exactly like your typical MMC3. See mapper 004 for details.</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_074&diff=4507INES Mapper 0742012-11-26T20:55:27Z<p>Zeromus: add notes to m074</p>
<hr />
<div>[[Category:iNES Mappers|074]][[Category:MMC3 with CHR ROM and CHR RAM|074]]<br />
'''iNES Mapper 074''' is a [[MMC3]] clone used in Eastern games.<br />
It's identical to [[iNES Mapper 192]] and used for the same reason, except that only pages 8 and 9 are RAM.<br />
If the [[NES 2.0]] header is present, 74 and 192 should be emulated identically, as NES 2.0 specifies CHR RAM size elsewhere.<br />
<br />
Some games will be mis-headered as m074 but should really be m192 and will either need to be changed to the correct mapper, or changed to the correct amount of CHR RAM and handled by unified code.<br />
<br />
We could consider deprecating one of these mappers and re-specifying it to support either CHR RAM size.<br />
<br />
Here are Disch's original notes:<br />
========================<br />
= Mapper 074 =<br />
========================<br />
<br />
<br />
aka:<br />
--------------------------<br />
Pirate MMC3 variant<br />
<br />
<br />
Example Games:<br />
--------------------------<br />
Di 4 Ci - Ji Qi Ren Dai Zhan<br />
Ji Jia Zhan Shi<br />
<br />
<br />
Notes:<br />
--------------------------<br />
This mapper is a modified MMC3 (or is based on MMC3?).<br />
<br />
In addition to any CHR-ROM present, there is also an additional 2k of CHR-RAM which is selectable. CHR pages<br />
$08 and $09 select CHR-RAM, other pages select CHR-ROM<br />
<br />
Apart from that, this mapper behaves exactly like your typical MMC3. See mapper 004 for details.</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_028&diff=4058INES Mapper 0282012-11-07T21:28:21Z<p>Zeromus: add mapper 028 implementation status notes</p>
<hr />
<div>'''iNES Mapper 028''' has been proposed as the assignment for a a [[User:Tepples/Multi-discrete mapper|multicart mapper in development]] by Tepples and Infiniteneslives in October 2012, as an extension of the [[Action 53]] project to cover [[CNROM]] and [[UNROM]] games.<br />
<br />
Implemented in FCEUX as of r2739; implemented in Bizhawk as of r3680.<br />
<br />
== References ==<br />
*[http://forums.nesdev.org/viewtopic.php?p=101111#p101111 Forum post announcing reservation of #28]<br />
*[http://forums.nesdev.org/viewtopic.php?p=101970#p101970 Forum post announcing implementation in NESICIDE]</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_101&diff=4792INES Mapper 1012012-10-10T18:26:36Z<p>Zeromus: m101-mention some emulator support levels</p>
<hr />
<div>This mapper is used for instance by Urusei Yatsura - Lum no Wedding Bell.<br />
<br />
Supported in r3420 BizHawk, r2696 FCEUX (probably has been supported for eons), and reportedly MESS.<br />
<br />
Registers:<br />
---------------------------<br />
$6000-7FFF: [CCCC CCCC]<br />
C = Selects 8k CHR @ $0000<br />
<br />
It's unknown how many bits C is but it probably isn't 8.</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_101&diff=4791INES Mapper 1012012-10-10T18:18:06Z<p>Zeromus: add nes mapper 101</p>
<hr />
<div>This mapper is used for instance by Urusei Yatsura - Lum no Wedding Bell.<br />
<br />
Registers:<br />
---------------------------<br />
$6000-7FFF: [CCCC CCCC]<br />
C = Selects 8k CHR @ $0000<br />
<br />
It's unknown how many bits C is but it probably isn't 8.</div>Zeromushttps://www.nesdev.org/w/index.php?title=Family_Computer_Disk_System&diff=2935Family Computer Disk System2012-09-11T23:09:59Z<p>Zeromus: fds: change a 65550->65500</p>
<hr />
<div>The '''Famicom Disk System''' was a Japan-exclusive storage device for the Famicom, designed to reduce Nintendo's cost of making copies of games by switching from mask [[ROM]] chips to a storage medium based on Mitsumi's Quick Disk.<br />
Unfortunately for Nintendo, it also reduced the pirates' cost of making copies of games.<br />
<br />
== .FDS format ==<br />
'''fwNES''' was an [[NES emulator]] developed by Fan Wan Yang. Its most lasting contribution to the NES scene was its disk image file format, an image of the Quick Disk media.<br />
<br />
The FDS format (file name suffix <code>.fds</code>) is a way to store Famicom Disk System disk data. It consists of the following sections, in order:<br />
# Header (16 bytes)<br />
# Disk data (65500 * ''x'' bytes)<br />
<br />
The format of the header is as follows:<br />
* 0-3: Constant $46 $44 $53 $1A ("FDS" followed by MS-DOS end-of-file)<br />
* 4: Number of disk sides<br />
* 5-15: Zero filled<br />
<br />
Note: Most games are an even number of sides. Ports from NROM were one side. No commercial FDS game had an odd number of sides greater than 1.<br />
Disk sides comes in the following order :<br />
* Disc 1 Side A<br />
* Disc 1 Side B<br />
* Disc 2 Side A<br />
* Disc 2 Side B<br />
* etc...<br />
<br />
== Overview ==<br />
* PRG ROM : 8 KB BIOS at $E000-$FFFF<br />
* PRG RAM: 32 KB at $6000-$DFFF<br />
* CHR capacity: 8 KB RAM<br />
* Storage capacity : ~64 KB per disk side<br />
* Nametable [[mirroring]]: Controlled by mapper<br />
* Subject to [[bus conflict]]s: No<br />
Games are stored on one or multiple disk sides. The FDS BIOS is used to load data from disks to PRG RAM or VRAM, and games can execute from there.<br />
<br />
== Hardware ==<br />
<br />
The Famicom disk system comes in two parts : The disk drive and the RAM adapter.<br />
<br />
The RAM adapter is a special shaped cartridge that contains the RAM chips, IRQ hardware, sound generation hardware, a serial interface for the disk drive and another (rarely used) serial port.<br />
<br />
The Disk Drive has to be powered separately and is only connected to the Famicom/NES through the serial cable to the RAM adapter.<br />
<br />
Most disk drives contains two motors: a rotation motor that spins the disk at a constant rate, and a tracking motor. However, the FDS only contains a single motor that does both at once. There is some mechanism that detects when the head reaches the end of the disc and make it return to the start, which makes a click sound.<br />
<br />
Because of this limitation, random access to the disc is not possible, you can only spin the disc and wait until you detect the head is at the start of the disc, then wait until it reaches the desired access place. A complete cycle through the entire disc takes about 7 seconds.<br />
<br />
The disc drives only contains basic electronics, there is no "intelligence" in it; therefore, the serial interface almost directly represents what is stored on the disc.<br />
<br />
== FDS Disk Side format ==<br />
<br />
Each disk side must be structured into block as follows :<br />
<br />
1, 2, 3, 4, 3, 4, ...., 3, 4<br />
<br />
The 3, 4 pattern should be repeated once per file present on the disk.<br />
<br />
From the last file, fill the side with all 0 so that the side has exactly 65500 is reached.<br />
<br />
== Data not stored in the FDS image ==<br />
<br />
In addition to data stored in the FDS image, there is other data stored on the disc, but removed when the disc is dumped because such data wasn't meaningful for emulation.<br />
<br />
=== Gaps ===<br />
<br />
Physically on the disc, there are "gaps" of 0 recorded between blocks and before the start of the disc.<br />
Length of the gaps are as follows:<br />
* Before the start of the disc : At least 26150 bits, 28300 typical.<br />
* Gap between blocks : At least 480 bits, 976 bits typical.<br />
<br />
Gaps are teminated by a single '1' bit. In terms of bytes, it would be $80, as the data is stored in little endian format.<br />
<br />
=== CRCs ===<br />
<br />
At the end of each block, a 16-bit CRC is stored. On loading, the CRC is *not* calculated by the 6502 in the BIOS, but by the RAM adapter, which monitors disc transfers and calculates the CRC. It will automatically send an error code if both CRCs doesn't match.<br />
<br />
=== True disc capacity ===<br />
<br />
Even if the FDS disc side image is always 65500 bytes, one WILL have to subtract all the bits taken by the gaps and CRCs to find the actual disc capacity. In this regard, the way the FDS image is made is not smart because all the bits that were saved by not dumping useless data should be wasted in zeroes at the end of the disc side. In addition to this, the programmer should be very careful for not using the whole disc side in FDS format, otherwise, the data might not fit the disc.<br />
<br />
The actual disc capacity in bytes is (N = number of files):<br />
<br />
65500 - 28300/8 - (2*N + 1)*(16 + 976)/8<br />
<br />
For example, if you use 8 files, there's room for only 59854 bytes instead of the supposed 65500.<br />
<br />
== Block format ==<br />
<br />
=== Disk info block (block 1) ===<br />
<br />
SIZE CONTENTS<br />
1 $01<br />
14 FC disk String *NINTENDO-HVC*<br />
1 Manufacturer code <br />
Same code as used in GameBoy(?)<br />
4 Game name code<br />
1 Game version number (starts with $00, increases in each revision)<br />
1 Side number <br />
$00: Side-A <br />
$01: Side-B<br />
1 Disk number (first disk is actually $00)<br />
1 Extra disk data #1 (indicates disk # ?, usually $00)<br />
1 Extra disk data #2 (indicates disk # ?, usually $00)<br />
1 Boot read file code<br />
5 Unknown<br />
3 Manufacturer permit date<br />
Recorded in BCD, in the year of "showa"(+1925)<br />
For example, 21 march 2010 becomes $85, $03, $21 (because 2010-1925 = 85)<br />
10 Unknown<br />
3 Created date <br />
Recorded in BCD, in the year of "showa"(+1925)<br />
9 Unknown<br />
<br />
The '''*NINTENDO-HVC*''', stored in ASCI standard strings proves that this is a FDS disk. If the string doesn't match, the BIOS will refuse to read the disk further.<br />
If the FDS is started with a disk whose side number and disk number aren't both $00, it will be prompted to insert the first disk side. However, some games make this number $00, even for the second disk to make it bootable too.<br />
<br />
All files with IDs smaller or equals to the ''boot read file code'' will be loaded when the game is booting.<br />
<br />
The FDS also has a trademark security system similar to what Sega used on some of its consoles.[http://segaretro.org/TradeMark_Security_System]<br />
The 224-byte text at PPU $2800-$28DF must match the data in the BIOS, starting at $ED37.<br />
This data roughly translates into "produced by or under license from Nintendo" in the SMB1/Zelda character encoding.<br />
Traditionally, the first file on a disk is a nametable type file loaded into $2800, which is named <code>KYODAKU-</code> (きょだく or [[wiktionary:許|許]][[wiktionary:諾|諾]] means approval).<br />
<br />
=== File amount block (block 2) ===<br />
<br />
This block contains the total number of files recorded on disk.<br />
<br />
SIZE CONTENTS<br />
1 $02<br />
1 File Amount<br />
<br />
More files might exist on the disk, but the BIOS load routine will ignore them, those files are called "hidden" files.<br />
Some games have a simple copy protection this way : They have their own loading routine similar to the one from the BIOS but hard-code the file amount to a higher number, which will allow for loading hidden files. This also allows the game to load faster because the BIOS will stop reading the disc after the last non-hidden file.<br />
<br />
=== File header block (block 3) ===<br />
<br />
SIZE CONTENTS<br />
1 $03<br />
1 File Number <br />
1 File Indicate Code (file identification code) <br />
ID specified at disk-read function call<br />
8 File Name<br />
2 File Address (16-bit little endian)<br />
the destination address when loading<br />
2 File Size (16-bit little endian)<br />
1 Kind of File <br />
0:Program (PRAM) <br />
1:Character (CRAM) <br />
2:Name table (VRAM)<br />
<br />
The file Number must go in increasing order, first file is 0.<br />
File IDs can be freely assigned, and this is the number which will decide which file is loaded from the disk (instead of the file number). An ID smaller than the boot number means the file is a boot file, and will be loaded on first start up.<br />
<br />
File names are uppercase ASCII.<br />
<br />
=== File data block (block 4) ===<br />
<br />
SIZE CONTENTS<br />
1 $04<br />
-- disk data<br />
<br />
== Registers ==<br />
<br />
$402x registers are write-only<br />
$403x registers are read-only<br />
<br />
<br />
=== IRQ timer low ($4020) ===<br />
<br />
7 bit 0<br />
---------<br />
LLLL LLLL<br />
|||| ||||<br />
++++-++++- 8 LSB of IRQ timer<br />
<br />
=== IRQ timer high ($4021) ===<br />
<br />
7 bit 0<br />
---------<br />
LLLL LLLL<br />
|||| ||||<br />
++++-++++- 8 MSB of IRQ timer<br />
<br />
=== IRQ timer enable ($4022) ===<br />
<br />
7 bit 0<br />
---------<br />
xxxx xxEx<br />
|<br />
+-- Enable IRQ timer<br />
<br />
Each CPU clock cycle the timer is decremented by one if the enable flag is set.<br />
When the counter reach 0, an IRQ is generated. Read $4030 to acknowledge the IRQ.<br />
<br />
Note : Since the disk transfer routine also uses IRQs, it's very important to disable timer IRQs before doing any access to the disk.<br />
<br />
=== Master I/O enable ($4023) ===<br />
<br />
7 bit 0<br />
---------<br />
xxxx xxSD<br />
||<br />
|+- Enable disk I/O registers<br />
+-- Enable sound I/O registers<br />
<br />
This register sounds obscure. FDS bios just writes $00 then $83 to it.<br />
<br />
=== Write data register ($4024) ===<br />
<br />
The data that this register is programmed with will be the next 8-bit quantity to load into the shift register (next time the byte transfer flag raises), and to be shifted out and appear on pin 5 of the RAM adapter cable (2C33 pin 52).<br />
<br />
=== FDS Control ($4025) ===<br />
7 bit 0<br />
---------<br />
IS1B MRTD<br />
|||| ||||<br />
|||| |||+- Drive Motor Control <br />
|||| ||| 0: Stop motor<br />
|||| ||| 1: Turn on motor<br />
|||| ||+-- Transfer Reset<br />
|||| || Set 1 to reset transfer timing to the initial state.<br />
|||| |+--- Read / Write mode<br />
|||| | (0: write; 1: read)<br />
|||| +---- Mirroring (0: horizontal; 1: vertical)<br />
|||+------ CRC control (set during CRC calculation of transfer)<br />
||+------- Always set to '1'<br />
|+-------- Read/Write Start <br />
| Turn on motor. Set to 1 when the drive becomes ready for read/write<br />
+--------- Interrupt Transfer <br />
0: Transfer without using IRQ<br />
1: Enable IRQ when the drive becomes ready for <br />
<br />
A FDS game that wants to change mirroring probably don't want to touch motor related bits, so it should do a read-modify-write from the pseudo registers (see below).<br />
<br />
=== External connector ($4026) ===<br />
<br />
Output of expansion terminal where there's a shutter on the back of the ram card. The outputs of $4026 (open-collector with 4.7K ohm pull-ups (except on bit 7)), are shared with the inputs on $4033.<br />
<br />
=== Disk Status Register 0 ($4030) ===<br />
7 bit 0<br />
---------<br />
IExB xxTD<br />
|||| ||<br />
|||| |+- Timer Interrupt (1: an IRQ occurred)<br />
|||| +-- Byte transfer flag. Set every time 8 bits have been transfered between the RAM adaptor & disk drive (service $4024/$4031). <br />
|||| Reset when $4024, $4031, or $4030 has been serviced.<br />
|||+------ CRC control (0: CRC passed; 1: CRC error)<br />
|+-------- End of Head (1 when disk head is on the most inner track)<br />
+--------- Disk Data Read/Write Enable (1 when disk is readable/writable)<br />
<br />
=== Read data register ($4031) ===<br />
<br />
This register is loaded with the contents of an internal shift register every time the byte transfer flag raises. The shift register receives it's serial data via pin 9 of the RAM adapter cable (2C33 pin 51).<br />
<br />
=== Disk drive status register ($4032) ===<br />
7 bit 0<br />
---------<br />
xxxx xPRS<br />
|||<br />
||+- Disk flag (0: Disk inserted; 1: Disk not inserted)<br />
|+-- Ready flag (0: Disk read; 1: Disk not ready)<br />
+--- Protect flag (0: Not write protected; 1: Write protected or disk ejected)<br />
<br />
=== External connector read ($4033) ===<br />
7 bit 0<br />
---------<br />
BIII IIII<br />
|||| ||||<br />
|+++-++++- Input from expansion terminal where there's a shutter on the back of the ram card.<br />
+--------- Battery status (0: Good; 1: Voltage is low).<br />
<br />
When a bit is clear in $4026 port it will read back as '0' here (including battery bit) because of how open collector input works.<br />
<br />
=== Sound ($4040-$4089) ===<br />
<br />
For details on sound information, see [[FDS_audio|FDS audio]].<br />
<br />
== Pseudo-registers ==<br />
Those registers are used by the FDS bios and FDS programs. They are used to overcome the problem that NES/FDS registers are write only, so it is effectively possible to modify only one bit of them without affecting other bits.<br />
<br />
[$FF]: value last written to [[PPU_registers#Controller_.28.242000.29_.3E_write|$2000]] $80 on reset.<br />
[$FE]: value last written to [[PPU_registers#Mask_.28.242001.29_.3E_write|$2001]] $06 on reset<br />
[$FD]: value last written to [[PPU_registers#Scroll_.28.242005.29_.3E.3E_write_x2|$2005]]#1 0'd on reset.<br />
[$FC]: value last written to [[PPU_registers#Scroll_.28.242005.29_.3E.3E_write_x2|$2005]]#2 0'd on reset.<br />
[$FB]: value last written to [[Controller_port_registers|$4016]] 0'd on reset.<br />
[$FA]: value last written to $4025 $2E on reset.<br />
[$F9]: value last written to $4026 $FF on reset.<br />
$F5..$F8 : Used by controller read routines<br />
$00..$0F is used as temporary memory for the BIOS. The main program can use it as temporary memory too.<br />
<br />
Those values are used by the BIOS to determine action on interrupt.<br />
($0102): PC action on reset<br />
[$0101]: PC action on IRQ. set to $80 on reset<br />
[$0100]: PC action on NMI. set to $C0 on reset<br />
($DFFE): disk game IRQ vector (if [$0101] = 11xxxxxxB)<br />
($DFFC): disk game reset vector (if ($0102) = $5335, or $AC35)<br />
($DFFA): disk game NMI vector #3 (if [$0100] = 11xxxxxxB)<br />
($DFF8): disk game NMI vector #2 (if [$0100] = 10xxxxxxB)<br />
($DFF6): disk game NMI vector #1 (if [$0100] = 01xxxxxxB)<br />
<br />
A few important notes :<br />
* After loading the boot files, $102 is set to $35 so that the ($DFFC) vector is used and the BIOS is skipped.<br />
* $103 indicate reset type : $AC = first boot of the game, $53 = the game was soft-reseted by the user<br />
* To use your own IRQ routine, you must manually write $c0 to $101<br />
* There is 3 possible NMI vectors, #3 is used by default.<br />
* On first start, the mirroring is set to horizontal, the stack pointer is $ff, and the I flag is ''clear''. System RAM is filled with values used by the BIOS, and PRG RAM is uninitialized, except for parts of it which has files loaded in.<br />
<br />
== BIOS calls ==<br />
<br />
=== Disk access routines ===<br />
<br />
* Routines takes one or two pointers as arguments. Those are placed directly after the JSR instruction: the subroutines uses the return address in stack to fetch the pointers and fix the return address.<br />
* Memory at $00-$0f will be affected by those routines<br />
* Unlike the vast majority of disk drives, the FDS lacks any kind of intelligent tracking system. All BIOS load and save functions will do access to the whole disk, no matter which data they load/save. A simple way to overcome this problem is to have your own loading routine, similar to the BIOS one but forcing the # of files to a smaller number than it actually is. That way the later files are not accessed at all and the earlier files load faster. Of course the maximal time is still taken when you have to load the files that are late on the disk.<br />
* All non-disk IRQ sources (timer, DMC and APU frame) should be properly disabled before calling any of these routines. The value at [$0101] however, is preserved on entry, and restored on exit.<br />
* On return of those routines, A = $00 means no error occurred, other number is error #. Main program should test if an error occurred with the BEQ or BNE instruction, BEQ will branch if no error, and BNE will branch if there is an error.<br />
* The structures defined below are used to identify files & disks in the access routines. The argument pointers should point to these structures in the program.<br />
<br />
{| border="1" cellspacing="0" cellpadding="3"<br />
| Adress || Name || Input parameters || Output parameters || Description<br />
|-<br />
| $e1f8 || LoadFiles || Pointer to Disk ID, Pointer to File List || A = error #, Y = # of files loaded || Loads files specified by DiskID into memory from disk. Load <br />
addresses are decided by the file's header.<br />
|-<br />
| $e237 || AppendFile || Pointer to Disk ID, Pointer to File Header || A = error # || Appends the file data given by DiskID to the disk. This means <br />
that the file is tacked onto the end of the disk, and the disk file count is incremented. The file is then read back to verify the write. If an error occurs during verification, the disk's file count is decremented (logically hiding the written file).<br />
|-<br />
| $e239 || WriteFile || Pointer to Disk ID, Pointer to File Header, A = file # || A = error # || Same as "Append File", but instead of writing the file to the end of the disk, A specifies the sequential position on the disk to write the file (0 is the first). This also has the effect of setting the disk's file count to the A value, therefore logically hiding any other files that may reside after the written one.<br />
|-<br />
| $e2b7 || CheckFileCount || Pointer to Disk ID, A = # to set file count to || A = error # || Reads in disk's file count, compares it to A, then sets the disk's file count to A.<br />
|-<br />
| $e2bb || AdjustFileCount || Pointer to Disk ID, A = number to reduce current file count by || A = error # || Reads in disk's file count, decrements it by A, then writes the new value back.<br />
|-<br />
| $e301 || SetFileCount1 || Pointer to Disk ID, A = file count minus one = # of the last file || A = error # || Set the file count to A + 1<br />
|-<br />
| $e305 || SetFileCount || Pointer to Disk ID, A = file count || A = error # || Set the file count to A<br />
|-<br />
| $e32a || GetDiskInfo || Pointer to Disk Info || A = error # || Fills DiskInfo up with data read off the current disk.<br />
|-<br />
|}<br />
<br />
=== Exemple code how to load files ===<br />
<br />
Load<br />
jsr LoadFiles<br />
.dw DiskID<br />
.dw LoadList<br />
bne _Error ;Check if there is an error<br />
rts<br />
_Error<br />
jsr PrintError ;If so print the error number and message to screen (include side/disk changing prompts)<br />
_sideError<br />
lda $4032<br />
and #$01<br />
beq _sideError ;Wait until disk is ejected<br />
_insert<br />
lda $4032<br />
and #$01<br />
bne _instert ;Wait until disk is inserted<br />
jmp Load<br />
<br />
DiskID<br />
.db $01 ;Manufacturer code<br />
.db "NAME" ;4-letter code of game<br />
.db $00 ;Version<br />
.db $01 ;Disk side<br />
.db $00 ;Disk number<br />
.db $00, $00 ;Extra disk IDs<br />
<br />
LoadList ;In this example the files with IDs equal to $02, $03 or $04 will be loaded into memory<br />
.db $02, $03, $04, $ff<br />
<br />
=== Error list ===<br />
<br />
Message in bold is the official BIOS message (if there is one) followed by an explanation<br />
*$00: no error<br />
*$01: '''disk set''', ($4032.0) disk not set<br />
*$02: '''battery''', ($4033.7) power supply failure<br />
*$03: ($4032.2) disk is write protected<br />
*$04: Wrong maker ID<br />
*$05: Wrong game<br />
*$06: Wrong game version<br />
*$07: '''a,b side''', wrong side number<br />
*$08: '''disk no.''', wrong disk number<br />
*$09: wrong additional disk ID 1<br />
*$0a: wrong additional disk ID 2<br />
*$20: '''disk trouble''', approval check failed<br />
*$21: '''disk trouble''', '*NINTENDO-HVC*' string in block 1 doesn't match<br />
*$22: '''disk trouble''', block type 1 expected<br />
*$23: '''disk trouble''', block type 2 expected<br />
*$24: '''disk trouble''', block type 3 expected<br />
*$25: '''disk trouble''', block type 4 expected<br />
*$27: '''disk trouble''', ($4030.4) block failed CRC<br />
*$28: '''disk trouble''', ($4030.6) file ends prematurely during read<br />
*$29: '''disk trouble''', ($4030.6) file ends prematurely during write<br />
*$30: '''disk trouble''', ($4032.1) disk is full<br />
<br />
=== Disk ID structure ===<br />
<br />
This is a commonly used string. It consists of 10 bytes which are all compared directly against bytes 15..24 (right after the '*NINTENDO-HVC*' string) of the disk's header block (block type 1; always the first one on the disk). If any of the bytes fail the comparison, an appropriate error # is generated. Comparisons of immaterial data can be skipped by placing an $FF byte in the appropriate place in the DiskID string (for example, when the ROM BIOS boots a disk, it sets all the fields in the DiskID string to -1, except disk side #, and disk #, which are set to 0 (so these fields have to match 0)). The following chart describes the DiskID structure, and the error #'s returned when a comparison fails.<br />
<br />
offset size error# description<br />
------ ---- ------ -----------<br />
0 1 $04 game manufacturer code<br />
1 4 $05 game ASCII name string<br />
5 1 $06 game version<br />
6 1 $07 disk side #<br />
7 1 $08 disk #<br />
8 1 $09 extra disk # data<br />
9 1 $10 extra disk # data<br />
A -<br />
<br />
=== File list structure ===<br />
<br />
This is a list of 1-byte IDs of files to load. All files that matches any ID in the list are loaded. A list of up to 20 IDs is possible at a time, smaller lists should be terminated by a $ff byte (this implies a file ID can never be $ff).<br />
<br />
Multiple files are loaded in the order as they exist on the disk, not in the order of the list.<br />
<br />
=== File header structure ===<br />
<br />
This structure is specified when a file is to be written to the disk. The first 14 bytes of this structure directly specify the data to use for generating a file header block (type 3, bytes [2..15]) to write to disk. The last 2 entries concern the file data to be written to disk (block type 4). The following is a table describing the FileHeader structure.<br />
<br />
offset size description<br />
------ ---- -----------<br />
00 1 file ID code<br />
01 8 file name<br />
09 2 load address<br />
0B 2 file data size<br />
0D 1 file type ($00 : Program; $01 : Character; $02 : Nametable)<br />
0E 2 source address of file data (NOT written to disk)<br />
10 1 source address type ($00 : RAM, $01 : VRAM)<br />
11 -<br />
<br />
=== Disk information structure ===<br />
<br />
This is a data structure returned by a subroutine, of collected information <br />
from the disk (list of files on disk, disk size, etc.). The following table <br />
is a description of that structure.<br />
<br />
offset size<br />
------ ----<br />
0 1 game manufacturer code<br />
1 4 game ASCII name string<br />
5 1 game version<br />
6 1 disk side #<br />
7 1 disk #<br />
8 1 extra disk # data<br />
9 1 extra disk # data<br />
A 1 # of files on disk<br />
<br />
(the following block will appear for as many files as the "# of files on <br />
disk" byte indicates)<br />
<br />
B 1 file ID code<br />
C 8 file name (ASCII)<br />
<br />
(the following is present after the last file info block. Disk size is equal <br />
to the sum of each file's size entry, plus an extra 261 per file.)<br />
<br />
x 1 disk size high byte<br />
x+1 1 disk size low byte<br />
x+2 -<br />
<br />
== Other BIOS calls ==<br />
<br />
{| border="1" cellspacing="0" cellpadding="3"<br />
| Address || Name || Input parameters || Output parameters || Affected RAM/Registers || Description<br />
|-<br />
| $e149 || Delay132 || || || || 132 clock cycle delay<br />
|-<br />
| $e153 || Delayms || || || X, Y || Delay routine, Y = delay in ms (approximate)<br />
|-<br />
| $e161 || DisPFObj || || || A, $fe || Disable sprites and background<br />
|-<br />
| $e16b || EnPFObj || || || A, $fe || Enable sprites and background<br />
|-<br />
| $e170 || DisObj || || || A, $fe || Disable sprites<br />
|-<br />
| $e178 || EnObj || || || A, $fe || Enable sprites<br />
|-<br />
| $e17e || DisPF || || || A, $fe || Disable background<br />
|-<br />
| $e185 || EnPF || || || A, $fe || Enable background<br />
|-<br />
| $e1b2 || VINTWait || || || $ff || Wait until next VBlank NMI fires, and return (for programs that does it the "everything in main" way). NMI vector selection at $100 is preserved, but further VBlanks are disabled.<br />
|-<br />
| $e7bb || VRAMStructWrite || Pointer to VRAM buffer to be written || || A, X, Y, $00, $01, $ff || Set VRAM increment to 1 (clear $2000/$ff bit 2), and write a VRAM buffer to VRAM. Read below for information on the structure.<br />
|-<br />
| $e844 || FetchDirectPtr || || $00, $01 = pointer fetched || A, X, Y, $05, $06 || Fetch a direct pointer from the stack (the pointer should be placed after the return address of the routine that calls this one (see "important notes" above)), save the pointer at ($00) and fix the return address.<br />
|-<br />
| $e86a || WriteVRAMBuffer || || || A, X, Y, $301, $302 || Write the VRAM Buffer at $302 to VRAM. Read below for information on the structure.<br />
|-<br />
| $e8b3 || ReadVRAMBuffer || X = start address in buffer, Y = # of bytes to read || || A, X, Y || Read individual bytes from VRAM to the VRAMBuffer. Apparently this routine has been made so that, when combined to WriteVRAMBuffer, it can easily do read-modify-write operations to individual VRAM bytes.<br />
|-<br />
| $e8d2 || PrepareVRAMString || A = High VRAM address, X = Low VRAM address, Y = string length, Direct Pointer = data to be written to VRAM || A = $ff : no error, A = $01 : string didn't fit in buffer || A, X, Y, $00, $01, $02, $03, $04, $05, $06 || This routine copies pointed data into the VRAM buffer.<br />
|-<br />
| $e8e1 || PrepareVRAMStrings || A = High VRAM address, X = Low VRAM address, Direct pointer = data to be written to VRAM || A = $ff : no error, A = $01 : data didn't fit in buffer || A, X, Y, $00, $01, $02, $03, $04, $05, $06 || This routine copies a 2D string into the VRAM buffer. The first byte of the data determines the width and height of the following string (in tiles): Upper nybble = height, lower nybble = width.<br />
|-<br />
| $e94f || GetVRAMBufferByte || X = starting index, Y = # of byte to read in buffer (starting at 1), $00, $01 = address to read from || carry clear : a byte was read, carry set : no byte was read || A, X, Y || This routine is somewhat obscure, and was probably meant to be used in pair with ReadVRAMBuffer. First the index is calculated as x+3*(y-1). Then the address stored at that index is compared with the address in ($00). If match, the third byte is read and the routine exit with c clear. If not match, the address is overwritten by the address in ($00) and the routine exit with c set. Exact details in how this could be any useful is under analysis.<br />
|-<br />
| $e97d || Pixel2NamConv || $02 = Pixel X cord, $03 = Pixel Y cord || $00 = High nametable address, $01 = Low nametable address || A || This routine convert pixel screen coordinates to corresponding nametable address (assumes no scrolling, and points to first nametable at $2000-$23ff).<br />
|-<br />
| $e997 || Nam2PixelConv || $00 = High nametable address, $01 = low nametable address || $02 = Pixel X cord, $03 = Pixel Y cord || A || This routine convert a nametable address to corresponding pixel coordinates (assume no scrolling).<br />
|-<br />
| $e9b1 || Random || X = Zero Page address where the random bytes are placed, Y = # of shift register bytes (normally $02) || || A, X, Y, $00 || This is a shift-register based random number generator, normally takes 2 bytes (using more won't affect random sequence). On reset you are supposed to write some non-zero values here (BIOS uses writes $d0, $d0), and call this routine several times before the data is actually random. Each call of this routine will shift the bytes ''right''.<br />
|-<br />
| $e9c8 || SpriteDMA || || || A || This routine does sprite DMA from RAM $200-$2ff<br />
|-<br />
| $e9d3 || CounterLogic || A, Y = end Zeropage address of counters, X = start zeropage address of counters || || A, X, $00 || This decrements several counters in Zeropage. The first counter is a decimal counter 9 -> 8 -> 7 -> ... -> 1 -> 0 -> 9 -> ... Counters 1...A are simply decremented and stays at 0. Counters A+1...Y are decremented when the first counter does a 0 -> 9 transition, and stays at 0.<br />
|-<br />
| $e9eb || ReadPads || || $f5 = Joypad #1 data, $f6 = Joypad #2 data || A, X, $00, $01, || This read hardwired famicom joypads.<br />
|-<br />
| $ea1a || ReadDownPads || || $f5 = Joypad #1 up->down transitions, $f6 = Joypad #2 up->down transitions $f7 = Joypad #1 data, $f8 = Joypad #2 data || A, X, $00, $01 || This reads hardwired famicom joypads, and detect up->down button transitions<br />
|-<br />
| $ea1f || ReadOrDownPads || || $f5 = Joypad #1 up->down transitions, $f6 = Joypad #2 up->down transitions $f7 = Joypad #1 data, $f8 = Joypad #2 data || A, X, $00, $01 || This read both hardwired famicom and expansion port joypads and detect up->down button transitions.<br />
|-<br />
| $ea36 || ReadDownVerifyPads || || $f5 = Joypad #1 up->down transitions, $f6 = Joypad #2 up->down transitions $f7 = Joypad #1 data, $f8 = Joypad #2 data || A, X, $00, $01 || This reads hardwired Famicom joypads, and detect up->down button transitions. Data is read until two consecutive read matches to work around the DMC reading glitches.<br />
|-<br />
| $ea4c || ReadOrDownVerifyPads || || $f5 = Joypad #1 up->down transitions, $f6 = Joypad #2 up->down transitions $f7 = Joypad #1 data, $f8 = Joypad #2 data || A, X, $00, $01 || This read both hardwired famicom and expansion port joypads and detect up->down button transitions. Data is read until two consecutive read matches to work around the DMC reading glitches.<br />
|-<br />
| $ea68 || ReadDownExpPads || $f1-$f4 = up->down transitions, $f5-$f8 = Joypad data in the order : Pad1, Pad2, Expansion1, Expansion2 || || A, X, $00, $01 || This read both hardwired famicom and expansion port joypad, but stores their data separately instead of ORing them together like the other routines does. This routine is NOT DMC fortified.<br />
|-<br />
| $ea84 || VRAMFill || A = High VRAM Address (aka tile row #), X = Fill value, Y = # of tile rows OR attribute fill data || || A, X, Y, $00, $01, $02 || This routine does 2 things : If A < $20, it fills pattern table data with the value in X for 16 * Y tiles. If A >= $20, it fills the corresponding nametable with the value in X and attribute table with the value in Y.<br />
|-<br />
| $ead2 || MemFill || A = fill value, X = first page #, Y = last page # || || A, X, Y, $00, $01 || This routines fills RAM pages with specified value.<br />
|-<br />
| $eaea || SetScroll || || || A || This routine set scroll registers according to values in $fc, $fd and $ff. Should typically be called in VBlank after VRAM updates<br />
|-<br />
| $eafd || JumpEngine || A = Jump table entry || || A, X, Y, $00, $01 || The instruction calling this is supposed to be followed by a jump table (16-bit pointers little endian, up to 128 pointers). A is the entry # to jump to, return address on stack is used to get jump table entries.<br />
|-<br />
| $eb13 || ReadKeyboard || || || || Read Family Basic Keyboard expansion (detail is under analysis)<br />
|-<br />
| $eb66 || LoadTileset || A = Low VRAM Address & Flags, Y = Hi VRAM Address, X = # of tiles to transfer to/from VRAM || || A, X, Y, $00, $01, $02, $03, $04 || This routine can read and write 2BP and 1BP tilesets to/from VRAM. See appendix below about the flags.<br />
|}<br />
<br />
<br />
=== VRAM Buffer Structure ===<br />
<br />
The structure of VRAM buffers are as follows:<br />
<br />
SIZE CONTENTS<br />
2 VRAM Address (big endian)<br />
1 bit 0-5 length of data ($0 means a length of 64)<br />
bit 6 : 0 = copy, 1 = fill<br />
bit 7 : 0 = increment by 1, 1 = increment by 32<br />
n Data to copy to VRAM<br />
..... repeated as many times as needed<br />
1 $ff<br />
<br />
* The main structure is terminated by a $ff byte (High address is always supposed to be in $00..$3f range)<br />
* $4c is a "call" command. The 2 bytes that follow is the address of a sub-VRAM structure. The sub-structure can call another sub-structure and so on.<br />
* $60 is a "return" command. It will terminate a sub-structure.<br />
* If Fill mode is used, the routine takes only 1 byte of data which is repeated.<br />
<br />
=== VRAM Buffer notes ===<br />
<br />
The VRAM buffer is located at $300-$3xx. $300 holds the size of the buffer (maximum), and $301 holds the end index of the buffer. The actual buffer lies at $302-$3xx.<br />
<br />
* $300 is initialized to the value $7d, effectively making the buffer lie at $300-$37f. It's possible to change the value here to make it bigger or smaller, but the biggest possible value is $fd, making the buffer lie at $300-$3ff.<br />
* Format of the buffer is equivalent to the VRAM structure above, except that there are no sub-structures, no increment by 32 flag and no fill flag.<br />
* For this reason, the VRAM buffer at $302 can be used as a sub-structure.<br />
* A call to WriteVRAMBuffer will execute faster than a call to VRAMStructWrite with $302 as an argument, but both will have the same effect.<br />
* Read routines are still obscure and analyzed at the moment<br />
<br />
=== Load Tileset notes ===<br />
<br />
The ''flags'' parameters are as follows:<br />
<br />
7 bit 0<br />
---------<br />
AAAA MMIT<br />
|||| ||||<br />
|||| |||+- Fill bit<br />
|||| ||+-- Transfer direction (0 = Write tiles, 1 = Read tiles)<br />
|||| ++--- Bitplane type (see below)<br />
++++------ Low VRAM Address (aka tile # within a row)<br />
<br />
1st bitplane 2nd bitplane Description<br />
----------- ----------- -----------<br />
0: data data+8 Normal 2-bitplane graphics<br />
1: data fill bit Single bitplane graphics. Fill bit clear : Use colors 0&1 Fill bit set : Use colors 2&3<br />
2: fill bit data Single bitplane graphics. Fill bit clear : Use color 0&2 Fill bit set : Use colors 1&3<br />
3: data^fill bit data Single bitplane graphics. Fill bit clear : Use colors 0&3 Fill bit set : Use colors 1&2<br />
<br />
This makes it possible for single bitplane tiles to take all possible color schemes when they end up in VRAM.<br />
However, it is not possible to (natively) load single bitplane graphics directly from the disk into VRAM; you have to load them into RAM before transferring the data into VRAM.<br />
In read mode, all non "data" bitplanes are replaced by dummy reads.<br />
<br />
== References ==<br />
* [http://nesdev.parodius.com/FDSListWIN.zip FDS Lister by ccovell]</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_156&diff=5127INES Mapper 1562012-09-05T18:24:00Z<p>Zeromus: add some rough notes on m156</p>
<hr />
<div>As of 04-sep-2012, fceux supports this mapper correctly (r2648). The code was taken from fceu-mm which had some bugs related to missing reset logic. It is additionally supported by the Nestopia 1.40u4 hack.<br />
<br />
It is described as "DIS23C01 DAOU ROM CONTROLLER, Korea" and is used by the following games:<br />
* Metal Force (K)<br />
* Buzz and Waldog (K)<br />
* General's Son (K)</div>Zeromushttps://www.nesdev.org/w/index.php?title=AxROM&diff=829AxROM2012-08-06T02:54:26Z<p>Zeromus: /* Various notes */</p>
<hr />
<div>The generic designation AxROM refers to Nintendo cartridge boards NES-[[AMROM]], NES-[[ANROM]], NES-[[AN1ROM]], NES-[[AOROM]], their [[Famicom|HVC]] counterparts, and clone boards. Most games developed by Rare Ltd. used an AxROM series board. The [[iNES]] format assigns [[iNES Mapper 007|mapper 7]] to AxROM.<br />
<br />
The following AxROM boards are known to exist:<br />
{| Border="1"<br />
! Board || PRG ROM || Bus conflicts<br />
|-<br />
|AMROM || 128 KB || Yes<br />
|-<br />
|ANROM || 128 KB || No<br />
|-<br />
|AN1ROM || 64 KB || No<br />
|-<br />
|AOROM || 128, 256 KB || Yes (by default)<br />
|}<br />
<br />
<br />
== Overview ==<br />
* PRG ROM size: up to 256 KB<br />
* PRG ROM bank size: 32 KB<br />
* PRG RAM: None<br />
* CHR capacity: 8 KB RAM [[Category:Mappers with CHR RAM]]<br />
* CHR bank size: Not bankswitched<br />
* Nametable [[mirroring]]: Single-screen, mapper-selectable<br />
* Subject to [[bus conflict]]s: AMROM/AOROM only [[Category:Mappers with bus conflicts]]<br />
<br />
== Banks ==<br />
* CPU $8000-$FFFF: 32 KB switchable PRG ROM bank<br />
<br />
== Solder pad config ==<br />
No solder pad config is needed on the AxROM board family.<br />
<br />
== Registers ==<br />
=== Bank select ($8000-$FFFF) ===<br />
7 bit 0<br />
---- ----<br />
xxxM xPPP<br />
| |||<br />
| +++- Select 32 KB PRG ROM bank for CPU $8000-$FFFF<br />
+------ Select 1 KB VRAM page for all 4 nametables<br />
<br />
== Hardware ==<br />
The AxROM boards contain a [[74161|74HC161]] binary counter used as a quad D latch (4-bit register). The ANROM and AN1ROM boards also contains a [[7402|74HC02]] which is used to disable the PRG ROM during writes, thus avoiding [[bus conflict]]s.<br />
<br />
== Various notes ==<br />
<br />
On the AOROM board, special mask ROMs with an additional positive CE on pin 2 (which is connected to PRG R/W) can be used to prevent bus conflicts without an additional chip. It seems that only double dare and wheel of fortune employ this trick noticeably--that is, if emulated with bus conflicts enabled, the games will glitch. Bootgod's database lacks quality coverage of the PCB backs for the AOROM games, so it is hard to determine yet which games may be wired this way.<br />
<br />
It is likely that every retail AOROM game could be emulated correctly without emulating bus conflicts.<br />
<br />
A few 128 KB games used AOROM instead of ANROM because this might sometimes be cheaper than a 74HC02 depending on production quantities.<br />
<br />
== Variants ==<br />
The only difference between AMROM and [[BxROM|BNROM]] is the mirroring configuration.<br />
<br />
In theory, it would be possible to implement the bank select register with a [[74377|74HC377]] octal D latch, allowing up to 512 kilobytes of PRG ROM, but no Rare game used this much memory.<br />
<br />
[[Category:Discrete logic mappers]]</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_112&diff=4836INES Mapper 1122012-07-16T22:16:21Z<p>Zeromus: add a notice to mapper112 that it is similar to mapper206 but a bit scrambled.</p>
<hr />
<div>This mapper is quite similar to [[INES Mapper 206|Mapper206]]; however, the registers are scrambled a bit. You should probably study the documentation below for details instead of referencing Mapper206. <br />
<br />
Here are Disch's original notes: <br />
========================<br />
= Mapper 112 =<br />
========================<br />
<br />
Example Games:<br />
--------------------------<br />
Huang Di<br />
San Guo Zhi - Qun Xiong Zheng Ba<br />
<br />
<br />
Registers:<br />
---------------------------<br />
<br />
Range,Mask: $8000-FFFF, $E001<br />
<br />
<br />
$8000: [.... .AAA]<br />
A = Address for use with $A000<br />
<br />
<br />
$A000: [DDDD DDDD]<br />
Data port:<br />
R:0 -> PRG reg 0<br />
R:1 -> PRG reg 1<br />
R:2 -> CHR reg 0<br />
R:3 -> CHR reg 1<br />
R:4 -> CHR reg 2<br />
R:5 -> CHR reg 3<br />
R:6 -> CHR reg 4<br />
R:7 -> CHR reg 5<br />
<br />
<br />
$E000: [.... ...M]<br />
Mirroring: 0=Vert<br />
1=Horz<br />
<br />
<br />
CHR Setup:<br />
---------------------------<br />
<br />
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00 <br />
+---------------+---------------+-------+-------+-------+-------+<br />
| <R:2> | <R:3> | R:4 | R:5 | R:6 | R:7 |<br />
+---------------+---------------+-------+-------+-------+-------+<br />
<br />
<br />
PRG Setup:<br />
---------------------------<br />
<br />
$8000 $A000 $C000 $E000 <br />
+-------+-------+-------+-------+<br />
| R:0 | R:1 | { -2} | { -1} |<br />
+-------+-------+-------+-------+<br />
<br />
[[Category:iNES Mappers]][[Category:MMC3-like mappers]]</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_088&diff=4644INES Mapper 0882012-07-15T22:35:29Z<p>Zeromus: reduce mapper088 docs to a reference to mapper206 and hopefully concise description of the wiring difference.</p>
<hr />
<div>[[Category:iNES Mappers]][[Category:MMC3-like mappers]]<br />
<br />
Example Games:<br />
--------------------------<br />
Quinty (J)<br />
Namcot Mahjong 3<br />
Dragon Spirit - Aratanaru Densetsu<br />
<br />
This is the same as [[INES Mapper 206|Mapper206]] with the following exception:<br />
* CHR support is increased to 128KB by connecting PPU's A12 line to the CHR ROM's A16 line.<br />
<br />
For example, mask the CHR ROM 1K bank output from the mapper by $3F, and then OR it with $40 if the PPU address was >= $1000.<br />
<br />
Consequently, CHR is split into two halves. $0xxx can only have CHR from the first 64K, $1xxx can only have CHR from the second 64K.</div>Zeromushttps://www.nesdev.org/w/index.php?title=Talk:INES_Mapper_003&diff=13909Talk:INES Mapper 0032012-06-25T06:47:34Z<p>Zeromus: discuss KiB and KB re: zepper's m003 edit changing KiB to KB</p>
<hr />
<div>Some people change KiB to KB and some other people change KB to KiB. Personally, I want to punch anyone who thinks KB means anything but 1024 bytes, but they do have a point and its probably for the best. On the whole I have no opinion. But rather than zap everyone's edits repeatedly, we should probably decide what this wiki is gonna use and stick to it. --[[User:Zeromus|Zeromus]] 23:47, 24 June 2012 (PDT)</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_003&diff=3663INES Mapper 0032012-06-24T17:36:14Z<p>Zeromus: add some clarification on bus conflicts to m003</p>
<hr />
<div>[[Category:iNES Mappers]]<br />
<br />
'''iNES Mapper 003''' is used to designate the [[CNROM]] board and a very similar board used for Panesian games, generalized to support up to 255 banks (2040 KiB) of CHR ROM.<br />
<br />
In May 2012, the [[NROM-368|CNROM-368]] extension was proposed, allowing 46 KB PRG ROM.<br />
<br />
Here are Disch's original notes:<br />
========================<br />
= Mapper 003 =<br />
========================<br />
<br />
aka<br />
--------------------------<br />
CNROM (and compatible)<br />
<br />
<br />
Example Games:<br />
--------------------------<br />
Solomon's Key<br />
Arkanoid<br />
Arkista's Ring<br />
Bump 'n' Jump<br />
Cybernoid<br />
<br />
<br />
Registers (**BUS CONFLICTS** sometimes):<br />
--------------------------<br />
$8000-FFFF: [CCCC CCCC]<br />
CHR Reg (selects 8k @ $0000)<br />
<br />
<br />
Notes:<br />
---------------------------<br />
CNROM has bus conflicts, however mapper 003 is meant to be CNROM and compatible. So some mappers which were<br />
similar in function, but did not have bus conflicts are included.<br />
<br />
Additionally, CNROM's reg is only 2 bits wide... therefore it is capped at 32KiB CHR. Extra bits are listed here for the Panesian boards.<br />
<br />
There is no PRG swapping.<br />
<br />
The game Cybernoid seems to behave very strangely. It uses unprepped system RAM... and it is as if it<br />
actually relies on bus conflicts (AND written value with value read from address)! Supposedly this bug <br />
manifests by CHR corruptions when the music changes.<br />
<br />
The game "Colorful Dragon (Unl) (Sachen)" has glitched CHR if bus conflicts are emulated.<br />
<br />
Emulators will probably have to use hashes to know which games to emulate bus conflicts on.</div>Zeromushttps://www.nesdev.org/w/index.php?title=Talk:INES_Mapper_116&diff=14026Talk:INES Mapper 1162012-06-24T17:07:26Z<p>Zeromus: discuss VRC2 pins</p>
<hr />
<div>"However, it seems important that the $8xxx, $9xxx, $Axxx regs be mapped to the entire $1000 region ('''unlike stock VRC2 which is supposedly strictly answering to $8000-$8003, etc.''')" - this is at odds with the actual [[VRC2]] page (as well as its pinout), which states that it only only monitors A0-A1 and A12-A15. --[[User:Quietust|Quietust]] 09:29, 24 June 2012 (PDT)<br />
<br />
this seems like the kind of thing more likely to be understood today than historically. it sounds plausible to me. I'm willing to do some cursory tests to sanity check that it still emulates ok and then update the VRC2 and m116 docs, if someone will second it. --[[User:Zeromus|Zeromus]] 10:07, 24 June 2012 (PDT)</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_178&diff=5357INES Mapper 1782012-06-24T17:03:10Z<p>Zeromus: add m178 docs</p>
<hr />
<div>VirtuaNesEX sources call this mapper "Education / WaiXing / HengGe". However, virtuanes is among most other emulators in not supporting it fully; a game "Pet Family ES-1081" has a larger PRG than this mapper was originally supposed to handle, and only Nestopia 1.40u4 has been supporting it. The rest of the emulators will manifest a bug in the nametables when the main game engine starts. With r2536, FCEUX supports it; bizhawk does as well.<br />
<br />
This is a simple mapper.<br />
<br />
$4800: [.... ...M]<br />
M = Mirror mode<br />
%0 = Vertical<br />
%1 = Horizontal<br />
<br />
$4801: [...P PPP.]<br />
P = Some bits of the selected 32K PRG bank<br />
<br />
$4802: [pppp pppp]<br />
p = Some more bits of the selected 32K PRG bank<br />
<br />
The selected 32K PRG bank (mapped to $8000) is P + (p<<2). The older emulators are masking this result by & 0xF which is what breaks the larger PRG games. It is unclear whether this mask is necessary for some games to work.<br />
<br />
This addition is pretty weird. And, unlikely, I think. Pet Family seems to boot up and get past the nametable bug using an OR instead of a + which strikes me as much more likely.<br />
<br />
The new PRG bank is only committed when $4801 is written. Therefore, you should write $4802 first and then $4801 to complete the remapping.<br />
<br />
[[Category:iNES Mappers]]</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_116&diff=4870INES Mapper 1162012-06-23T08:49:02Z<p>Zeromus: m116 - add category tag</p>
<hr />
<div>These boards appear to have been researched by Cah4e3. They're used for some chinese games and bootlegs. He has described them in fceu-mm sources as:<br />
<br />
* SL12 Protected 3-in-1 mapper hardware (VRC2, MMC3, MMC1)<br />
* the same as 603-5052 board (TODO: add reading registers, merge)<br />
* SL1632 2-in-1 protected board, similar to SL12 (TODO: find difference)<br />
<br />
The following PCBs are listed as examples:<br />
<br />
* Garou Densetsu Special (G0904.PCB, Huang-1, GAL dip: W conf.)<br />
* Kart Fighter (008, Huang-1, GAL dip: W conf.)<br />
* Somari (008, C5052-13, GAL dip: P conf., GK2-P/GK2-V maskroms)<br />
* Somari (008, Huang-1, GAL dip: W conf., GK1-P/GK1-V maskroms)<br />
* AV Mei Shao Nv Zhan Shi ()<br />
* Samurai Spirits (Full version) (Huang-1, GAL dip: unk conf. GS-2A/GS-4A maskroms)<br />
* Contra Fighter (603-5052 board, C5052-3, GAL dip: unk conf. SC603-A/SCB603-B maskroms)<br />
<br />
These documents were verified by implementation into bizhawk based solely on the fceu-mm sources. FCEUX also possesses fceu-mm's sources for this mapper.<br />
<br />
This equipment is much simpler to operate than you might expect, considering that it is a combination of VRC2 + MMC3 + MMC1. There is a register:<br />
<br />
Range,Mask: $4000-7FFF, $4100<br />
$4100: [.... .CMM]<br />
MM = Mapper mode<br />
%00 = VRC2<br />
%01 = MMC3<br />
%02, %03 = MMC1<br />
C = 256K CHR ROM base (AV Girl Fighting uses this)<br />
<br />
This control register supposedly occupies the WRAM address range, so there can be no WRAM. However, it only answers to $41xx.<br />
<br />
The Mapper mode bits control which of the mapper circuits are connected to the NES. All of the PRG-based registers and IRQ signals are connected or disconnected accordingly. This means that in order to configure one of the mapper circuits, it must be connected. <br />
<br />
The VRC2 acts somewhat differently from a stock VRC2. Fundamentally, the VRC2 registers are mapped as documented elsewhere as VRC2b, not suffering from any of the PCB address signal rewiring complexities as most of the VRC-based boards. However, it seems important that the $8xxx, $9xxx, $Axxx regs be mapped to the entire $1000 region (unlike stock VRC2 which is supposedly strictly answering to $8000-$8003, etc.) This is important for "Garou Densetsu Special". Additionally, the PRG registers are 5 bits instead of 4. Finally, the CHR regs must be initialized specially: the first four to $FF, at least. (SOMARI-W depends on this). There is no evidence for what the subsequent 4 CHR regs must be initialized to.<br />
<br />
The MMC3 acts exactly as a stock TxROM. It has not been determined which MMC3 variant this MMC3 is acting as. Fceu-mm makes it seem as if the mmc3 CHR regs must be initialized at power-on in a certain pattern; it is unknown why this would be important.<br />
<br />
The MMC1 acts exactly as a stock SxROM. Fceu-mm contained "hacky hacky" logic to do a reset of sorts on the MMC1 whenever the low bit of $41xx's address was set, claiming it was necessary for SOMARI-W.<br />
<br />
The C bit of the m116's control reg simply provides a CHR ROM base offset for the VRC2 and MMC3 modes. After running the VRC2 or MMC3 logic, toss this extra signal onto the output CHR ROM address bus. One might speculate that this applies to MMC1 as well, but there is no evidence.<br />
<br />
[[Category:iNES Mappers]]</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_116&diff=4869INES Mapper 1162012-06-23T08:48:24Z<p>Zeromus: add mapper 116 docs based on inspection of cah4e3's sources and experimentation</p>
<hr />
<div>These boards appear to have been researched by Cah4e3. They're used for some chinese games and bootlegs. He has described them in fceu-mm sources as:<br />
<br />
* SL12 Protected 3-in-1 mapper hardware (VRC2, MMC3, MMC1)<br />
* the same as 603-5052 board (TODO: add reading registers, merge)<br />
* SL1632 2-in-1 protected board, similar to SL12 (TODO: find difference)<br />
<br />
The following PCBs are listed as examples:<br />
<br />
* Garou Densetsu Special (G0904.PCB, Huang-1, GAL dip: W conf.)<br />
* Kart Fighter (008, Huang-1, GAL dip: W conf.)<br />
* Somari (008, C5052-13, GAL dip: P conf., GK2-P/GK2-V maskroms)<br />
* Somari (008, Huang-1, GAL dip: W conf., GK1-P/GK1-V maskroms)<br />
* AV Mei Shao Nv Zhan Shi ()<br />
* Samurai Spirits (Full version) (Huang-1, GAL dip: unk conf. GS-2A/GS-4A maskroms)<br />
* Contra Fighter (603-5052 board, C5052-3, GAL dip: unk conf. SC603-A/SCB603-B maskroms)<br />
<br />
These documents were verified by implementation into bizhawk based solely on the fceu-mm sources. FCEUX also possesses fceu-mm's sources for this mapper.<br />
<br />
This equipment is much simpler to operate than you might expect, considering that it is a combination of VRC2 + MMC3 + MMC1. There is a register:<br />
<br />
Range,Mask: $4000-7FFF, $4100<br />
$4100: [.... .CMM]<br />
MM = Mapper mode<br />
%00 = VRC2<br />
%01 = MMC3<br />
%02, %03 = MMC1<br />
C = 256K CHR ROM base (AV Girl Fighting uses this)<br />
<br />
This control register supposedly occupies the WRAM address range, so there can be no WRAM. However, it only answers to $41xx.<br />
<br />
The Mapper mode bits control which of the mapper circuits are connected to the NES. All of the PRG-based registers and IRQ signals are connected or disconnected accordingly. This means that in order to configure one of the mapper circuits, it must be connected. <br />
<br />
The VRC2 acts somewhat differently from a stock VRC2. Fundamentally, the VRC2 registers are mapped as documented elsewhere as VRC2b, not suffering from any of the PCB address signal rewiring complexities as most of the VRC-based boards. However, it seems important that the $8xxx, $9xxx, $Axxx regs be mapped to the entire $1000 region (unlike stock VRC2 which is supposedly strictly answering to $8000-$8003, etc.) This is important for "Garou Densetsu Special". Additionally, the PRG registers are 5 bits instead of 4. Finally, the CHR regs must be initialized specially: the first four to $FF, at least. (SOMARI-W depends on this). There is no evidence for what the subsequent 4 CHR regs must be initialized to.<br />
<br />
The MMC3 acts exactly as a stock TxROM. It has not been determined which MMC3 variant this MMC3 is acting as. Fceu-mm makes it seem as if the mmc3 CHR regs must be initialized at power-on in a certain pattern; it is unknown why this would be important.<br />
<br />
The MMC1 acts exactly as a stock SxROM. Fceu-mm contained "hacky hacky" logic to do a reset of sorts on the MMC1 whenever the low bit of $41xx's address was set, claiming it was necessary for SOMARI-W.<br />
<br />
The C bit of the m116's control reg simply provides a CHR ROM base offset for the VRC2 and MMC3 modes. After running the VRC2 or MMC3 logic, toss this extra signal onto the output CHR ROM address bus. One might speculate that this applies to MMC1 as well, but there is no evidence.</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_241&diff=5829INES Mapper 2412012-06-20T22:17:37Z<p>Zeromus: add quick docs on m241</p>
<hr />
<div>[[Category:iNES Mappers]]<br />
<br />
ex. Fan Kong Jing Ying (Unl) (Ch)<br />
<br />
This mapper just has one register located at $8000-$FFFF which selects a 32KB PRG page. <br />
<br />
Additionally, the EXP bus may need to return 0x50<br />
<br />
This is supported in fceu-mm, fceux, and bizhawk (at least)</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_015&diff=3834INES Mapper 0152012-06-19T21:30:13Z<p>Zeromus: add some mostly useless notes to m015 based on some recent research</p>
<hr />
<div>[[Category:iNES Mappers]] [[Category:Pirate multicarts]]<br />
<br />
The [[iNES]] format assigns '''iNES Mapper 015''' as the mapper used in ''100-in-1 Contra Function 16'', the first pirate multicart to be emulated.<br />
<br />
The mapper allows multiple [[NROM]] or [[BNROM]] games plus one [[UNROM]] game to be used with very little modification. A few games originally released on a [[CNROM]] compatible board (such as two variants of ''Tetris'') showed up on the cart; these were ripped to NROM by tossing out all 8 KB CHR banks except the one used for gameplay.<br />
<br />
== Overview ==<br />
* PRG ROM size: Up to 512 KB<br />
* PRG ROM bank size: 8 KB, 16 KB, or 32 KB<br />
* PRG RAM: 8 KB<br />
* CHR capacity: 8 KB RAM [[Category:Mappers with CHR RAM]]<br />
* CHR bank size: None<br />
* Nametable [[mirroring]]: Controlled by mapper<br />
* Subject to [[bus conflict]]s: Unknown<br />
<br />
== Banks ==<br />
There is one switchable bank. How this is mapped into depends on the current bank mode (see [[#Registers|Registers below]]).<br />
<br />
=== Bank mode 0 ( 32K ) ===<br />
<br />
*CPU $8000-$BFFF: Bank B<br />
*CPU $C000-$FFFF: Bank (B OR 1)<br />
<br />
If bit 0 of B equals 1, then bank modes 1 and 2 are identical.<br />
<br />
=== Bank mode 1 ( 128K ) ===<br />
<br />
*CPU $8000-$BFFF: Switchable 16 KB bank B<br />
*CPU $C000-$DFFF: Fixed to last bank in the cart<br />
<br />
This mode uses the same configuration as [[UNROM]].<br />
<br />
=== Bank mode 2 ( 8K ) ===<br />
<br />
*CPU $8000-$9FFF: Sub-bank b of 16 KB PRG ROM bank B<br />
*CPU $A000-$FFFF: Mirrors of $8000-$9FFF<br />
<br />
=== Bank mode 3 ( 16K ) ===<br />
<br />
*CPU $8000-$BFFF: 16 KB bank B<br />
*CPU $C000-$FFFF: Mirror of $8000-$BFFF<br />
<br />
== Registers ==<br />
=== Control ($8000-$FFFF) ===<br />
This is a 10-bit register. The upper 2 bits of the value are set from address lines A1-A0.<br />
<br />
15 bit 8 7 bit 0 Address bus<br />
---- ---- ---- ----<br />
1xxx xxxx xxxx xxSS<br />
| ||<br />
| ++- Select PRG ROM bank mode<br />
| 0: 32K; 1: 128K (UNROM style); 2: 8K; 3: 16K<br />
+------------------- Always 1<br />
<br />
7 bit 0 Data bus<br />
---- ----<br />
bMBB BBBB<br />
|||| ||||<br />
||++-++++- Select 16 KB PRG ROM bank<br />
|+-------- Select nametable mirroring mode (0=vertical; 1=horizontal)<br />
+--------- Select 8 KB half of 16 KB PRG ROM bank<br />
(should be 0 except in bank mode 0)<br />
<br />
The result when b=1 outside of bank mode 0 is not specified.<br />
<br />
Power-up state: bank mode 2, bank 0, mirroring not specified.<br />
<br />
Some emulators (fceux, virtuanesex) are XORing the b (8KB half) bit frequently instead of ORing or ignoring. It is unclear what effects this would have. Additionally, there is some disagreement as to the boot-up state (disch says mode 0, the above says mode 2, emulators vary).<br />
<br />
The unlicensed chinese WXN game "Bio Hazard" which uses this mapper freezes in the same way in fceux, fceu-mm, nestopia, bizhawk, and virtuanesx (maybe?) and so the game is probably buggy.<br />
<br />
== Hardware ==<br />
<br />
== Variants ==<br />
<br />
Here are Disch's original notes:<br />
========================<br />
= Mapper 015 =<br />
========================<br />
<br />
Example Game:<br />
--------------------------<br />
100-in-1 Contra Function 16<br />
<br />
<br />
Notes:<br />
---------------------------<br />
<br />
Possible bus conflicts???<br />
<br />
<br />
<br />
Registers:<br />
---------------------------<br />
<br />
$8000-FFFF: A~[.... .... .... ..OO]<br />
[pMPP PPPP]<br />
O = Mode<br />
p = Low bit of PRG page (not always used)<br />
P = High bits of PRG page<br />
M = Mirroring (0=Vert, 1=Horz)<br />
<br />
<br />
PRG Setup:<br />
---------------------------<br />
<br />
Depending on the Mode used, the 'p' bit may not be used. In the chart below, "P" will indicate that only the<br />
'P' bits are used to form a 6-bit page number... whereas "Pp" will indicate the full 7-bit page number.<br />
<br />
<br />
$8000 $A000 $C000 $E000 <br />
+---------------+---------------+<br />
Mode 0: | P | P OR 1 |<br />
+---------------+---------------+<br />
Mode 1: | P | { -1} |<br />
+---------------+---------------+<br />
Mode 2: | Pp | Pp | Pp | Pp |<br />
+---------------+---------------+<br />
Mode 3: | P | P |<br />
+---------------+---------------+<br />
<br />
<br />
Powerup:<br />
---------------------------<br />
All regs reset to 0 on powerup.</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_210&diff=5632INES Mapper 2102012-06-16T16:23:52Z<p>Zeromus: m210 clarification</p>
<hr />
<div>This mapper represents the NAMCOT-175 board, used for ''Wagyan 2'' and ''Splatterhouse 2''.<br />
It is very similar to [[iNES Mapper 019]], having a [[Namco 106]] with no [[Namco 163 audio|N163 expansion sound]].<br />
Some reports claim it has hardwired mirroring (like [[TxROM|TFROM]]); others claim only that games rely on a well-defined default mirroring (which should be set in the iNES header, but is expected always to be vertical, due to the practical necessity of the mirroring being implemented through uniform [[Namco 106]] registers default values)</div>Zeromushttps://www.nesdev.org/w/index.php?title=Talk:INES_Mapper_210&diff=14117Talk:INES Mapper 2102012-06-16T15:49:09Z<p>Zeromus: m210 discussion</p>
<hr />
<div>Does this mapper actually exist? The boards Disch mentions as #210 are #19 in Bootgod's DB and don't seem to have hardwired mirroring when I trace the board. [[User:Lidnariq|Lidnariq]] 23:11, 15 June 2012 (PDT)<br />
----<br />
I checked out a bunch of roms. They all came to me as mapper 19. I removed the 210 special logic from this mapper, and they all seemed to work, as long as the default nametable registers were $FE, $FF, $FE, $FF (vertical mirroring). Wagyan 2 depended on this. Wagyan 2 is NAMCOT-175. Splatterhouse 2 is NAMCOT-175 as well, and it needs vertical mirroring as well, but it sets its registers. So Wagyan 2 must be on a board that uses the nametable regs and is truly depending on the default values. Therefore, I agree that there is no difference between 019 and 210.<br />
<br />
Even if there is no functional difference between 019 and 210, if there are roms in the wild that are 210, we should keep the mapper reserved for it, at the very least with notes similar to this. Itd be a good candidate for recovery, but there are better. Ill have to scour my roms and see if there are any 210 left. <br />
[[User:Zeromus|Zeromus]] 08:49, 16 June 2012 (PDT)</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_095&diff=4730INES Mapper 0952012-06-15T21:06:01Z<p>Zeromus: learned to preview first</p>
<hr />
<div>[[Category:iNES Mappers]][[Category:MMC3-like mappers]]<br />
Mapper 95 represents '''NAMCOT-3425''', a board that is to the ordinary Namco 108 family boards ([[iNES Mapper 206|mapper 206]]) as TKSROM and TLSROM ([[iNES Mapper 118|mapper 118]]) is to ordinary MMC3 boards ([[iNES Mapper 004|mapper 4]]).<br />
Instead of having hardwired mirroring like mapper 206, it has CHR A15 directly controlling CIRAM A10, just as CHR A17 controls CIRAM A10 on TxSROM.<br />
Only horizontal mirroring and 1-screen mirroring are possible because the Namco 108 lacks the C bit of MMC3.<br />
It is used for [http://bootgod.dyndns.org:7777/profile.php?id=1806 Dragon Buster (J)], which has 32 KiB of CHR ROM.<br />
The mapper could be extended to 64 KiB through careful arrangement of CHR ROM to put game background tiles in one half (which would always use one nametable) and status bar and menu tiles in the other half (which would always use the other nametable).<br />
<br />
Disch's older notes described an extended and mistaken version of this mapper with a full MMC3, so some emulators may be doing it that way. That extended version is identical to mapper 118, except CHR A15 (bank bit 5) controls CIRAM A10 instead of CHR A17 (bank bit 7).<br />
<br />
Here's a terse pseudocode:<br />
chr_rom_addr = namco108_chrmap(ppu_addr&0x1FFF) & 0x7FFF;<br />
ciram_addr = ((namco108_chrmap(ppu_addr&0x1FFF)>>15)<<10) | (ppu_addr&0x03FF);<br />
<br />
=== Bank data ($8001-$9FFF, odd) ===<br />
7 bit 0<br />
---- ----<br />
..ND DDDD<br />
|| ||||<br />
|+-++++- New bank value, based on last value written to Bank select register<br />
| All registers as standard [[iNES Mapper 206|Namco 108]]<br />
|<br />
+------- Nametable select, based on last value written to Bank select register<br />
0: Select Nametable A<br />
1: Select Nametable B<br />
The nametable at PPU $2000-$27FF (top left/right) are controlled with register 0<br />
The nametable at PPU $2800-$2FFF (bottom left/right) are controlled with register 1</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_095&diff=4729INES Mapper 0952012-06-15T21:05:37Z<p>Zeromus: add a bit of new style description to m095, maybe youll like it. an emulator coder should like it, anyway</p>
<hr />
<div>[[Category:iNES Mappers]][[Category:MMC3-like mappers]]<br />
Mapper 95 represents '''NAMCOT-3425''', a board that is to the ordinary Namco 108 family boards ([[iNES Mapper 206|mapper 206]]) as TKSROM and TLSROM ([[iNES Mapper 118|mapper 118]]) is to ordinary MMC3 boards ([[iNES Mapper 004|mapper 4]]).<br />
Instead of having hardwired mirroring like mapper 206, it has CHR A15 directly controlling CIRAM A10, just as CHR A17 controls CIRAM A10 on TxSROM.<br />
Only horizontal mirroring and 1-screen mirroring are possible because the Namco 108 lacks the C bit of MMC3.<br />
It is used for [http://bootgod.dyndns.org:7777/profile.php?id=1806 Dragon Buster (J)], which has 32 KiB of CHR ROM.<br />
The mapper could be extended to 64 KiB through careful arrangement of CHR ROM to put game background tiles in one half (which would always use one nametable) and status bar and menu tiles in the other half (which would always use the other nametable).<br />
<br />
Disch's older notes described an extended and mistaken version of this mapper with a full MMC3, so some emulators may be doing it that way. That extended version is identical to mapper 118, except CHR A15 (bank bit 5) controls CIRAM A10 instead of CHR A17 (bank bit 7).<br />
<br />
Here's a terse pseudocode:<br />
chr_rom_addr = namco108_chrmap(ppu_addr&0x1FFF) & 0x7FFF;<br />
ciram_addr = ((namco108_chrmap(ppu_addr&0x1FFF)>>15)<<10) | (ppu_addr&0x03FF);<br />
<br />
=== Bank data ($8001-$9FFF, odd) ===<br />
7 bit 0<br />
---- ----<br />
..ND DDDD<br />
|| ||||<br />
|+-++++- New bank value, based on last value written to Bank select register<br />
| All registers as standard [[iNES Mapper 206|Namco 108]]<br />
|<br />
+------- Nametable select, based on last value written to Bank select register<br />
0: Select Nametable A<br />
1: Select Nametable B<br />
The nametable at PPU $2000-$27FF (top left/right) are controlled with register 0<br />
The nametable at PPU $2800-$2FFF (bottom left/right) are controlled with register 1</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_095&diff=4728INES Mapper 0952012-06-15T20:34:07Z<p>Zeromus: wasnt happy with the last m095, i thought for 20 minutes that it was functionally changed before I understood it. Tried explaining it differently.</p>
<hr />
<div>[[Category:iNES Mappers]][[Category:MMC3-like mappers]]<br />
Mapper 95 represents '''NAMCOT-3425''', a board that is to the ordinary Namco 108 family boards ([[iNES Mapper 206|mapper 206]]) as TKSROM and TLSROM ([[iNES Mapper 118|mapper 118]]) is to ordinary MMC3 boards ([[iNES Mapper 004|mapper 4]]).<br />
Instead of having hardwired mirroring like mapper 206, it has CHR A15 directly controlling CIRAM A10, just as CHR A17 controls CIRAM A10 on TxSROM.<br />
Only horizontal mirroring and 1-screen mirroring are possible because the Namco 108 lacks the C bit of MMC3.<br />
It is used for [http://bootgod.dyndns.org:7777/profile.php?id=1806 Dragon Buster (J)], which has 32 KiB of CHR ROM.<br />
The mapper could be extended to 64 KiB through careful arrangement of CHR ROM to put game background tiles in one half (which would always use one nametable) and status bar and menu tiles in the other half (which would always use the other nametable).<br />
<br />
Disch's older notes described an extended and mistaken version of this mapper with a full MMC3, so some emulators may be doing it that way. That extended version is identical to mapper 118, except CHR A15 (bank bit 5) controls CIRAM A10 instead of CHR A17 (bank bit 7).<br />
<br />
=== Bank data ($8001-$9FFF, odd) ===<br />
7 bit 0<br />
---- ----<br />
..ND DDDD<br />
|| ||||<br />
|+-++++- New bank value, based on last value written to Bank select register<br />
| All registers as standard [[iNES Mapper 206|Namco 108]]<br />
|<br />
+------- Nametable select, based on last value written to Bank select register<br />
0: Select Nametable A<br />
1: Select Nametable B<br />
The nametable at PPU $2000-$27FF (top left/right) are controlled with register 0<br />
The nametable at PPU $2800-$2FFF (bottom left/right) are controlled with register 1</div>Zeromushttps://www.nesdev.org/w/index.php?title=INES_Mapper_095&diff=4726INES Mapper 0952012-06-15T17:50:53Z<p>Zeromus: m095 - thought the conclusion not to use dischs docs needed to be stronger, for clarification. why should we keep around the long docs? when we've pretty much tackled a board entirely, we should obsolete dischs docs</p>
<hr />
<div>[[Category:iNES Mappers]][[Category:MMC3-like mappers]]<br />
Mapper 95 represents '''NAMCOT-3425''', a board that is to the ordinary Namco 108 family boards ([[iNES Mapper 206|mapper 206]]) as TKSROM and TLSROM ([[iNES Mapper 118|mapper 118]]) is to ordinary MMC3 boards ([[iNES Mapper 004|mapper 4]]).<br />
Instead of having hardwired mirroring like mapper 206, it has CHR A15 directly controlling CIRAM A10, just as CHR A17 controls CIRAM A10 on TxSROM.<br />
Only horizontal mirroring and 1-screen mirroring are possible because the Namco 108 lacks the C bit of MMC3.<br />
It is used for [http://bootgod.dyndns.org:7777/profile.php?id=1806 Dragon Buster (J)], which has 32 KiB of CHR ROM.<br />
The mapper could be extended to 64 KiB through careful arrangement of CHR ROM to put game background tiles in one half (which would always use one nametable) and status bar and menu tiles in the other half (which would always use the other nametable).<br />
<br />
Disch's older notes (below) describe an extended (mistaken) version of this mapper with a full MMC3, so some emulators may be doing it that way. This extended version is identical to mapper 118, except CHR A15 (bank bit 5) controls CIRAM A10 instead of CHR A17 (bank bit 7).<br />
<br />
========================<br />
= Mapper 095 =<br />
========================<br />
<br />
aka<br />
--------------------------<br />
MMC3 (modified)<br />
<br />
<br />
Example Game:<br />
--------------------------<br />
Dragon Buster (J)<br />
<br />
<br />
Notes:<br />
---------------------------<br />
This mapper is a modified [[MMC3]]. It behaves exactly like your normal MMC3, only mirroring is handled<br />
differently. For details on MMC3, refer to [[INES Mapper 004|mapper 004]].<br />
<br />
<br />
Regs:<br />
---------------------------<br />
<br />
$8000: [CP.. .AAA]<br />
C = CHR Mode<br />
P = PRG Mode<br />
A = Address for $8001<br />
<br />
<br />
This register operates exactly like it does on your normal MMC3. It is mentioned here because the 'C' bit<br />
has another usage for mirroring.<br />
<br />
<br />
<br />
The normal mirroring reg ($A000) is totally ignored, and the CHR regs select nametables:<br />
<br />
When 'C' is set:<br />
[ R:2 ][ R:3 ]<br />
[ R:4 ][ R:5 ]<br />
<br />
When 'C' is clear:<br />
[ R:0 ][ R:0 ]<br />
[ R:1 ][ R:1 ]<br />
<br />
<br />
For mirroring, only bit 5 of the CHR regs is significant. Bit 5 of the appropriate reg selects either NTA or<br />
NTB.</div>Zeromus