https://www.nesdev.org/w/api.php?action=feedcontributions&user=Bregalad&feedformat=atomNESdev Wiki - User contributions [en]2024-03-28T16:01:40ZUser contributionsMediaWiki 1.39.0https://www.nesdev.org/w/index.php?title=MMC5&diff=21724MMC52024-03-28T08:29:44Z<p>Bregalad: Oops, better sorting of the info between footnote and extended attribute mode</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 />
A later '''[[#MMC5A|MMC5A]]''' revision was introduced with a few extra features, but all released games do not rely on these features and are compatible with the original MMC5.<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 ($5000-$5015) ===<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 ($2000 = [[PPUCTRL]]) ====<br />
7 bit 0<br />
---- ----<br />
xxZx xxxx<br />
|<br />
+------- Sprite size (0: 8x8 pixels; 1: 8x16 pixels)<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 />
==== PPU Data Substitution Enable ($2001 = [[PPUMASK]]) ====<br />
7 bit 0<br />
---------<br />
xxxE Exxx<br />
| |<br />
+-+--- 1,2,3: Substitutions enabled; 0: substitutions disabled<br />
<br />
The MMC5 listens to writes to PPUMASK ($2001). When it sees that both E bits are cleared, it disables its ability to make substitutions on the PPU data bus. This includes disabling:<br />
* Independent bank 8x16 sprite mode<br />
* Extended attribute mode<br />
* Vertical split mode<br />
<br />
The MMC5 only listens to the fully decoded address $2001, so this can be tested by using the PPU’s mirrors of this register. For example, writing to register $2009 will be heard by the PPU but not the MMC5. It is not clear if that could have a practical use beyond test purposes.<br />
<br />
Scanline interrupts are not affected by this. Driving pin 92 low performs the same disabling function.<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 />
==== Internal extended RAM mode ($5104) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxXX<br />
||<br />
++- Specify extended RAM usage<br />
{| class=wikitable<br />
! $5104 !! CPU Access ($5C00-5FFF) !! PPUDATA Access ($2000-23FF){{sup|(1)}} !! Available as Nametable{{sup|(2)}} !! Enable Extended Attribute Mode<br />
|-<br />
! %00<br />
| <center>Write Only{{sup|(3)}}</center> || {{yes|Read/Write}} || {{yes}} || {{no}}<br />
|-<br />
! %01<br />
| <center>Write Only{{sup|(3)}}</center> || {{yes|Read/Write}} || {{yes}} || {{yes}}<br />
|-<br />
! %10<br />
| {{yes|Read/Write}} || {{no}} || {{no}} || {{no}}<br />
|-<br />
! %11<br />
| <center>Read Only</center> || {{no}} || {{no}} || {{no}}<br />
|-<br />
|}<br />
<br />
{{sup|(1)}}When configured as a nametable in register $5105, read and write access is possible through the PPU via registers $2006/$2007 when the PPU is not rendering.<br />
<br />
{{sup|(2)}}In modes %00 and %01, the extended RAM can be assigned as a nametable via register $5105. In the other modes, the nametable will read as if it contains all $00s. Though it is possible to still assign the extended RAM as a nametable in this case, you are going to have the same data used twice, once as extended attribute data, and once as nametable data, this does not seem to be a useful combination.<br />
<br />
Vertical split mode always uses the extended RAM as its nametable; it can’t be reassigned. When attempting to use mode %10 or %11, vertical split mode automatically gets disabled. When using mode %01 with vertical split mode, the non-split region gains extended attributes, and the split region does not use extended attributes. As long as the non-split region remains horizontally scrolled to align with the left edge of a nametable, it is possible to share the extended RAM for both purposes. For example, a split region on the right side of the screen will read its nametable data and non-extended attribute data from the “right side” of the extended RAM, and the left side of the screen will read its nametable data from wherever it is assigned in $5105, and get its extended attributes from the “left side” of the extended RAM. The two separate functions of extended RAM data would not overlap this way.<br />
<br />
{{sup|(3)}}Counterintuitively, writes in these modes are only allowed when the PPU is rendering. If writes are attempted during V-blank, they may be ignored or cause a corruption at that memory address. In practice, temporarily switch to mode %10 if you wish to write during V-blank.<br />
<br />
===== Extended attributes =====<br />
<br />
In mode %01, "Extended Attribute Mode", each byte of the MMC5's internal extended RAM is used to enhance the background tile at the corresponding nametable address. The extended attributes are 1-screen mirrored; in other words, they apply the same for all nametables.<br />
<br />
Format of each extended attribute byte:<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 />
In extended attribute mode, CHR banking behaves differently than normal when fetching background tiles from pattern tables:<br />
* CHR mode (register $5101) is ignored. CHR banks are always 4KB in this mode.<br />
* The values of the CHR banking registers $5120-$512B are also ignored.<br />
* Bits 0-5 specified here are used for selecting a 4KB CHR bank on a per-tile basis.<br />
* The two bits in $5130 are used globally as CHR bank bits 6 and 7.<br />
* Driving pin 92 low disables extended attribute mode. Extended attribute mode is also automatically disabled based on PPUMASK monitoring. (See section on $2001 monitoring.) In these cases, the non-extended attribute table is used instead.<br />
<br />
''Just Breed'', ''Yakuman Tengoku'', and the Koei games use extended attributes continuously.<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 - CIRAM page 0<br />
* 1 - CIRAM page 1<br />
* 2 - Internal extended RAM<br />
**When $5104 is set to mode %10 or %11, the nametable will read as all zeros. This does not share functionality with fill mode.<br />
* 3 - Fill-mode data<br />
**See registers $5106 and $5017<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 />
When a nametable is mapped to fill-mode in register $5105, all nametable fetches get replaced by the value of this register. Only the nametable is affected by fill mode. When the PPU later uses this information to fetch the corresponding tile from the pattern table, CHR banking is unaffected and continues to work normally.<br />
<br />
==== Fill-mode color ($5107) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxAA<br />
||<br />
++- Specify background palette index to use for fill-mode nametable<br />
When a nametable is mapped to fill-mode in register $5105, and $5104 is not in mode %01, all attribute table fetches get replaced by the value of this register. Each byte of the attribute table normally contains four 2-bit palette indexes. The two bits in this register are copied for all four indexes.<br />
<br />
When $5104 is in mode %01, extended attribute mode does apply for fill mode, and this register is ignored. However, if pin 92 is driven low in this mode, extended attribute mode becomes disabled and this register comes back into effect.<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 />
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 />
!CPU Address<br />
!scope="col" style="width: 125px;"|Mode 3 Registers<br />
!scope="col" style="width: 125px;"|Mode 2 Registers<br />
!scope="col" style="width: 125px;"|Mode 1 Registers<br />
!scope="col" style="width: 125px;"|Mode 0 Registers<br />
|-<br />
||'''$6000-7FFF'''|| $5113 (RAM only) || $5113 (RAM only) || $5113 (RAM only) || $5113 (RAM only)<br />
|-<br />
||'''$8000-9FFF'''|| $5114 || rowspan=2|$5115 || rowspan=2|$5115 || rowspan=4|$5117 (ROM only) <br />
|-<br />
||'''$A000-BFFF'''|| $5115<br />
|-<br />
||'''$C000-DFFF'''|| $5116 || $5116 || rowspan=2|$5117 (ROM only) <br />
|-<br />
||'''$E000-FFFF'''|| $5117 (ROM only) || $5117 (ROM only) <br />
|-<br />
|}<br />
<br />
Register bits $5113.7 and $5117.7 are always ignored. $5113 always maps RAM, and $5117 always maps ROM. Because of this, it is not possible to map the interrupt vectors to RAM in any mode. All known 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. This tells us that $5117 must have a reliable power-on value of $FF.<br />
<br />
When a bankswitch register controls an 8kByte CPU address range, register bits 6..0 correspond to PRG A19..A13.<br />
<br />
In PRG modes where a register controls a 16kByte CPU address range, register bits 6..1 correspond to PRG A19..A14. Register bit 0 is ignored and instead CPU A13 directly controls PRG A13. For example, comparing mode 3 to mode 2 for CPU address range $8000-BFFF. These are equivalent:<br />
*In mode 3, write value $90 to $5114 and value $91 to $5115.<br />
*In mode 2, write value $90 to $5115.<br />
<br />
However, these are not equivalent:<br />
*In mode 3, write value $91 to $5114 and value $92 to $5115.<br />
*In mode 2, write value $91 to $5115.<br />
<br />
The MMC5 ignores register bit 0 in the 16kByte bank.<br />
<br />
Similarly, when register $5117 controls a 32kByte CPU address range in mode 0, register bits 6..2 correspond to PRG A19..A15, register bits 1..0 are ignored, and CPU A14..A13 directly control PRG A14..A13<br />
<br />
====Separate PRG-ROM and PRG-RAM Address Busses====<br />
<br />
The MMC5 has separate sets of address pins for PRG-ROM and PRG-RAM. This is a concept that has proven difficult to understand and explain. It all stems from the fact that CPU A15 is not directly routed to the cartridge; the signal /ROMSEL is supplied instead. Though it is possible to figure out CPU A15 from /ROMSEL, it is not possible to use it to select the correct PRG address. The PRG address needs to be set sooner than this in order to have an adequate setup time for the RAM or ROM chips. So basically, the starting point is that the MMC5 has to ''ignore'' /ROMSEL (and therefore CPU A15) when it comes to the PRG address, for the purpose of timings. This effectively creates a mirror on the PRG address bus for CPU address range $0000-7FFF and $8000-FFFF. Specifically, this makes range $6000-7FFF indistinguishable from $E000-FFFF. Because the MMC5 wanted to have separately controllable mapping for those ranges, its solution was to make two separate PRG address busses.<br />
<br />
The MMC5's PRG-ROM address pins follow this logic. Though the PRG-ROM address bus is decoded at ''all'' CPU addresses, the gray areas always have PRG ROM /CE disabled:<br />
<br />
{| class="wikitable"<br />
!CPU Address<br />
!scope="col" style="width: 125px;"|Mode 3 PRG-ROM<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 2 PRG-ROM<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 1 PRG-ROM<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 0 PRG-ROM<br/>Address Source<br />
|-<br />
||'''$0000-1FFF'''|| style="background: #cccccc;"|$5114 || style="background: #cccccc;" rowspan=2|$5115 || style="background: #cccccc;" rowspan=2|$5115 || style="background: #cccccc;" rowspan=4|$5117<br />
|-<br />
||'''$2000-3FFF'''|| style="background: #cccccc;"|$5115<br />
|-<br />
||'''$4000-5FFF'''|| style="background: #cccccc;"|$5116 || style="background: #cccccc;"|$5116 || style="background: #cccccc;" rowspan=2|$5117<br />
|-<br />
||'''$6000-7FFF'''|| style="background: #cccccc;"|$5117 || style="background: #cccccc;"|$5117<br />
|-<br />
||'''$8000-9FFF'''|| style="background: #80C0FF;"|$5114 || style="background: #80C0FF;"rowspan=2|$5115 || style="background: #80C0FF;"rowspan=2|$5115 || style="background: #80C0FF;"rowspan=4|$5117<br />
|-<br />
||'''$A000-BFFF'''|| style="background: #80C0FF;"|$5115<br />
|-<br />
||'''$C000-DFFF'''|| style="background: #80C0FF;"|$5116 || style="background: #80C0FF;"|$5116 || style="background: #80C0FF;"rowspan=2|$5117<br />
|-<br />
||'''$E000-FFFF'''|| style="background: #80C0FF;"|$5117 || style="background: #80C0FF;"|$5117<br />
|-<br />
|}<br />
<br />
The MMC5's PRG-RAM address pins follow this logic, again with PRG-RAM /CE always disabled in the gray areas:<br />
{| class="wikitable"<br />
!CPU Address<br />
!scope="col" style="width: 125px;"|Mode 3 PRG-RAM<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 2 PRG-RAM<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 1 PRG-RAM<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 0 PRG-RAM<br/>Address Source<br />
|-<br />
||'''$0000-1FFF'''|| style="background: #cccccc;"|$5114 || style="background: #cccccc;" rowspan=2|$5115 || style="background: #cccccc;" rowspan=2|$5115 || style="background: #cccccc;" rowspan=3|$5113<br />
|-<br />
||'''$2000-3FFF'''|| style="background: #cccccc;"|$5115<br />
|-<br />
||'''$4000-5FFF'''|| style="background: #cccccc;"|$5116 || style="background: #cccccc;"|$5116 || style="background: #cccccc;"|$5113<br />
|-<br />
||'''$6000-7FFF'''|| style="background: #FFC0C0;"|$5113 || style="background: #FFC0C0;"|$5113 || style="background: #FFC0C0;"|$5113 || style="background: #FFC0C0;"|$5113<br />
|-<br />
||'''$8000-9FFF'''|| style="background: #FFC0C0;"|$5114 || style="background: #FFC0C0;"rowspan=2|$5115 || style="background: #FFC0C0;"rowspan=2|$5115 || style="background: #cccccc;" rowspan=4|$5113<br />
|-<br />
||'''$A000-BFFF'''|| style="background: #FFC0C0;"|$5115<br />
|-<br />
||'''$C000-DFFF'''|| style="background: #FFC0C0;"|$5116 || style="background: #FFC0C0;"|$5116 || style="background: #cccccc;" rowspan=2|$5113<br />
|-<br />
||'''$E000-FFFF'''|| style="background: #cccccc;"|$5113 || style="background: #cccccc;"|$5113<br />
|-<br />
|}<br />
<br />
If we overlap these two tables, the original table reemerges. Pink always has /CE enabled for RAM (using $5113), Blue always has /CE enabled for ROM (using $5117), and Purple chooses which /CE using the register bit 7. Gray always has RAM /CE and ROM /CE disabled at all times.<br />
{| class="wikitable"<br />
!CPU Address<br />
!scope="col" style="width: 125px;"|Mode 3 PRG<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 2 PRG<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 1 PRG<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 0 PRG<br/>Address Source<br />
|-<br />
||'''$0000-1FFF'''|| style="background: #cccccc;"|$5114 || style="background: #cccccc;" rowspan=2|$5115 || style="background: #cccccc;" rowspan=2|$5115 || style="background: #cccccc;" rowspan=3|$5113/$5117<br />
|-<br />
||'''$2000-3FFF'''|| style="background: #cccccc;"|$5115<br />
|-<br />
||'''$4000-5FFF'''|| style="background: #cccccc;"|$5116 || style="background: #cccccc;"|$5116 || style="background: #cccccc;"|$5113/$5117<br />
|-<br />
||'''$6000-7FFF'''|| style="background: #FFC0C0;"|$5113/$5117 || style="background: #FFC0C0;"|$5113/$5117 || style="background: #FFC0C0;"|$5113/$5117 || style="background: #FFC0C0;"|$5113/$5117<br />
|-<br />
||'''$8000-9FFF'''|| style="background: #D0C0E0;"|$5114 || style="background: #D0C0E0;"rowspan=2|$5115 || style="background: #D0C0E0;"rowspan=2|$5115 || style="background: #80C0FF;" rowspan=4|$5113/$5117<br />
|-<br />
||'''$A000-BFFF'''|| style="background: #D0C0E0;"|$5115<br />
|-<br />
||'''$C000-DFFF'''|| style="background: #D0C0E0;"|$5116 || style="background: #D0C0E0;"|$5116 || style="background: #80C0FF;" rowspan=2|$5113/$5117<br />
|-<br />
||'''$E000-FFFF'''|| style="background: #80C0FF;"|$5113/$5117 || style="background: #80C0FF;"|$5113/$5117<br />
|-<br />
|}<br />
<br />
<br />
==== PRG-RAM configurations ====<br />
<br />
In [[ExROM|commercial configurations]], bits 0 and 1 select pages ''within'' an SRAM chip, and bit 2 selects between two separate SRAMs. 8K and 32K games have a single SRAM chip that will only be active when bit 2 is clear. 16K games instead have two chips, but only the first is battery backed.<br />
{| class="wikitable"<br />
! rowspan=2 | Configuration<br />
! colspan=8 | bank value & 7<br />
|-<br />
! 0 !! 1 !! 2 !! 3 !! 4 !! 5 !! 6 !! 7<br />
|-<br />
! ELROM 0K<br />
| [[open bus]] || open bus || open bus || open bus || open bus || open bus || open bus || open bus<br />
|-<br />
! EKROM 8K (1 x 8K)<br />
| 0:$0000 || 0:$0000 || 0:$0000 || 0:$0000 || open bus || open bus || open bus || open bus<br />
|-<br />
! ETROM 16K (2 x 8K)<br />
| '''0''':$0000 || '''0''':$0000 || '''0''':$0000 || '''0''':$0000 || '''1''':$0000 || '''1''':$0000 || '''1''':$0000 || '''1''':$0000<br />
|-<br />
! EWROM 32K (1 x 32K)<br />
| 0:$'''0000''' || 0:$'''2000''' || 0:$'''4000''' || 0:$'''6000''' || open bus || open bus || open bus || open bus<br />
|-<br />
! Superset 64K (2 x 32K)<br />
| '''0''':$'''0000''' || '''0''':$'''2000''' || '''0''':$'''4000''' || '''0''':$'''6000''' || '''1''':$'''0000''' || '''1''':$'''2000''' || '''1''':$'''4000''' || '''1''':$'''6000'''<br />
|}<br />
<br />
Since [[iNES]] headers were lacking reliable PRG-RAM size information before [[NES 2.0]], some emulators may have selected these behaviours through ROM CRC checks.<br />
<br />
Because no ExROM game is known to write PRG-RAM with one bank value and then attempt to read back the same data with a different bank value, emulating the PRG-RAM as 64K at all times can be used as a compatible superset for all games.<br />
<br />
Investigation of the [[MMC5 pinout]] in 2018 revealed that bits 2 and 3 also control additional PRG-RAM address pins, which could theoretically have been used to select 32 banks of a single 128K SRAM, with bit 2 controlling PRG A15 directly rather than using the two chip select /CE outputs.<br />
<br />
==== Other PRG-RAM notes ====<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 />
* Games with 16K PRG-RAM only battery-save the first 8K.<br />
* [http://bootgod.dyndns.org:7777/search.php?ines=5&battery=Yes&group=groupid List of MMC5 games which include a battery].<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, the PPU ignores the [[PPUCTRL|sprite pattern table address]] and can select tiles from the entire 8 KiB of pattern tables, which on other mappers overlaps with the background pattern table. The MMC5 keeps track of whether the PPU is fetching background tiles or sprite tiles, and has new registers to specify independent banks for the background tiles even if they appear to be the same address from the PPU. This effectively creates a CHR window of 12 KiB, with up to eight 1 KiB banks of sprites available simultaneously. 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 />
<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 />
In extended attribute mode ($5104 = 1), this register likely acts as a global, instantaneous bank selection that gets appended as the most significant 2 bits of ''all'' of the tile-specific CHR banks, selecting which 256KB of CHR ROM is to be used for all background tiles on the screen. It is unlikely that the extended RAM stores all 10 bits per write, like registers $5120-$512B.<br />
<br />
=== Other Registers ===<br />
<br />
==== Vertical Split Mode ($5200) ====<br />
7 bit 0<br />
---- ----<br />
ESxW WWWW<br />
|| | ||||<br />
|| +-++++- Specify vertical split threshold tile count<br />
|+-------- Specify vertical split region screen side (0:left; 1:right)<br />
+--------- Enable vertical split mode<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 />
MMC5 internal extended RAM is always used as the nametable in split screen mode. Extended RAM mode ($5104) should be set to %00. RAM modes %10 or %11 disable split mode. Driving pin 92 low also disables split mode. Split mode is automatically disabled based on PPUMASK monitoring. (See section on $2001 monitoring)<br />
<br />
===== Location of the Split Threshold =====<br />
<br />
For each visible scanline, the PPU fetches data from the pattern tables for 34 background tiles. The MMC5 locates the split threshold by counting these pattern table fetches and comparing the count to the count value stored in register $5200. When the PPU is rendering in the split region, the MMC5 replaces the normal pattern table data with the split region pattern data. Because the split threshold is located based on pattern table fetch count and not based on any nametable information, the location of the split is more of an absolute position on the screen, always positioned the same number of tiles from the left side of the screen. The PPU’s fine horizontal scrolling can cause the first tile rendered to be of fractional width, however the vertical split threshold will always occur at a full tile boundary, so the exact location of the split threshold is affected by fine horizontal scrolling, potentially deviating by up to 7 pixels this way. (The entire split region also deviates by this same amount; see the next section.)<br />
<br />
Left Split:<br />
* Tiles 0 to T-1 are the split region.<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 region.<br />
<br />
===== Scrolling =====<br />
<br />
There is no intended horizontal scrolling of any kind for the split region. Right-side split regions will always remain right-aligned with the right-hand side of the nametable, and left-side split regions will always remain left-aligned with the left-hand side of the nametable. Coarse horizontal scrolling can still be used for the non-split region, but it does not carry into the split region because the MMC5 is not keeping track of the nametable addresses being fetched. However, fine horizontal scrolling of the PPU does move the split region up to 7 pixels, as described in the previous section.<br />
<br />
Vertical scrolling of the split region is fully independent, and fine vertical scrolling of the split region is possible only if CHR A0..3 are controlled by the MMC5. By default, Nintendo PCBs are wired in “CL Mode”, which prevents the fine vertical scrolling of the split region. (See [[MMC5 pinout]]).<br />
<br />
Vertical scrolling for the split region operates like normal vertical scrolling. 0-239 are valid scroll values, whereas 240-255 will display attribute table data as nametable data for the first few scanlines. The MMC5 does proper vertical mirroring of the split region nametable so that scrolling down properly rolls over to the top of the nametable, skipping the attribute table data that would naturally be located there.<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. (No existing games used the SL board configuration.)<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 actively rendering visible scanlines and cleared when not rendering; for example, vertical blank scanlines. This flag does not clear for the short H-Blank period between visible scanlines. When pin 92 is driven low, this flag remains low at all times. Additionally, scanline IRQs no longer occur when pin 92 is driven low.<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 />
=== Internal extended RAM ($5C00-$5FFF, read/write) ===<br />
Refer to register $5104 for special behaviors of the MMC5's 1KB internal extended RAM.<br />
<br />
<br />
== MMC5A ==<br />
<br />
The MMC5A was a later revision of MMC5 that included some extra features. Other than Just Breed mysteriously writing to $5800, no game is known that uses these features. Therefore, these will probably tend to have poor support from emulators.<br />
<br />
=== MMC5A Registers ===<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 xx00<br />
|| ||<br />
|| |+- MMC5.97 (CL3) Function (0 = I/O Control, 1 = $5800 read control<br />
|| +-- MMC5.98 (SL3) Function (0 = I/O Control, 1 = $5800 write control<br />
|+-------- MMC5.97 (CL3) I/O Data Direction (0 = output, 1 = input)<br />
+--------- MMC5.98 (SL3) I/O Data Direction (0 = output, 1 = input)<br />
<br />
When a function bit is set to 1, the pin becomes controlled by the applicable CPU writes or reads in the range $5800-$5BFF. The pin is normally driven high, and when the read or write occurs, it has a low pulse corresponding to !(M2). The intended purpose is unknown. It is theorized that it may attach a peripheral or additional RAM. When in this mode, none of the I/O configuration bits have any effect.<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 it is set as an I/O output in $5207.<br />
+--------- Value to be output on MMC5.98 pin (SL3) if it is set as an I/O output in $5207.<br />
<br />
Warning: The PCB may connect pins 97 and 98 directly to GND. Though not totally confirmed, setting them as output high while connected like this has appeared to break the output drivers of these pins. Also note that enabling the $5800 function will have these pins driving high most of the time as well.<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 each CPU cycle, specifically on the 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 has no effect on, and reading $5204 does not report on, IRQs generated these registers.<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 internal extended 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. It is theorized that this was used as a debug signal to measure CPU usage / idle time during development.<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 />
== 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>Bregaladhttps://www.nesdev.org/w/index.php?title=MMC5&diff=21723MMC52024-03-28T08:23:51Z<p>Bregalad: /* Internal extended RAM mode ($5104) */ Avoids to tell the same thing twice, removed the incorrect info of extended attribute being 4-screen mirrored when it is actually single-screen mirrored</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 />
A later '''[[#MMC5A|MMC5A]]''' revision was introduced with a few extra features, but all released games do not rely on these features and are compatible with the original MMC5.<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 ($5000-$5015) ===<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 ($2000 = [[PPUCTRL]]) ====<br />
7 bit 0<br />
---- ----<br />
xxZx xxxx<br />
|<br />
+------- Sprite size (0: 8x8 pixels; 1: 8x16 pixels)<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 />
==== PPU Data Substitution Enable ($2001 = [[PPUMASK]]) ====<br />
7 bit 0<br />
---------<br />
xxxE Exxx<br />
| |<br />
+-+--- 1,2,3: Substitutions enabled; 0: substitutions disabled<br />
<br />
The MMC5 listens to writes to PPUMASK ($2001). When it sees that both E bits are cleared, it disables its ability to make substitutions on the PPU data bus. This includes disabling:<br />
* Independent bank 8x16 sprite mode<br />
* Extended attribute mode<br />
* Vertical split mode<br />
<br />
The MMC5 only listens to the fully decoded address $2001, so this can be tested by using the PPU’s mirrors of this register. For example, writing to register $2009 will be heard by the PPU but not the MMC5. It is not clear if that could have a practical use beyond test purposes.<br />
<br />
Scanline interrupts are not affected by this. Driving pin 92 low performs the same disabling function.<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 />
==== Internal extended RAM mode ($5104) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxXX<br />
||<br />
++- Specify extended RAM usage<br />
{| class=wikitable<br />
! $5104 !! CPU Access ($5C00-5FFF) !! PPUDATA Access ($2000-23FF){{sup|(1)}} !! Available as Nametable{{sup|(2)}} !! Enable Extended Attribute Mode<br />
|-<br />
! %00<br />
| <center>Write Only{{sup|(3)}}</center> || {{yes|Read/Write}} || {{yes}} || {{no}}<br />
|-<br />
! %01<br />
| <center>Write Only{{sup|(3)}}</center> || {{yes|Read/Write}} || {{yes}} || {{yes}}<br />
|-<br />
! %10<br />
| {{yes|Read/Write}} || {{no}} || {{no}} || {{no}}<br />
|-<br />
! %11<br />
| <center>Read Only</center> || {{no}} || {{no}} || {{no}}<br />
|-<br />
|}<br />
<br />
{{sup|(1)}}When configured as a nametable in register $5105, read and write access is possible through the PPU via registers $2006/$2007 when the PPU is not rendering.<br />
<br />
{{sup|(2)}}In modes %00 and %01, the extended RAM can be assigned as a nametable via register $5105. In the other modes, the nametable will read as if it contains all $00s. In mode %01, "Extended Attribute Mode", each byte of the MMC5's internal extended RAM is used to enhance the background tile at the corresponding nametable address. The extended attributes are 1-screen mirrored; in other words, they apply the same for all nametables. Though it is possible to still assign the extended RAM as a nametable in this case, you are going to have the same data used twice, once as extended attribute data, and once as nametable data, this does not seem to be a useful combination.<br />
<br />
Vertical split mode always uses the extended RAM as its nametable; it can’t be reassigned. When attempting to use mode %10 or %11, vertical split mode automatically gets disabled. When using mode %01 with vertical split mode, the non-split region gains extended attributes, and the split region does not use extended attributes. As long as the non-split region remains horizontally scrolled to align with the left edge of a nametable, it is possible to share the extended RAM for both purposes. For example, a split region on the right side of the screen will read its nametable data and non-extended attribute data from the “right side” of the extended RAM, and the left side of the screen will read its nametable data from wherever it is assigned in $5105, and get its extended attributes from the “left side” of the extended RAM. The two separate functions of extended RAM data would not overlap this way.<br />
<br />
{{sup|(3)}}Counterintuitively, writes in these modes are only allowed when the PPU is rendering. If writes are attempted during V-blank, they may be ignored or cause a corruption at that memory address. In practice, temporarily switch to mode %10 if you wish to write during V-blank.<br />
<br />
<br />
Format of each extended attribute byte:<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 />
In extended attribute mode, CHR banking behaves differently than normal when fetching background tiles from pattern tables:<br />
* CHR mode (register $5101) is ignored. CHR banks are always 4KB in this mode.<br />
* The values of the CHR banking registers $5120-$512B are also ignored.<br />
* Bits 0-5 specified here are used for selecting a 4KB CHR bank on a per-tile basis.<br />
* The two bits in $5130 are used globally as CHR bank bits 6 and 7.<br />
* Driving pin 92 low disables extended attribute mode. Extended attribute mode is also automatically disabled based on PPUMASK monitoring. (See section on $2001 monitoring.) In these cases, the non-extended attribute table is used instead.<br />
<br />
''Just Breed'', ''Yakuman Tengoku'', and the Koei games use extended attributes continuously.<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 - CIRAM page 0<br />
* 1 - CIRAM page 1<br />
* 2 - Internal extended RAM<br />
**When $5104 is set to mode %10 or %11, the nametable will read as all zeros. This does not share functionality with fill mode.<br />
* 3 - Fill-mode data<br />
**See registers $5106 and $5017<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 />
When a nametable is mapped to fill-mode in register $5105, all nametable fetches get replaced by the value of this register. Only the nametable is affected by fill mode. When the PPU later uses this information to fetch the corresponding tile from the pattern table, CHR banking is unaffected and continues to work normally.<br />
<br />
==== Fill-mode color ($5107) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xxAA<br />
||<br />
++- Specify background palette index to use for fill-mode nametable<br />
When a nametable is mapped to fill-mode in register $5105, and $5104 is not in mode %01, all attribute table fetches get replaced by the value of this register. Each byte of the attribute table normally contains four 2-bit palette indexes. The two bits in this register are copied for all four indexes.<br />
<br />
When $5104 is in mode %01, extended attribute mode does apply for fill mode, and this register is ignored. However, if pin 92 is driven low in this mode, extended attribute mode becomes disabled and this register comes back into effect.<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 />
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 />
!CPU Address<br />
!scope="col" style="width: 125px;"|Mode 3 Registers<br />
!scope="col" style="width: 125px;"|Mode 2 Registers<br />
!scope="col" style="width: 125px;"|Mode 1 Registers<br />
!scope="col" style="width: 125px;"|Mode 0 Registers<br />
|-<br />
||'''$6000-7FFF'''|| $5113 (RAM only) || $5113 (RAM only) || $5113 (RAM only) || $5113 (RAM only)<br />
|-<br />
||'''$8000-9FFF'''|| $5114 || rowspan=2|$5115 || rowspan=2|$5115 || rowspan=4|$5117 (ROM only) <br />
|-<br />
||'''$A000-BFFF'''|| $5115<br />
|-<br />
||'''$C000-DFFF'''|| $5116 || $5116 || rowspan=2|$5117 (ROM only) <br />
|-<br />
||'''$E000-FFFF'''|| $5117 (ROM only) || $5117 (ROM only) <br />
|-<br />
|}<br />
<br />
Register bits $5113.7 and $5117.7 are always ignored. $5113 always maps RAM, and $5117 always maps ROM. Because of this, it is not possible to map the interrupt vectors to RAM in any mode. All known 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. This tells us that $5117 must have a reliable power-on value of $FF.<br />
<br />
When a bankswitch register controls an 8kByte CPU address range, register bits 6..0 correspond to PRG A19..A13.<br />
<br />
In PRG modes where a register controls a 16kByte CPU address range, register bits 6..1 correspond to PRG A19..A14. Register bit 0 is ignored and instead CPU A13 directly controls PRG A13. For example, comparing mode 3 to mode 2 for CPU address range $8000-BFFF. These are equivalent:<br />
*In mode 3, write value $90 to $5114 and value $91 to $5115.<br />
*In mode 2, write value $90 to $5115.<br />
<br />
However, these are not equivalent:<br />
*In mode 3, write value $91 to $5114 and value $92 to $5115.<br />
*In mode 2, write value $91 to $5115.<br />
<br />
The MMC5 ignores register bit 0 in the 16kByte bank.<br />
<br />
Similarly, when register $5117 controls a 32kByte CPU address range in mode 0, register bits 6..2 correspond to PRG A19..A15, register bits 1..0 are ignored, and CPU A14..A13 directly control PRG A14..A13<br />
<br />
====Separate PRG-ROM and PRG-RAM Address Busses====<br />
<br />
The MMC5 has separate sets of address pins for PRG-ROM and PRG-RAM. This is a concept that has proven difficult to understand and explain. It all stems from the fact that CPU A15 is not directly routed to the cartridge; the signal /ROMSEL is supplied instead. Though it is possible to figure out CPU A15 from /ROMSEL, it is not possible to use it to select the correct PRG address. The PRG address needs to be set sooner than this in order to have an adequate setup time for the RAM or ROM chips. So basically, the starting point is that the MMC5 has to ''ignore'' /ROMSEL (and therefore CPU A15) when it comes to the PRG address, for the purpose of timings. This effectively creates a mirror on the PRG address bus for CPU address range $0000-7FFF and $8000-FFFF. Specifically, this makes range $6000-7FFF indistinguishable from $E000-FFFF. Because the MMC5 wanted to have separately controllable mapping for those ranges, its solution was to make two separate PRG address busses.<br />
<br />
The MMC5's PRG-ROM address pins follow this logic. Though the PRG-ROM address bus is decoded at ''all'' CPU addresses, the gray areas always have PRG ROM /CE disabled:<br />
<br />
{| class="wikitable"<br />
!CPU Address<br />
!scope="col" style="width: 125px;"|Mode 3 PRG-ROM<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 2 PRG-ROM<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 1 PRG-ROM<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 0 PRG-ROM<br/>Address Source<br />
|-<br />
||'''$0000-1FFF'''|| style="background: #cccccc;"|$5114 || style="background: #cccccc;" rowspan=2|$5115 || style="background: #cccccc;" rowspan=2|$5115 || style="background: #cccccc;" rowspan=4|$5117<br />
|-<br />
||'''$2000-3FFF'''|| style="background: #cccccc;"|$5115<br />
|-<br />
||'''$4000-5FFF'''|| style="background: #cccccc;"|$5116 || style="background: #cccccc;"|$5116 || style="background: #cccccc;" rowspan=2|$5117<br />
|-<br />
||'''$6000-7FFF'''|| style="background: #cccccc;"|$5117 || style="background: #cccccc;"|$5117<br />
|-<br />
||'''$8000-9FFF'''|| style="background: #80C0FF;"|$5114 || style="background: #80C0FF;"rowspan=2|$5115 || style="background: #80C0FF;"rowspan=2|$5115 || style="background: #80C0FF;"rowspan=4|$5117<br />
|-<br />
||'''$A000-BFFF'''|| style="background: #80C0FF;"|$5115<br />
|-<br />
||'''$C000-DFFF'''|| style="background: #80C0FF;"|$5116 || style="background: #80C0FF;"|$5116 || style="background: #80C0FF;"rowspan=2|$5117<br />
|-<br />
||'''$E000-FFFF'''|| style="background: #80C0FF;"|$5117 || style="background: #80C0FF;"|$5117<br />
|-<br />
|}<br />
<br />
The MMC5's PRG-RAM address pins follow this logic, again with PRG-RAM /CE always disabled in the gray areas:<br />
{| class="wikitable"<br />
!CPU Address<br />
!scope="col" style="width: 125px;"|Mode 3 PRG-RAM<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 2 PRG-RAM<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 1 PRG-RAM<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 0 PRG-RAM<br/>Address Source<br />
|-<br />
||'''$0000-1FFF'''|| style="background: #cccccc;"|$5114 || style="background: #cccccc;" rowspan=2|$5115 || style="background: #cccccc;" rowspan=2|$5115 || style="background: #cccccc;" rowspan=3|$5113<br />
|-<br />
||'''$2000-3FFF'''|| style="background: #cccccc;"|$5115<br />
|-<br />
||'''$4000-5FFF'''|| style="background: #cccccc;"|$5116 || style="background: #cccccc;"|$5116 || style="background: #cccccc;"|$5113<br />
|-<br />
||'''$6000-7FFF'''|| style="background: #FFC0C0;"|$5113 || style="background: #FFC0C0;"|$5113 || style="background: #FFC0C0;"|$5113 || style="background: #FFC0C0;"|$5113<br />
|-<br />
||'''$8000-9FFF'''|| style="background: #FFC0C0;"|$5114 || style="background: #FFC0C0;"rowspan=2|$5115 || style="background: #FFC0C0;"rowspan=2|$5115 || style="background: #cccccc;" rowspan=4|$5113<br />
|-<br />
||'''$A000-BFFF'''|| style="background: #FFC0C0;"|$5115<br />
|-<br />
||'''$C000-DFFF'''|| style="background: #FFC0C0;"|$5116 || style="background: #FFC0C0;"|$5116 || style="background: #cccccc;" rowspan=2|$5113<br />
|-<br />
||'''$E000-FFFF'''|| style="background: #cccccc;"|$5113 || style="background: #cccccc;"|$5113<br />
|-<br />
|}<br />
<br />
If we overlap these two tables, the original table reemerges. Pink always has /CE enabled for RAM (using $5113), Blue always has /CE enabled for ROM (using $5117), and Purple chooses which /CE using the register bit 7. Gray always has RAM /CE and ROM /CE disabled at all times.<br />
{| class="wikitable"<br />
!CPU Address<br />
!scope="col" style="width: 125px;"|Mode 3 PRG<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 2 PRG<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 1 PRG<br/>Address Source<br />
!scope="col" style="width: 125px;"|Mode 0 PRG<br/>Address Source<br />
|-<br />
||'''$0000-1FFF'''|| style="background: #cccccc;"|$5114 || style="background: #cccccc;" rowspan=2|$5115 || style="background: #cccccc;" rowspan=2|$5115 || style="background: #cccccc;" rowspan=3|$5113/$5117<br />
|-<br />
||'''$2000-3FFF'''|| style="background: #cccccc;"|$5115<br />
|-<br />
||'''$4000-5FFF'''|| style="background: #cccccc;"|$5116 || style="background: #cccccc;"|$5116 || style="background: #cccccc;"|$5113/$5117<br />
|-<br />
||'''$6000-7FFF'''|| style="background: #FFC0C0;"|$5113/$5117 || style="background: #FFC0C0;"|$5113/$5117 || style="background: #FFC0C0;"|$5113/$5117 || style="background: #FFC0C0;"|$5113/$5117<br />
|-<br />
||'''$8000-9FFF'''|| style="background: #D0C0E0;"|$5114 || style="background: #D0C0E0;"rowspan=2|$5115 || style="background: #D0C0E0;"rowspan=2|$5115 || style="background: #80C0FF;" rowspan=4|$5113/$5117<br />
|-<br />
||'''$A000-BFFF'''|| style="background: #D0C0E0;"|$5115<br />
|-<br />
||'''$C000-DFFF'''|| style="background: #D0C0E0;"|$5116 || style="background: #D0C0E0;"|$5116 || style="background: #80C0FF;" rowspan=2|$5113/$5117<br />
|-<br />
||'''$E000-FFFF'''|| style="background: #80C0FF;"|$5113/$5117 || style="background: #80C0FF;"|$5113/$5117<br />
|-<br />
|}<br />
<br />
<br />
==== PRG-RAM configurations ====<br />
<br />
In [[ExROM|commercial configurations]], bits 0 and 1 select pages ''within'' an SRAM chip, and bit 2 selects between two separate SRAMs. 8K and 32K games have a single SRAM chip that will only be active when bit 2 is clear. 16K games instead have two chips, but only the first is battery backed.<br />
{| class="wikitable"<br />
! rowspan=2 | Configuration<br />
! colspan=8 | bank value & 7<br />
|-<br />
! 0 !! 1 !! 2 !! 3 !! 4 !! 5 !! 6 !! 7<br />
|-<br />
! ELROM 0K<br />
| [[open bus]] || open bus || open bus || open bus || open bus || open bus || open bus || open bus<br />
|-<br />
! EKROM 8K (1 x 8K)<br />
| 0:$0000 || 0:$0000 || 0:$0000 || 0:$0000 || open bus || open bus || open bus || open bus<br />
|-<br />
! ETROM 16K (2 x 8K)<br />
| '''0''':$0000 || '''0''':$0000 || '''0''':$0000 || '''0''':$0000 || '''1''':$0000 || '''1''':$0000 || '''1''':$0000 || '''1''':$0000<br />
|-<br />
! EWROM 32K (1 x 32K)<br />
| 0:$'''0000''' || 0:$'''2000''' || 0:$'''4000''' || 0:$'''6000''' || open bus || open bus || open bus || open bus<br />
|-<br />
! Superset 64K (2 x 32K)<br />
| '''0''':$'''0000''' || '''0''':$'''2000''' || '''0''':$'''4000''' || '''0''':$'''6000''' || '''1''':$'''0000''' || '''1''':$'''2000''' || '''1''':$'''4000''' || '''1''':$'''6000'''<br />
|}<br />
<br />
Since [[iNES]] headers were lacking reliable PRG-RAM size information before [[NES 2.0]], some emulators may have selected these behaviours through ROM CRC checks.<br />
<br />
Because no ExROM game is known to write PRG-RAM with one bank value and then attempt to read back the same data with a different bank value, emulating the PRG-RAM as 64K at all times can be used as a compatible superset for all games.<br />
<br />
Investigation of the [[MMC5 pinout]] in 2018 revealed that bits 2 and 3 also control additional PRG-RAM address pins, which could theoretically have been used to select 32 banks of a single 128K SRAM, with bit 2 controlling PRG A15 directly rather than using the two chip select /CE outputs.<br />
<br />
==== Other PRG-RAM notes ====<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 />
* Games with 16K PRG-RAM only battery-save the first 8K.<br />
* [http://bootgod.dyndns.org:7777/search.php?ines=5&battery=Yes&group=groupid List of MMC5 games which include a battery].<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, the PPU ignores the [[PPUCTRL|sprite pattern table address]] and can select tiles from the entire 8 KiB of pattern tables, which on other mappers overlaps with the background pattern table. The MMC5 keeps track of whether the PPU is fetching background tiles or sprite tiles, and has new registers to specify independent banks for the background tiles even if they appear to be the same address from the PPU. This effectively creates a CHR window of 12 KiB, with up to eight 1 KiB banks of sprites available simultaneously. 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 />
<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 />
In extended attribute mode ($5104 = 1), this register likely acts as a global, instantaneous bank selection that gets appended as the most significant 2 bits of ''all'' of the tile-specific CHR banks, selecting which 256KB of CHR ROM is to be used for all background tiles on the screen. It is unlikely that the extended RAM stores all 10 bits per write, like registers $5120-$512B.<br />
<br />
=== Other Registers ===<br />
<br />
==== Vertical Split Mode ($5200) ====<br />
7 bit 0<br />
---- ----<br />
ESxW WWWW<br />
|| | ||||<br />
|| +-++++- Specify vertical split threshold tile count<br />
|+-------- Specify vertical split region screen side (0:left; 1:right)<br />
+--------- Enable vertical split mode<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 />
MMC5 internal extended RAM is always used as the nametable in split screen mode. Extended RAM mode ($5104) should be set to %00. RAM modes %10 or %11 disable split mode. Driving pin 92 low also disables split mode. Split mode is automatically disabled based on PPUMASK monitoring. (See section on $2001 monitoring)<br />
<br />
===== Location of the Split Threshold =====<br />
<br />
For each visible scanline, the PPU fetches data from the pattern tables for 34 background tiles. The MMC5 locates the split threshold by counting these pattern table fetches and comparing the count to the count value stored in register $5200. When the PPU is rendering in the split region, the MMC5 replaces the normal pattern table data with the split region pattern data. Because the split threshold is located based on pattern table fetch count and not based on any nametable information, the location of the split is more of an absolute position on the screen, always positioned the same number of tiles from the left side of the screen. The PPU’s fine horizontal scrolling can cause the first tile rendered to be of fractional width, however the vertical split threshold will always occur at a full tile boundary, so the exact location of the split threshold is affected by fine horizontal scrolling, potentially deviating by up to 7 pixels this way. (The entire split region also deviates by this same amount; see the next section.)<br />
<br />
Left Split:<br />
* Tiles 0 to T-1 are the split region.<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 region.<br />
<br />
===== Scrolling =====<br />
<br />
There is no intended horizontal scrolling of any kind for the split region. Right-side split regions will always remain right-aligned with the right-hand side of the nametable, and left-side split regions will always remain left-aligned with the left-hand side of the nametable. Coarse horizontal scrolling can still be used for the non-split region, but it does not carry into the split region because the MMC5 is not keeping track of the nametable addresses being fetched. However, fine horizontal scrolling of the PPU does move the split region up to 7 pixels, as described in the previous section.<br />
<br />
Vertical scrolling of the split region is fully independent, and fine vertical scrolling of the split region is possible only if CHR A0..3 are controlled by the MMC5. By default, Nintendo PCBs are wired in “CL Mode”, which prevents the fine vertical scrolling of the split region. (See [[MMC5 pinout]]).<br />
<br />
Vertical scrolling for the split region operates like normal vertical scrolling. 0-239 are valid scroll values, whereas 240-255 will display attribute table data as nametable data for the first few scanlines. The MMC5 does proper vertical mirroring of the split region nametable so that scrolling down properly rolls over to the top of the nametable, skipping the attribute table data that would naturally be located there.<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. (No existing games used the SL board configuration.)<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 actively rendering visible scanlines and cleared when not rendering; for example, vertical blank scanlines. This flag does not clear for the short H-Blank period between visible scanlines. When pin 92 is driven low, this flag remains low at all times. Additionally, scanline IRQs no longer occur when pin 92 is driven low.<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 />
=== Internal extended RAM ($5C00-$5FFF, read/write) ===<br />
Refer to register $5104 for special behaviors of the MMC5's 1KB internal extended RAM.<br />
<br />
<br />
== MMC5A ==<br />
<br />
The MMC5A was a later revision of MMC5 that included some extra features. Other than Just Breed mysteriously writing to $5800, no game is known that uses these features. Therefore, these will probably tend to have poor support from emulators.<br />
<br />
=== MMC5A Registers ===<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 xx00<br />
|| ||<br />
|| |+- MMC5.97 (CL3) Function (0 = I/O Control, 1 = $5800 read control<br />
|| +-- MMC5.98 (SL3) Function (0 = I/O Control, 1 = $5800 write control<br />
|+-------- MMC5.97 (CL3) I/O Data Direction (0 = output, 1 = input)<br />
+--------- MMC5.98 (SL3) I/O Data Direction (0 = output, 1 = input)<br />
<br />
When a function bit is set to 1, the pin becomes controlled by the applicable CPU writes or reads in the range $5800-$5BFF. The pin is normally driven high, and when the read or write occurs, it has a low pulse corresponding to !(M2). The intended purpose is unknown. It is theorized that it may attach a peripheral or additional RAM. When in this mode, none of the I/O configuration bits have any effect.<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 it is set as an I/O output in $5207.<br />
+--------- Value to be output on MMC5.98 pin (SL3) if it is set as an I/O output in $5207.<br />
<br />
Warning: The PCB may connect pins 97 and 98 directly to GND. Though not totally confirmed, setting them as output high while connected like this has appeared to break the output drivers of these pins. Also note that enabling the $5800 function will have these pins driving high most of the time as well.<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 each CPU cycle, specifically on the 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 has no effect on, and reading $5204 does not report on, IRQs generated these registers.<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 internal extended 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. It is theorized that this was used as a debug signal to measure CPU usage / idle time during development.<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 />
== 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>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:MMC5&diff=21709Talk:MMC52024-03-26T14:05:31Z<p>Bregalad: /* iNES Mapper 5 page */ Link to Dish mappers notes</p>
<hr />
<div>==List of Mysteries==<br />
{| class="wikitable"<br />
! Resolved? !! Issue !! Notes/Clues/Theories<br />
|-<br />
|{{yes}}<br />
|Why does the MMC5 have a PPU /WR input?<br />
|Internal expansion RAM can be used as a normal nametable, and some games write to it using PPUDATA.<br />
|-<br />
|{{no}}<br />
|Why does the MMC5A (only) apparently listen to writes to PPUADDR?<br />
|Reads and writes from/to PPUDATA directly control the PPU address bus in range $0000-3FFF (A0-A13). Since the MMC5A would already know the PPU address this way, it stands to reason that the normally unused address bits A14 and A15 are captured for some reason. In normal use, A14 and A15 are ignored, resulting in 4 mirrors. Since the MMC5A has control over CIRAM /CE, it is possible that the MMC5A takes control of some or all of these mirrors for some purpose, possibly for the extended attribute data. Further investigation required.<br />
|-<br />
|{{no}}<br />
|What is the function of pins 29, 30, 81, 82?<br />
|The pins appear to behave as digital inputs with internal ESD protection diodes, but no function has been observed.<br />
|-<br />
|{{no}}<br />
|Why are CHR A0, A1, A2 not used on any known PCB?<br />
|Wiring the board in "SL mode" (with SL3-SL6 closed and CL3-CL6 open) routes PPU A0-A2 through the MMC5 chip, allowing split screen mode to perform smooth vertical scrolling without causing the tile data to "roll in-place". It's possible there was a downside to this configuration, but it is not known.<br />
|-<br />
|{{no}}<br />
|Why does the MMC5 apparently monitor writes to PPUSCROLL?<br />
|This could be to offset from fine vertical scrolling in split screen mode (see previous issue).<br />
|-<br />
|{{no}}<br />
|Why does the MMC5 apparently monitor writes to OAMDMA?<br />
|Could this trigger the MMC5 to listen to the OAM data and capture bits 2,3,4 in byte 2 of each sprite for some purpose? If so, could those bits be selecting a CHR bank for the sprite? If not so, does that function need to be enabled in a register somehow?<br />
|-<br />
|{{no}}<br />
|Why does the MMC5 apparently listen to PPUSTATUS reads?<br />
|The MMC5's scanline detection appears to already do quite well detecting scanlines and v-blank.<br />
|-<br />
|{{no}}<br />
|PCM audio "read mode" is intended to result in CPU efficiency savings, as stated in its patent. There is no known way that this mode could save any CPU cycles.<br />
|The present theory is that the feature failed its objective did not end up to be useful.<br />
|-<br />
|{{no}}<br />
|Scanline detection diagram and pseudocode do not match each other well in the wiki.<br />
|Further investigation required. These items should be able to reference each other directly/clearly.<br />
|-<br />
|{{no}}<br />
|Is expansion RAM backed up by the battery? If so, is it subject to holding reset at power off to prevent corruption?<br />
|Yes, the MMC5's internal RAM is backed up by the battery. No games seem to use it, and it's unclear why. See also this post: https://forums.nesdev.org/viewtopic.php?p=246243#p246243<br />
|-<br />
|{{no}}<br />
|Is it possible to use an external CHR-RAM for extended attributes on more than 1 nametable?<br />
|This seems like too obvious of an omission based on the level of other features in this chip. Since PPU reads occur every other PPU cycle (due to its multiplexed data/address bus), there is an extra cycle everywhere that can potentially be used to read extended attributes from elsewhere from the same RAM.<br />
|-<br />
|}<br />
<br />
== [[wikipedia:Don't repeat yourself|Don't Repeat Yourself]] failure ==<br />
Ok, it's crazy to have two completely different pages explaining the MMC5 mapper, one on iNES mapper 5 and the other on MMC5. I think the info should be present on a single page (like it is for all other mappers).<br />
<br />
Well in fact it seems it's Zeromus who added Dish's notes on all iNES mapper pages. This would be nice if the info wasn't already present on the wiki - having twice the same info isn't very logical is it ? I don't know what to do but something should probably be changed...Bregalad 00:36, 23 March 2012 (PDT)<br />
<br />
:Disch' format is '''much''' better for reading. Funny, I was really thinking to discuss about such thing. :) --[[User:Zepper|Zepper]] 14:44, 23 March 2012 (PDT)<br />
<br />
:Problem solved. @Zepper : If there is a particular point that should be improved about how the mappers are presented on the wiki, then please change it (or at least say more precisely what is ''much'' better).[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:02, 20 April 2015 (MDT)<br />
<br />
::Rather than just deleting them, I've been trying to review the disch notes and compare them to the existing article, integrating anything that it was adding before removing it. It's more time consuming than just deleting them, but the whole point of zeromus pasting them here was that they might improve the articles. Sometimes they add nothing, for sure, but it's worth reviewing before deleting, I think. In the process you might find other things here and there to improve in the mapper articles too. This review process is healthy for the wiki content. We don't need to be in a hurry to scour the disch notes from the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 20:38, 20 April 2015 (MDT)<br />
<br />
:: They have been here for more than three years, so how much time should have been waited for their removal in your opinion? 10 years? As I said they are still available, so you can just download them, and do the review work using your local copy of Dish notes. No point to have them pasted here, period. I absolutely agree that such a review work is benefical, and if there is a particular part you'd want me to review, just ask.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 03:13, 21 April 2015 (MDT)<br />
<br />
::: If you'd bothered to pay attention to what Rainwarrior's been doing, he's been carefully looking over each page and incorporating Disch's documentation as he goes, not just blindly removing everything.—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 04:53, 21 April 2015 (MDT)<br />
<br />
::: I did not just remove it but link to the original place. That's a different thing. Please explain me why Rainwarrior cannot download dish's document on his hard drive and work with that copy. (answer : he can, and that makes a lot more sense). Anyways I'm sick of editing this wiki for a while. [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:04, 21 April 2015 (MDT)<br />
<br />
:::: There are several reasons why I would not do it that way:<br />
:::: - If I download the document and begin integrating it into the Wiki, it can no longer be a collaborative process. If I do that, I have to do every single one myself (nobody can help, sensibly, without being redundant), and there is really no good way to know which have been done already.<br />
:::: - Several of the Disch notes sections have had edits in the time since being pasted here, and all of these deserve an overview before being removed.<br />
:::: - I believe zeromus' addition of the Disch notes to the Wiki was overall a good thing, filling in content where it was missing at the temporary expense of redundancy.<br />
:::: - Simply reverting someone's changes without reviewing them treats them in bad faith.<br />
:::: "if there is a particular part you'd want me to review, just ask." Please review every deletion you make. That's what I am asking, and that was the project I had begun, myself. If you don't want to do this, please just leave it there. I will get to it eventually! I had started working on this carefully (but slowly). It will probably take me a few months if I do it alone, but I really don't appreciate someone coming in with sweeping deletions and making it difficult for me to try and attempt to finally make good on zeromus' good-faith effort to have the wiki improved by Disch's notes. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 10:48, 21 April 2015 (MDT)<br />
<br />
Oh because those HAVE HAD EDITS ?! :O<br />
<br />
Now everything makes even less sense. I give up! This wiki is a huge mess anyway and will always be. Collaborative work just doesn't work. My only regrets is to have worked so hard for the hardware page and the FDS page, when they are doomed to be in the little of this huge disorganized mess with no head and no tail. Any change I make is systematically criticized, even if I asked in the forums if it was ok to do it, and nobody reacts which I belive is "I'm ok with that", but after the change everytime screams like "Begalad you're doing it all wrong, revert those changes!" It's the fourth time there is an issue like that where changes I made in a lame attempt to make this wiki a slightly better place are refuted only AFTER I made them.<br />
<br />
By the way a great thing would be to report those edits to RHDN, so that at least a clean and up to date version of Dish' doccument lies somewhere (and that is on RHDN, not here).[[Special:Contributions/185.26.182.29|185.26.182.29]] 12:47, 21 April 2015 (MDT)<br />
:If consensus for large scale editing has been established in a topic on the forum, it would be a good idea to include the URL of this topic in the edit summary of each edit so that we know what you're doing. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 12:56, 21 April 2015 (MDT)<br />
<br />
:I can't complain about your changes before you make them, unless you tell us what your intentions are first. If you want to make large scale changes unannounced, yes, people will complain after the fact. When else would they complain? I think we want the same thing in the end (no more redundant Disch notes), but I am unhappy with the way you are doing it. I began several days ago a long term effort to do it carefully to make sure we aren't losing information as the Disch notes are removed, but suddenly you have come in to just bulldoze it to the ground, and this does bother me. This isn't collaboration, this is in effect just you having an edit war with zeromus with a 2 year delay. I don't know what argument you had about the FDS article, or what, but it's not at all relevant to the current discussion. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:13, 21 April 2015 (MDT)<br />
<br />
:Yeah, it really suck because we're making efforts and we get in the way of eachother. That's just how this wiki works and is doomed to work. As for the thread it's [http://forums.nesdev.org/viewtopic.php?f=14&t=12621 here], but it was in an abandoned state after one day. If I say "should we do that" and nobody react I assume nobody cares if I to do it. Well wrong assumption I guess. I was absolutely sure the Dish docs were untouched that is why I acted this way. However the edits from the are not lost because they're in the history logs. I'll track for them, and update new Dish docs to RHDN to apologize for this behaviour (so I don't have to deal with the wiki anymore but still repair what I have broken). I hope this is okay for everyone. It will take a few days, though.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:28, 21 April 2015 (MDT)<br />
<br />
::I reacted, and I started working on the problem. I didn't want to just revert your deletions because it would basically be an edit war if we don't talk about it first. Undoing a single revision I can explain in the comment summary, but doing many is kind of hostile. I know you spent a good amount of time (in good faith) making the edits, though zeromus also spent a good amount of time putting that stuff up in the first place. Both of you wanted to improve the wiki, and I'm trying to mediate this by keeping anything of value that was there. You don't need to revert anything yourself, at this point; I have been reviewing the changes, and keeping a list of deletions at [[User:Rainwarrior]], and I'll eventually get through them one by one as part of the ongoing project I started. I want to keep all the document links you added, for eaxmple, because those are good. As for updating RHDN, you can do that if you like, but I'm only concerned about the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:42, 21 April 2015 (MDT)<br />
<br />
== MMC5-internal RAM ==<br />
What is the logic in the ASIC that causes it to write zero if the PPU is not rendering? --[[User:Zzo38|Zzo38]] 01:51, 22 September 2012 (MDT)<br />
<br />
Another question about the ExRAM is, what happens when you try to read/write ExRAM nametables through the PPU registers, and if extended attribute mode is selected, what happens when reading/writing attribute tables using the PPU registers (when it isn't rendering the picture, and in any potentially random order)? --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 22:23, 24 February 2014 (MST)<br />
<br />
Yet another question : Is the ExRAM battery backed ? It would seem no, but technically the Battery is connected to the MMC5 so who knowns ? [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 04:38, 5 May 2014 (MDT)<br />
<br />
== Even more extended PRG RAM ==<br />
Parsimony of silicon strongly implies that the higher address lines (corresponding to the 0x78 bits of the register) are still driven for the registers from $5114 to $5116 even when RAM is selected, meaning >64KiB PRG-RAM would be usable when mapped to $8000-$DFFF.<br />
It's conceivable that these same bits of the register at $5113 (controlling PRG-RAM bank) are implemented, since they have to feed a multiplexer anyway.<br />
Something to test, maybe. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 23:34, 20 January 2014 (MST)<br />
<br />
== PRG Bankswitching ==<br />
The PRG bankswitching section was much better before the recent edits by Ben Bolt. In particular, I do not see why non-existing registers $5112 etc... are even mentioned at all. The current page is a huge mess and I don't see any new info that wasn't there before, except that it's now much less readable and non understandable.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 00:40, 26 November 2018 (MST)<br />
<br />
Also, this is not related to recent edits, but the info in this wiki clearly contradict Dish notes.<br />
<br />
Wiki says:<br />
<br />
''Mode 1 - Select a 16KB PRG ROM bank at $C000-$FFFF (pass through CPU A13 to PRG A13 instead of using bit 0)''<br />
''Mode 0 - Select a 32KB PRG ROM bank at $8000-$FFFF (pass through CPU A13 and A14 to PRG A13 and A14 instead of using bits 0 and 1)''<br />
<br />
Before the recent edits it said:<br />
<br />
''Mode 0 - Select a 32KB PRG ROM bank at $8000-$FFFF (ignore bottom 2 bits)''<br />
''Mode 1 - Select a 16KB PRG ROM bank at $C000-$FFFF (ignore bottom bit)''<br />
<br />
which is equivalent, but simpler to understand in a sowftware viewpoint.<br />
<br />
Dish however says:<br />
<br />
''Note that unlike most other mappers, these CHR pages are in *actual* sizes. IE: when in 4k mode, registers contain 4k page numbers. But when in 2k mode, register contain 2k page numbers.''<br />
<br />
Which is the oposite ! This was already contradictory before the recent edits but I didn't notice. So who's right, who's wrong ? At least Castlevania III uses 16k banks with MMC5 so this should be easy to figure out.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 08:50, 26 November 2018 (MST)<br />
<br />
: You'll note that the former comment is about PRG bankswitching, and Disch's comment is about CHR bankswitching. Both are true. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 13:29, 26 November 2018 (MST)<br />
<br />
:: Ah Okaaay... so the MMC5 did the shifting trick for it's CHR pages but not PRG pages where bigger sizes are used like usual by ignoring lower bits... that's very tricky indeed. This should probably be mentionned after the PRG bankswitching part is fixed up.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:56, 26 November 2018 (MST)<br />
<br />
OK I hope everything is fixed now, tried to present the information in a way that is simultaneously as concise and complete as possible.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 15:10, 21 December 2018 (MST)<br />
<br />
: Thanks for cleaning up my mess [[User:Bregalad|Bregalad]]. [[User:Ben Boldt|Ben Boldt]] ([[User talk:Ben Boldt|talk]]) 11:33, 1 January 2019 (MST)<br />
<br />
== iNES Mapper 5 page ==<br />
<br />
It is mentioned in a previous section here that Disch had his own version of this MMC5 page, in the "don't repeat yourself" section. Does anyone have a link to that or a backup? I would like to go back and make sure we have integrated everything from Disch properly. [[User:Ben Boldt|Ben Boldt]] ([[User talk:Ben Boldt|talk]]) 17:48, 3 August 2021 (UTC)<br />
:In case anybody's still interested, it's available at: https://www.romhacking.net/documents/362/ [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 14:05, 26 March 2024 (UTC)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=APU_DMC&diff=21673APU DMC2024-03-21T16:22:08Z<p>Bregalad: /* Pitch table */ There is no point in giving the fraction of cents, who aren't perceptible by the human ear. Instead give pitches for 1-byte, 17-byte and 33-byte loops.</p>
<hr />
<div>[[Category:APU]]<br />
<br />
The [[APU|NES APU's]] delta modulation channel (DMC) can output 1-bit [[wikipedia:Delta modulation|delta-encoded samples]] or can have its 7-bit counter directly loaded, allowing flexible manual sample playback.<br />
<br />
== Overview ==<br />
<br />
The DMC channel contains the following: memory reader, interrupt flag, sample buffer, [[APU Misc|timer]], output unit, 7-bit output level with up and down counter.<br />
<br />
<pre><br />
Timer<br />
|<br />
v<br />
Reader ---> Buffer ---> Shifter ---> Output level ---> (to the mixer)<br />
</pre><br />
<br />
{| class="wikitable"<br />
| '''$4010''' || <tt>IL--.RRRR</tt> || '''Flags and Rate''' (write)<br />
|-<br />
| bit 7 || <tt>I---.----</tt> || IRQ enabled flag. If clear, the interrupt flag is cleared.<br />
|-<br />
| bit 6 || <tt>-L--.----</tt> || Loop flag<br />
|-<br />
| bits 3-0 || <tt>----.RRRR</tt> || Rate index<br><br />
<!-- If you modify this table, keep the values comma-separated so they can be used without changes in a program --><br />
<pre><br />
Rate $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $A $B $C $D $E $F<br />
------------------------------------------------------------------------------<br />
NTSC 428, 380, 340, 320, 286, 254, 226, 214, 190, 160, 142, 128, 106, 84, 72, 54<br />
PAL 398, 354, 316, 298, 276, 236, 210, 198, 176, 148, 132, 118, 98, 78, 66, 50<br />
</pre><br />
<br />
The rate determines for how many CPU cycles happen between changes in the output level during automatic delta-encoded sample playback. For example, on NTSC (1.789773 MHz), a rate of 428 gives a frequency of 1789773/428 Hz = 4181.71 Hz. These periods are all even numbers because there are 2 CPU cycles in an APU cycle. A rate of 428 means the output level changes every 214 APU cycles.<br />
|-<br />
|colspan=3| &nbsp;<br />
|-<br />
| '''$4011''' || <tt>-DDD.DDDD</tt> || '''Direct load''' (write)<br />
|-<br />
| bits 6-0 || <tt>-DDD.DDDD</tt> || The DMC output level is set to D, an unsigned value. If the timer is outputting a clock at the same time, the output level is occasionally not changed properly.[http://forums.nesdev.org/viewtopic.php?p=104491#p104491]<br />
|-<br />
|colspan=3| &nbsp;<br />
|-<br />
| '''$4012''' || <tt>AAAA.AAAA</tt> || '''Sample address''' (write)<br />
|-<br />
| bits 7-0 || <tt>AAAA.AAAA</tt> || Sample address = <tt>%11AAAAAA.AA000000</tt> = <tt>$C000 + (A * 64)</tt><br />
|-<br />
|colspan=3| &nbsp;<br />
|-<br />
| '''$4013''' || <tt>LLLL.LLLL</tt> || '''Sample length''' (write)<br />
|-<br />
| style="white-space: nowrap;" | bits 7-0 || <tt>LLLL.LLLL</tt> || Sample length = <tt>%LLLL.LLLL0001</tt> = <tt>(L * 16) + 1 bytes</tt><br />
|}<br />
<br />
The output level is sent to the [[APU Mixer|mixer]] whether the channel is enabled or not. It is loaded with 0 on power-up, and can be updated by $4011 writes and delta-encoded sample playback.<br />
<br />
Automatic 1-bit [[wikipedia:Delta modulation|delta-encoded sample]] playback is carried out by a combination of three units. The ''memory reader'' fills the 8-bit ''sample buffer'' whenever it is emptied by the sample ''output unit''. The [[APU Status|status register]] is used to start and stop automatic sample playback.<br />
<br />
The '''sample buffer''' either holds a single 8-bit sample byte or is empty. It is filled by the reader and can only be emptied by the output unit; once loaded with a sample byte it will be played back.<br />
<br />
=== Pitch table ===<br />
<br />
{| class="wikitable"<br />
|-<br />
|<br />
| colspan="6" bgcolor = FFDDDD | NTSC<br />
| colspan="6" bgcolor = DDDDFF | PAL<br />
|-<br />
! $4010 || Period || Frequency || Note (raw) || Note (1-byte loop) || Note (17-byte loop) || Note (33-byte loop) || Period || Frequency || Note (raw) || Note (1-byte loop) || Note (17-byte loop) || Note (33-byte loop)<br />
|-<br />
| $0 <br />
| bgcolor=FFDDDD | $1AC || 4181.71 Hz || C-8 -2c || C-5 -2c || B-0 -7c || infrasound<br />
| bgcolor=DDDDFF | $18E || 4177.40 Hz || C-8 -4c || C-5 -4c || B-0 -9c || infrasound<br />
|-<br />
| $1<br />
| bgcolor=FFDDDD | $17C || 4709.93 Hz || D-8 +4c || C-5 +4c || C#1 -1c || infrasound<br />
| bgcolor=DDDDFF | $162 || 4696.63 Hz || D-8 -1c || D-5 -1c || C#1 -6c || infrasound<br />
|-<br />
| $2<br />
| bgcolor=FFDDDD | $154 || 5264.04 Hz || E-8 -3c || E-5 -3c || Eb1 -8c || infrasound<br />
| bgcolor=DDDDFF | $13C || 5261.41 Hz || E-8 -4c || E-5 -4c || Eb1 -9c || infrasound<br />
|-<br />
| $3<br />
| bgcolor=FFDDDD | $140 || 5593.04 Hz || F-8 +2c || F-5 +2c || E-1 -3c || E-0 +48c<br />
| bgcolor=DDDDFF | $12A || 5579.22 Hz || F-8 -3c || F-5 -3c || E-1 -8c || E-0 +44c<br />
|-<br />
| $4<br />
| bgcolor=FFDDDD | $11E || 6257.95 Hz || G-8 -4c || G-5 -4c || F#1 -9c || F#0 +43c<br />
| bgcolor=DDDDFF | $114 || 6023.94 Hz || G-8 -70c || G-5 -70c || F#1 -75c || F#0 -23c<br />
|-<br />
| $5<br />
| bgcolor=FFDDDD | $0FE || 7046.35 Hz || A-8 +2c || A-5 +2c || Ab1 -3c || Ab0 +48c<br />
| bgcolor=DDDDFF | $0EC || 7044.94 Hz || A-8 +1c || A-5 +1c || Ab1 -4c || Ab0 +48c<br />
|-<br />
| $6<br />
| bgcolor=FFDDDD | $0E2 || 7919.35 Hz || B-8 +4c || B-5 +4c || Bb1 -1c || Bb0 +50c<br />
| bgcolor=DDDDFF | $0D2 || 7917.18 Hz || B-8 +3c || B-5 +3c || Bb1 -2c || Bb0 +50c<br />
|-<br />
| $7<br />
| bgcolor=FFDDDD | $0D6 || 8363.42 Hz || C-9 -2c || C-6 -2c || B-1 -7c || B-0 +45c<br />
| bgcolor=DDDDFF | $0C6 || 8397.01 Hz || C-9 +5c || C-6 +5c || B-1 +0c || B-0 +52c<br />
|-<br />
| $8<br />
| bgcolor=FFDDDD | $0BE || 9419.86 Hz || D-9 +4c || D-6 +4c || C#2 -1c || C#1 +51c<br />
| bgcolor=DDDDFF | $0B0 || 9446.63 Hz || D-9 +9c || D-9 +9c || C#2 +4c || C#1 +56c<br />
|-<br />
| $9<br />
| bgcolor=FFDDDD | $0A0 || 11186.1 Hz || F-9 +2c || F-6 +2c || E-2 -3c || E-1 +48c<br />
| bgcolor=DDDDFF | $094 || 11233.8 Hz || F-9 +9c || F-6 +9c || E-2 +4c || E-1 +56c<br />
|-<br />
| $A<br />
| bgcolor=FFDDDD | $08E || 12604.0 Hz || G-9 +8c || G-6 +8c || F#2 +3c || F#1 +55c<br />
| bgcolor=DDDDFF | $084 || 12595.5 Hz || G-9 +7c || G-6 +7c || F#2 -2c || G-1 +54c<br />
|-<br />
| $B<br />
| bgcolor=FFDDDD | $080 || 13982.6 Hz || A-9 -12c || A-6 -12c || Ab2 -17c || Ab1 +35c<br />
| bgcolor=DDDDFF | $076 || 14089.9 Hz || A-9 +1c || A-6 +1c || Ab2 -4c || Ab1 +48c<br />
|-<br />
| $C<br />
| bgcolor=FFDDDD | $06A || 16884.6 Hz || C-10 +14c || C-7 +14c || B-2 +10c || B-1 +61c<br />
| bgcolor=DDDDFF | $062 || 16965.4 Hz || C-10 +23c || C-7 +23c || B-2 +18c || B-1 +69c<br />
|-<br />
| $D<br />
| bgcolor=FFDDDD | $054 || 21306.8 Hz || E-10 +17c || E-7 +17c || Eb3 +12c || Eb2 +64c<br />
| bgcolor=DDDDFF | $04E || 21315.5 Hz || E-10 +18c || E-7 +18c || Eb3 +13c || Eb2 +65c<br />
|-<br />
| $E<br />
| bgcolor=FFDDDD | $048 || 24858.0 Hz || G-10 -16c || G-7 -16c || F#3 -21c || F#2 +31c<br />
| bgcolor=DDDDFF | $042 || 25191.0 Hz || G-10 +7c || G-7 +7c || F#3 +2c || F#2 +54c<br />
|-<br />
| $F<br />
| bgcolor=FFDDDD | $036 || 33143.9 Hz || C-11 -18c || C-8 -18c || B-3 -23c || B-2 +29c<br />
| bgcolor=DDDDFF | $032 || 33252.1 Hz || C-11 -12c || C-8 -12c || B-3 -17c || B-2 +34c<br />
|}<br />
(Deviation from note is given in cents, which are defined as 1/100th of a semitone.)<br />
<br />
Note that on PAL systems, the pitches at $4 and $C appear to be incorrect with respect to their intended A-440 tuning scheme<ref>[http://forums.nesdev.org/viewtopic.php?p=94079#p94079 Forum post]: PAL DPCM frequency table contains 2 errors.</ref>.<br />
<br />
=== Memory reader ===<br />
<br />
When the sample buffer is emptied, the memory reader fills the sample buffer with the next byte from the currently playing sample. It has an address counter and a bytes remaining counter.<br />
<br />
When a sample is (re)started, the current address is set to the sample address, and bytes remaining is set to the sample length.<br />
<br />
Any time the sample buffer is in an empty state and bytes remaining is not zero (including just after a write to $4015 that enables the channel, regardless of where that write occurs relative to the bit counter mentioned below), the following occur:<br />
<br />
* The [[CPU]] is stalled for 1-4 CPU cycles to read a sample byte. The exact cycle count depends on many factors and is described in detail in the [[DMA]] article.<br />
* The sample buffer is filled with the next sample byte read from the current address, subject to whatever [[MMC|mapping hardware]] is present.<br />
* The address is incremented; if it exceeds $FFFF, it is wrapped around to $8000.<br />
* The bytes remaining counter is decremented; if it becomes zero and the loop flag is set, the sample is restarted (see above); otherwise, if the bytes remaining counter becomes zero and the IRQ enabled flag is set, the interrupt flag is set.<br />
<br />
At any time, if the interrupt flag is set, the [[CPU|CPU's IRQ line]] is ''continuously'' asserted until the interrupt flag is cleared.<br />
The processor will continue on from where it was stalled.<br />
<br />
=== Output unit ===<br />
<br />
The output unit continuously outputs a 7-bit value to the [[APU Mixer|mixer]]. It contains an 8-bit right shift register, a bits-remaining counter, a 7-bit output level (the same one that can be loaded directly via $4011), and a silence flag.<br />
<br />
The bits-remaining counter is updated whenever the [[APU Misc|timer]] outputs a clock, regardless of whether a sample is currently playing. When this counter reaches zero, we say that the output cycle ends. The DPCM unit can only transition from silent to playing at the end of an output cycle.<br />
<br />
When an output cycle ends, a new cycle is started as follows:<br />
* The bits-remaining counter is loaded with 8.<br />
* If the sample buffer is empty, then the silence flag is set; otherwise, the silence flag is cleared and the sample buffer is emptied into the shift register.<br />
<br />
When the timer outputs a clock, the following actions occur in order:<br />
# If the silence flag is clear, the output level changes based on bit 0 of the shift register. If the bit is 1, add 2; otherwise, subtract 2. But if adding or subtracting 2 would cause the output level to leave the 0-127 range, leave the output level unchanged. This means subtract 2 only if the current level is at least 2, or add 2 only if the current level is at most 125.<br />
# The right shift register is clocked.<br />
# As stated above, the bits-remaining counter is decremented. If it becomes zero, a new output cycle is started.<br />
<br />
''Nothing can interrupt a cycle; every cycle runs to completion before a new cycle is started.''<br />
<br />
== Conflict with controller and PPU read ==<br />
<br />
On the NTSC NES and Famicom, if a new sample byte is fetched from memory at the same time the program is reading the [[Standard controller|controller]] through $4016/4017, a conflict occurs corrupting the data read from the controller. Programs which use DPCM sample playback will normally use a redundant [[Controller Reading|controller read]] routine to work around this defect.<br />
<br />
A similar problem occurs when reading data from the PPU through $2007, or polling $2002 for vblank.<br />
<br />
=== Likely internal implementation of the read ===<br />
<br />
The following is speculation, and thus not necessarily 100% accurate, but it does accurately predict observed behavior.<br />
<br />
The 6502 cannot be pulled off of the bus normally. The 2A03 DMC gets around this by pulling RDY low internally. This causes the CPU to pause during the next read cycle, until RDY goes high again. The DMC unit holds RDY low for 4 cycles. The first three cycles it idles, as the CPU could have just started an interrupt cycle, and thus be writing for 3 consecutive cycles (and thus ignoring RDY). On the fourth cycle, the DMC unit drives the next sample address onto the address lines, and reads that byte from memory. It then drives RDY high again, and the CPU picks up where it left off.<br />
<br />
This matters because on NTSC NES and Famicom, it can interfere with the expected operation of any register where reads have a side effect: the controller registers ($4016 and $4017), reads of the PPU status register ($2002), and reads of VRAM/VROM data ($2007) if they happen to occur in the same cycle that the DMC unit pulls RDY low.<br />
<br />
For the controller registers, this can cause an extra rising clock edge to occur, and thus shift an extra bit out. For the others, the PPU will see multiple reads, which will cause extra increments of the address latches, or clear the vblank flag.<br />
<br />
This problem has been fixed on the 2A07 and PAL NES is exempt of this bug.<br />
<br />
== Usage of DMC for syncing to video ==<br />
<br />
DMC IRQs can be used for timed video operations. The following method was discussed on the forum in 2010.<ref>[http://forums.nesdev.org/viewtopic.php?t=6521 Forum thread]: DMC IRQ as a video timer.</ref><br />
<br />
=== Concept ===<br />
<br />
The NES hardware only has limited tools for syncing the code with video rendering. The VBlank NMI and sprite 0 hit are the only two reasonably reliable flags that can be used, so only 2 synchronizations per frame can be done easily. In addition, only the VBlank NMI can trigger an interrupt; the sprite 0 hit flag has to be polled, potentially wasting a lot of CPU cycles.<br />
<br />
However, the DMC channel can hypothetically be used for syncing with video instead of using it for sound. Unfortunately it's a bit complicated, but used correctly, it can function as a crude scanline counter, eliminating the need for an advanced mapper.<br />
<br />
The DMC's timing is completely separate from the video. The DMC's timer is always running, and samples can only start every 8 clock cycles. However, because the DMC's timer isn't synchronized to the PPU in any way, these 8-clock boundaries occur on different scanlines each frame.<br />
<br />
Here are the steps to achieve stable timing:<br />
<br />
* At a fixed point in video rendering (we'll use the start of vblank as an example), a dummy single-byte sample at rate $F is started. Due to a hardware quirk†, the sample needs to be started three times in a row like this:<br />
<br />
<pre><br />
sei<br />
lda #$10 <br />
sta $4015 <br />
sta $4015 <br />
sta $4015 <br />
cli<br />
</pre><br />
<br />
* The amount of cycles before a DMC IRQ happens is then measured (either using an actual IRQ, or by polling $4015).<br />
** At rate $F, there are 54 CPU cycles between clocks, so there are 432 CPU cycles (432 × 3 ÷ 341 = about 3.8 scanlines) between boundaries.<br />
* The main sample that will be used for the timing is then started (please refer to the table below to have sample lengths for various waiting times)<br />
* When the main IRQ happens, the measurement from before is retrieved, and a timing loop with variable delay is used. In order to synchronize with vblank, after a DMC IRQ we should wait 432 CPU cycles minus the time we measured.<br />
†'''Note:''' The hardware quirk mentioned above deals with how DMC IRQs are generated. Basically, the IRQ is generated when the last '''byte''' of the sample is '''read''', '''not''' when the last ''sample'' of the sample ''plays''. The sample buffer sometimes has enough time to empty itself between writes to $4015, meaning your next write to $4015 will trigger an immediate IRQ. Fortunately, writing to $4015 three times will avoid this issue.<br />
<br />
Still using vblank as an example, the measurement tells how far into the 8-clock boundary vblank occurred, and by delaying after a DMC IRQ, we perform a raster effect at the same point within the 8-clock boundary, aligning it with vblank. By performing this same method each frame, the raster effect will have a reasonably stable timing to it. As a bonus, since mostly using IRQs are being used, the CPU is free to do something else, instead of waiting in a timed loop.<br />
<br />
It's possible to use more than one IRQ per frame - but the ''measurement'' part needs to be done at the ''same time'' within each frame, before the usage of any IRQ.<br />
<br />
Only a single split-point per IRQ is possible, with the shortest IRQ being 3.8 scanlines. For split points closer than this amount, timed code has to be used.<br />
<br />
In order to remain silent, samples should be made up of all $00 bytes, and $00 should have been previously written to $4011. Otherwise, audio will unintentionally be created. This ''is'' a sound channel, after all.<br />
<br />
=== Timing table ===<br />
<br />
This table converts sample length in scanline length (all values are rounded to the higher integer).<br />
<br />
<pre><br />
NTSC Rate <br />
Length $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $a $b $c $d $e $f <br />
---------------------------------------------------------------------------------------------------- <br />
1-byte (8 bits) 31 27 24 23 21 18 16 16 14 12 10 10 8 6 6 4 <br />
17-byte (136 bits) ** ** ** ** ** ** ** ** 228 192 170 154 127 101 87 65 <br />
33-byte (264 bits) ** ** ** ** ** ** ** ** ** ** ** ** ** 196 168 126 <br />
49-byte (392 bits) ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** 187 <br />
<br />
PAL Rate <br />
Length $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $a $b $c $d $e $f <br />
---------------------------------------------------------------------------------------------------- <br />
1-byte (8 bits) 30 27 24 23 21 18 16 15 14 12 10 9 8 6 5 4 <br />
17-byte (136 bits) ** ** ** ** ** ** ** ** 225 189 169 151 126 100 85 64 <br />
33-byte (264 bits) ** ** ** ** ** ** ** ** ** ** ** ** ** 194 164 124 <br />
49-byte (392 bits) ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** 184<br />
</pre><br />
<br />
=== Number of scanlines to wait table ===<br />
<br />
This table gives the best sample length and frequency combinations for all possible scanlines interval to wait. They are best because they are where the CPU will have to kill the least time. However, it's still possible to use options to wait for fewer lines and kill more time during the interrupt before the video effect.<br />
<br />
Because a PAL interrupt will always happen about the same time or a bit sooner than a NTSC interrupt, the NTSC table will be used to set the "best" setting here :<br />
<br />
<pre><br />
Scanlines Best opt. for IRQ <br />
<br />
1-3 Timed code <br />
4-5 Length $0, rate $f <br />
6-7 Length $0, rate $d <br />
8-9 Length $0, rate $c <br />
10-11 Length $0, rate $a <br />
12-13 Length $0, rate $9 <br />
14-15 Length $0, rate $8 <br />
16-17 Length $0, rate $6 <br />
18-20 Length $0, rate $5 <br />
21-22 Length $0, rate $4 <br />
23 Length $0, rate $3 <br />
24-26 Length $0, rate $2 <br />
27-30 Length $0, rate $1 <br />
31-64 Length $0, rate $0 <br />
65-86 Length $1, rate $f <br />
87-100 Length $1, rate $e <br />
101-125 Length $1, rate $d <br />
126 Length $2, rate $f <br />
127-153 Length $1, rate $c <br />
154-167 Length $1, rate $b <br />
168-169 Length $2, rate $e <br />
170-186 Length $1, rate $a <br />
187-191 Length $3, rate $f <br />
192-195 Length $1, rate $9 <br />
196-227 Length $2, rate $d <br />
228-239 Length $1, rate $8<br />
</pre><br />
<br />
== References ==<br />
<references /></div>Bregaladhttps://www.nesdev.org/w/index.php?title=PPU_palettes&diff=21647PPU palettes2024-03-05T10:06:08Z<p>Bregalad: /* The background palette hack */ Direct access is more accurate than "hack" to describe this effect ~~~~</p>
<hr />
<div>The NES has a limited selection of color outputs. A 6-bit value in the palette memory area corresponds to one of 64 outputs. The [[Colour emphasis|emphasis]] bits of the [[PPUMASK]] register ($2001) provide an additional color modifier.<br />
<br />
For more information on how the colors are generated on an NTSC NES, see: [[NTSC video]]. For additional information on how the colors are generated on a PAL NES, see: [[PAL video]].<br />
<br />
== Memory Map ==<br />
The palette for the background runs from VRAM $3F00 to $3F0F; the palette for the sprites runs from $3F10 to $3F1F. Each color takes up one byte.<br />
<br />
{| class="wikitable"<br />
! Address || Purpose<br />
|-<br />
| $3F00 || Universal background color<br />
|-<br />
| $3F01-$3F03 || Background palette 0<br />
|-<br />
| $3F04 || Normally unused color 1<br />
|-<br />
| $3F05-$3F07 || Background palette 1<br />
|-<br />
| $3F08 || Normally unused color 2<br />
|-<br />
| $3F09-$3F0B || Background palette 2<br />
|-<br />
| $3F0C || Normally unused color 3<br />
|-<br />
| $3F0D-$3F0F || Background palette 3<br />
|-<br />
| $3F10 || Mirror of universal background color<br />
|-<br />
| $3F11-$3F13 || Sprite palette 0<br />
|-<br />
| $3F14 || Mirror of unused color 1<br />
|-<br />
| $3F15-$3F17 || Sprite palette 1<br />
|-<br />
| $3F18 || Mirror of unused color 2<br />
|-<br />
| $3F19-$3F1B || Sprite palette 2<br />
|-<br />
| $3F1C || Mirror of unused color 3<br />
|-<br />
| $3F1D-$3F1F || Sprite palette 3<br />
|}<br />
<br />
Each palette has three colors. Each 16x16 pixel area of the background can use the backdrop color and the three colors from one of the four background palettes. The choice of palette for each 16x16 pixel area is controlled by bits in the attribute table at the end of each [[PPU nametables|nametable]].<br />
Each sprite can use the three colors from one of the sprite palettes. The choice of palette is in attribute 2 of each sprite (see [[PPU OAM]]).<br />
<br />
Addresses $3F04/$3F08/$3F0C are not used by the PPU when normally rendering (since the pattern values that would otherwise select those cells select the backdrop color instead). They can still be shown using the background palette direct access, explained below.<br />
<br />
Addresses $3F10/$3F14/$3F18/$3F1C are mirrors of $3F00/$3F04/$3F08/$3F0C. Note that this goes for writing as well as reading.<br />
A symptom of not having implemented this correctly in an emulator is the sky being black in ''Super Mario Bros.'', which writes the backdrop color through $3F10.<br />
<br />
Thus, indices into the palette are formed as follows:<br />
43210<br />
|||||<br />
|||++- Pixel value from tile data<br />
|++--- Palette number from attribute table or OAM<br />
+----- Background/Sprite select<br />
As in some second-generation game consoles, values in the NES palette are based on [[wikipedia:HSL and HSV|hue and brightness]]:<br />
76543210<br />
||||||||<br />
||||++++- Hue (phase, determines NTSC/PAL chroma)<br />
||++----- Value (voltage, determines NTSC/PAL luma)<br />
++------- Unimplemented, reads back as 0<br />
Hue $0 is light gray, $1-$C are blue to red to green to cyan, $D is dark gray, and $E-$F are mirrors of $1D (black).<br />
<br />
It works this way because of the way colors are represented in a composite NTSC or PAL signal, with the phase of a color subcarrier controlling the hue. For details regarding signal generation and color decoding, see [[NTSC video]].<br />
<br />
The canonical code for "black" is $0F.<br />
<br />
The 2C03 RGB PPU used in the PlayChoice-10 and 2C05-99 in the Famicom Titler renders hue $D as black, not dark gray.<br />
The 2C04 PPUs used in many [[Vs. System]] arcade games have completely different palettes as a copy protection measure.<br />
<br />
== Palettes ==<br />
<br />
The 2C02 (NTSC) and 2C07 (PAL) PPU is used to generate an analog composite video signal. These were used in most home consoles.<br />
<br />
The 2C03, 2C04, and 2C05, on the other hand, all output analog red, green, blue, and sync (RGBS) signals. The sync signal contains horizontal and vertical sync pulses in the same format as an all-black composite signal.<br />
Each of the three video channels uses a 3-bit DAC driven by a look-up table in a 64x9-bit ROM inside the PPU.<br />
The look-up tables (one digit for each of red, green, and blue, in order) are given below.<br />
<br />
RGB PPUs were used mostly in arcade machines (e.g. [[Vs. System]], Playchoice 10), as well as the Sharp Famicom Titler.<br />
<br />
=== 2C02 ===<br />
The RF Famicom, AV Famicom, NES (both front- and top-loading), and the North American version of the Sharp Nintendo TV use the 2C02 PPU.<br />
Unlike some other consoles' video circuits, the 2C02 does not generate RGB video and then encode that to composite.<br />
Instead it generates [[NTSC video]] directly in the composite domain, decoded by the television receiver into RGB to drive its picture tube.<br />
<br />
{{mbox<br />
| type = warning<br />
| text = <font size=+1>Do not use color $0D. It results in a "blacker than black" signal that may cause problems for some TVs.</font><br />
<hr><br />
Further details on $0D and its effects can be found [[Color_$0D_games|here.]]}}<br />
<br />
Most emulators can use a predefined palette, such as one commonly stored in common [[.pal]] format, in which each triplet represents the sRGB color that results from decoding a large flat area with a given palette value.<br />
<br />
See [[NTSC_video#Composite_decoding|this page]] for more details on a general algorithm to decode a PPU composite signal to color RGB.<br />
<br />
The following palette was generated using [https://github.com/Gumball2415/palgen-persune Persune's palette generator @v0.12.0] with the following arguments: <code>palgen-persune.py -phs -5.0 -o 2C02G -f ".txt MediaWiki"</code><br />
<br />
{|class="wikitable"<br />
|-<br />
|style="border:0px;background-color:#626262;width:32px;height:32px;color:#fff;text-align:center"|$00<br />
|style="border:0px;background-color:#001FB2;width:32px;height:32px;color:#fff;text-align:center"|$01<br />
|style="border:0px;background-color:#2404C8;width:32px;height:32px;color:#fff;text-align:center"|$02<br />
|style="border:0px;background-color:#5200B2;width:32px;height:32px;color:#fff;text-align:center"|$03<br />
|style="border:0px;background-color:#730076;width:32px;height:32px;color:#fff;text-align:center"|$04<br />
|style="border:0px;background-color:#800024;width:32px;height:32px;color:#fff;text-align:center"|$05<br />
|style="border:0px;background-color:#730B00;width:32px;height:32px;color:#fff;text-align:center"|$06<br />
|style="border:0px;background-color:#522800;width:32px;height:32px;color:#fff;text-align:center"|$07<br />
|style="border:0px;background-color:#244400;width:32px;height:32px;color:#fff;text-align:center"|$08<br />
|style="border:0px;background-color:#005700;width:32px;height:32px;color:#fff;text-align:center"|$09<br />
|style="border:0px;background-color:#005C00;width:32px;height:32px;color:#fff;text-align:center"|$0A<br />
|style="border:0px;background-color:#005324;width:32px;height:32px;color:#fff;text-align:center"|$0B<br />
|style="border:0px;background-color:#003C76;width:32px;height:32px;color:#fff;text-align:center"|$0C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|[[Color_$0D_games#Effects|<s style="color:red">$0D</s>]]<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$0E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$0F<br />
|-<br />
|style="border:0px;background-color:#ABABAB;width:32px;height:32px;color:#000;text-align:center"|$10<br />
|style="border:0px;background-color:#0D57FF;width:32px;height:32px;color:#fff;text-align:center"|$11<br />
|style="border:0px;background-color:#4B30FF;width:32px;height:32px;color:#fff;text-align:center"|$12<br />
|style="border:0px;background-color:#8A13FF;width:32px;height:32px;color:#fff;text-align:center"|$13<br />
|style="border:0px;background-color:#BC08D6;width:32px;height:32px;color:#fff;text-align:center"|$14<br />
|style="border:0px;background-color:#D21269;width:32px;height:32px;color:#fff;text-align:center"|$15<br />
|style="border:0px;background-color:#C72E00;width:32px;height:32px;color:#fff;text-align:center"|$16<br />
|style="border:0px;background-color:#9D5400;width:32px;height:32px;color:#fff;text-align:center"|$17<br />
|style="border:0px;background-color:#607B00;width:32px;height:32px;color:#fff;text-align:center"|$18<br />
|style="border:0px;background-color:#209800;width:32px;height:32px;color:#fff;text-align:center"|$19<br />
|style="border:0px;background-color:#00A300;width:32px;height:32px;color:#fff;text-align:center"|$1A<br />
|style="border:0px;background-color:#009942;width:32px;height:32px;color:#fff;text-align:center"|$1B<br />
|style="border:0px;background-color:#007DB4;width:32px;height:32px;color:#fff;text-align:center"|$1C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1F<br />
|-<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|$20<br />
|style="border:0px;background-color:#53AEFF;width:32px;height:32px;color:#000;text-align:center"|$21<br />
|style="border:0px;background-color:#9085FF;width:32px;height:32px;color:#000;text-align:center"|$22<br />
|style="border:0px;background-color:#D365FF;width:32px;height:32px;color:#000;text-align:center"|$23<br />
|style="border:0px;background-color:#FF57FF;width:32px;height:32px;color:#000;text-align:center"|$24<br />
|style="border:0px;background-color:#FF5DCF;width:32px;height:32px;color:#000;text-align:center"|$25<br />
|style="border:0px;background-color:#FF7757;width:32px;height:32px;color:#000;text-align:center"|$26<br />
|style="border:0px;background-color:#FA9E00;width:32px;height:32px;color:#000;text-align:center"|$27<br />
|style="border:0px;background-color:#BDC700;width:32px;height:32px;color:#000;text-align:center"|$28<br />
|style="border:0px;background-color:#7AE700;width:32px;height:32px;color:#000;text-align:center"|$29<br />
|style="border:0px;background-color:#43F611;width:32px;height:32px;color:#000;text-align:center"|$2A<br />
|style="border:0px;background-color:#26EF7E;width:32px;height:32px;color:#000;text-align:center"|$2B<br />
|style="border:0px;background-color:#2CD5F6;width:32px;height:32px;color:#000;text-align:center"|$2C<br />
|style="border:0px;background-color:#4E4E4E;width:32px;height:32px;color:#fff;text-align:center"|$2D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$2E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$2F<br />
|-<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|$30<br />
|style="border:0px;background-color:#B6E1FF;width:32px;height:32px;color:#000;text-align:center"|$31<br />
|style="border:0px;background-color:#CED1FF;width:32px;height:32px;color:#000;text-align:center"|$32<br />
|style="border:0px;background-color:#E9C3FF;width:32px;height:32px;color:#000;text-align:center"|$33<br />
|style="border:0px;background-color:#FFBCFF;width:32px;height:32px;color:#000;text-align:center"|$34<br />
|style="border:0px;background-color:#FFBDF4;width:32px;height:32px;color:#000;text-align:center"|$35<br />
|style="border:0px;background-color:#FFC6C3;width:32px;height:32px;color:#000;text-align:center"|$36<br />
|style="border:0px;background-color:#FFD59A;width:32px;height:32px;color:#000;text-align:center"|$37<br />
|style="border:0px;background-color:#E9E681;width:32px;height:32px;color:#000;text-align:center"|$38<br />
|style="border:0px;background-color:#CEF481;width:32px;height:32px;color:#000;text-align:center"|$39<br />
|style="border:0px;background-color:#B6FB9A;width:32px;height:32px;color:#000;text-align:center"|$3A<br />
|style="border:0px;background-color:#A9FAC3;width:32px;height:32px;color:#000;text-align:center"|$3B<br />
|style="border:0px;background-color:#A9F0F4;width:32px;height:32px;color:#000;text-align:center"|$3C<br />
|style="border:0px;background-color:#B8B8B8;width:32px;height:32px;color:#000;text-align:center"|$3D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$3E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$3F<br />
|}<br />
<br />
Other tools for generating a palette include [http://bisqwit.iki.fi/utils/nespalette.php one by Bisqwit] and [http://drag.wootest.net/misc/palgen.html one by Drag].<br />
These simulate generating a large area of one flat color and then decoding that with the adjustment knobs set to various settings.<br />
<br />
=== 2C07 ===<br />
<br />
The PAL PPU (2C07) generates a composite [[PAL video]] signal, which has a -15 degree hue shift relative to the 2C02 due to a different colorburst reference phase generated by the PPU ($x7 rather than $x8), in addition to the PAL colorburst phase being defined as -U ± 45 degrees.<br />
<br />
The following palette was generated using [https://github.com/Gumball2415/palgen-persune Persune's palette generator @v0.12.0] with the following arguments: <code>palgen-persune.py -ppu "2C07" -o 2C07 -f ".txt MediaWiki"</code><br />
<br />
{|class="wikitable"<br />
|-<br />
|style="border:0px;background-color:#626262;width:32px;height:32px;color:#fff;text-align:center"|$00<br />
|style="border:0px;background-color:#002E98;width:32px;height:32px;color:#fff;text-align:center"|$01<br />
|style="border:0px;background-color:#0C11C2;width:32px;height:32px;color:#fff;text-align:center"|$02<br />
|style="border:0px;background-color:#3B00C2;width:32px;height:32px;color:#fff;text-align:center"|$03<br />
|style="border:0px;background-color:#650098;width:32px;height:32px;color:#fff;text-align:center"|$04<br />
|style="border:0px;background-color:#7D004E;width:32px;height:32px;color:#fff;text-align:center"|$05<br />
|style="border:0px;background-color:#7D0000;width:32px;height:32px;color:#fff;text-align:center"|$06<br />
|style="border:0px;background-color:#651900;width:32px;height:32px;color:#fff;text-align:center"|$07<br />
|style="border:0px;background-color:#3B3600;width:32px;height:32px;color:#fff;text-align:center"|$08<br />
|style="border:0px;background-color:#0C4F00;width:32px;height:32px;color:#fff;text-align:center"|$09<br />
|style="border:0px;background-color:#005B00;width:32px;height:32px;color:#fff;text-align:center"|$0A<br />
|style="border:0px;background-color:#005900;width:32px;height:32px;color:#fff;text-align:center"|$0B<br />
|style="border:0px;background-color:#00494E;width:32px;height:32px;color:#fff;text-align:center"|$0C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|[[Color_$0D_games#Effects|<s style="color:red">$0D</s>]]<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$0E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$0F<br />
|-<br />
|style="border:0px;background-color:#ABABAB;width:32px;height:32px;color:#000;text-align:center"|$10<br />
|style="border:0px;background-color:#0064F4;width:32px;height:32px;color:#fff;text-align:center"|$11<br />
|style="border:0px;background-color:#353CFF;width:32px;height:32px;color:#fff;text-align:center"|$12<br />
|style="border:0px;background-color:#761BFF;width:32px;height:32px;color:#fff;text-align:center"|$13<br />
|style="border:0px;background-color:#AE0AF4;width:32px;height:32px;color:#fff;text-align:center"|$14<br />
|style="border:0px;background-color:#CF0C8F;width:32px;height:32px;color:#fff;text-align:center"|$15<br />
|style="border:0px;background-color:#CF231C;width:32px;height:32px;color:#fff;text-align:center"|$16<br />
|style="border:0px;background-color:#AE4700;width:32px;height:32px;color:#fff;text-align:center"|$17<br />
|style="border:0px;background-color:#766F00;width:32px;height:32px;color:#fff;text-align:center"|$18<br />
|style="border:0px;background-color:#359000;width:32px;height:32px;color:#fff;text-align:center"|$19<br />
|style="border:0px;background-color:#00A100;width:32px;height:32px;color:#fff;text-align:center"|$1A<br />
|style="border:0px;background-color:#009E1C;width:32px;height:32px;color:#fff;text-align:center"|$1B<br />
|style="border:0px;background-color:#00888F;width:32px;height:32px;color:#fff;text-align:center"|$1C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1F<br />
|-<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|$20<br />
|style="border:0px;background-color:#4AB5FF;width:32px;height:32px;color:#000;text-align:center"|$21<br />
|style="border:0px;background-color:#858CFF;width:32px;height:32px;color:#000;text-align:center"|$22<br />
|style="border:0px;background-color:#C86AFF;width:32px;height:32px;color:#000;text-align:center"|$23<br />
|style="border:0px;background-color:#FF58FF;width:32px;height:32px;color:#000;text-align:center"|$24<br />
|style="border:0px;background-color:#FF5BE2;width:32px;height:32px;color:#000;text-align:center"|$25<br />
|style="border:0px;background-color:#FF726A;width:32px;height:32px;color:#000;text-align:center"|$26<br />
|style="border:0px;background-color:#FF9702;width:32px;height:32px;color:#000;text-align:center"|$27<br />
|style="border:0px;background-color:#C8C100;width:32px;height:32px;color:#000;text-align:center"|$28<br />
|style="border:0px;background-color:#85E300;width:32px;height:32px;color:#000;text-align:center"|$29<br />
|style="border:0px;background-color:#4AF502;width:32px;height:32px;color:#000;text-align:center"|$2A<br />
|style="border:0px;background-color:#29F26A;width:32px;height:32px;color:#000;text-align:center"|$2B<br />
|style="border:0px;background-color:#29DBE2;width:32px;height:32px;color:#000;text-align:center"|$2C<br />
|style="border:0px;background-color:#4E4E4E;width:32px;height:32px;color:#fff;text-align:center"|$2D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$2E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$2F<br />
|-<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|$30<br />
|style="border:0px;background-color:#B6E1FF;width:32px;height:32px;color:#000;text-align:center"|$31<br />
|style="border:0px;background-color:#CED1FF;width:32px;height:32px;color:#000;text-align:center"|$32<br />
|style="border:0px;background-color:#E9C3FF;width:32px;height:32px;color:#000;text-align:center"|$33<br />
|style="border:0px;background-color:#FFBCFF;width:32px;height:32px;color:#000;text-align:center"|$34<br />
|style="border:0px;background-color:#FFBDF4;width:32px;height:32px;color:#000;text-align:center"|$35<br />
|style="border:0px;background-color:#FFC6C3;width:32px;height:32px;color:#000;text-align:center"|$36<br />
|style="border:0px;background-color:#FFD59A;width:32px;height:32px;color:#000;text-align:center"|$37<br />
|style="border:0px;background-color:#E9E681;width:32px;height:32px;color:#000;text-align:center"|$38<br />
|style="border:0px;background-color:#CEF481;width:32px;height:32px;color:#000;text-align:center"|$39<br />
|style="border:0px;background-color:#B6FB9A;width:32px;height:32px;color:#000;text-align:center"|$3A<br />
|style="border:0px;background-color:#A9FAC3;width:32px;height:32px;color:#000;text-align:center"|$3B<br />
|style="border:0px;background-color:#A9F0F4;width:32px;height:32px;color:#000;text-align:center"|$3C<br />
|style="border:0px;background-color:#B8B8B8;width:32px;height:32px;color:#000;text-align:center"|$3D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$3E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$3F<br />
|}<br />
<br />
=== 2C03 and 2C05 ===<br />
This palette is intentionally similar to the NES's standard palette, but notably is missing the greys in entries $2D and $3D.<br />
The 2C03 is used in ''Vs. Duck Hunt'', ''Vs. Tennis'', all PlayChoice games, and the Sharp C1 (Famicom TV).<br />
The 2C05 is used in some later Vs. games as a copy protection measure. A variant of the 2C05 without copy protection measures is present in the Sharp Famicom Titler, albeit with adjustments to the output (see below).<br />
Both have historically been used in RGB mods for the NES, as a circuit implementing <code>A0' = A0 xor (A1 nor A2)</code> can swap PPUCTRL and PPUMASK to make a 2C05 behave as a 2C03.<br />
<br />
The formula for mapping the DAC integer channel value to 8-bit per channel color is <code>C = 255 * DAC / 7</code>.<br />
<br />
{|class="wikitable"<br />
|-<br />
! style="text-align:center"|<br />
! style="text-align:center"|$x0<br />
! style="text-align:center"|$x1<br />
! style="text-align:center"|$x2<br />
! style="text-align:center"|$x3<br />
! style="text-align:center"|$x4<br />
! style="text-align:center"|$x5<br />
! style="text-align:center"|$x6<br />
! style="text-align:center"|$x7<br />
! style="text-align:center"|$x8<br />
! style="text-align:center"|$x9<br />
! style="text-align:center"|$xA<br />
! style="text-align:center"|$xB<br />
! style="text-align:center"|$xC<br />
! style="text-align:center"|$xD<br />
! style="text-align:center"|$xE<br />
! style="text-align:center"|$xF<br />
|-<br />
! style="text-align:center"|$0x<br />
|style="border:0px;background-color:#6D6D6D;width:32px;height:32px;color:#fff;text-align:center"|333<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|014<br />
|style="border:0px;background-color:#0000DA;width:32px;height:32px;color:#fff;text-align:center"|006<br />
|style="border:0px;background-color:#6D48DA;width:32px;height:32px;color:#fff;text-align:center"|326<br />
|style="border:0px;background-color:#91006D;width:32px;height:32px;color:#fff;text-align:center"|403<br />
|style="border:0px;background-color:#B6006D;width:32px;height:32px;color:#fff;text-align:center"|503<br />
|style="border:0px;background-color:#B62400;width:32px;height:32px;color:#fff;text-align:center"|510<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|420<br />
|style="border:0px;background-color:#6D4800;width:32px;height:32px;color:#fff;text-align:center"|320<br />
|style="border:0px;background-color:#244800;width:32px;height:32px;color:#fff;text-align:center"|120<br />
|style="border:0px;background-color:#006D24;width:32px;height:32px;color:#fff;text-align:center"|031<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|022<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|-<br />
! style="text-align:center"|$1x<br />
|style="border:0px;background-color:#B6B6B6;width:32px;height:32px;color:#000;text-align:center"|555<br />
|style="border:0px;background-color:#006DDA;width:32px;height:32px;color:#fff;text-align:center"|036<br />
|style="border:0px;background-color:#0048FF;width:32px;height:32px;color:#fff;text-align:center"|027<br />
|style="border:0px;background-color:#9100FF;width:32px;height:32px;color:#fff;text-align:center"|407<br />
|style="border:0px;background-color:#B600FF;width:32px;height:32px;color:#fff;text-align:center"|507<br />
|style="border:0px;background-color:#FF0091;width:32px;height:32px;color:#fff;text-align:center"|704<br />
|style="border:0px;background-color:#FF0000;width:32px;height:32px;color:#fff;text-align:center"|700<br />
|style="border:0px;background-color:#DA6D00;width:32px;height:32px;color:#000;text-align:center"|630<br />
|style="border:0px;background-color:#916D00;width:32px;height:32px;color:#fff;text-align:center"|430<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|140<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#00B66D;width:32px;height:32px;color:#fff;text-align:center"|053<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|044<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|-<br />
! style="text-align:center"|$2x<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#6DB6FF;width:32px;height:32px;color:#000;text-align:center"|357<br />
|style="border:0px;background-color:#9191FF;width:32px;height:32px;color:#000;text-align:center"|447<br />
|style="border:0px;background-color:#DA6DFF;width:32px;height:32px;color:#000;text-align:center"|637<br />
|style="border:0px;background-color:#FF00FF;width:32px;height:32px;color:#fff;text-align:center"|707<br />
|style="border:0px;background-color:#FF6DFF;width:32px;height:32px;color:#000;text-align:center"|737<br />
|style="border:0px;background-color:#FF9100;width:32px;height:32px;color:#000;text-align:center"|740<br />
|style="border:0px;background-color:#FFB600;width:32px;height:32px;color:#000;text-align:center"|750<br />
|style="border:0px;background-color:#DADA00;width:32px;height:32px;color:#000;text-align:center"|660<br />
|style="border:0px;background-color:#6DDA00;width:32px;height:32px;color:#000;text-align:center"|360<br />
|style="border:0px;background-color:#00FF00;width:32px;height:32px;color:#000;text-align:center"|070<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#00FFFF;width:32px;height:32px;color:#000;text-align:center"|077<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#777;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|-<br />
! style="text-align:center"|$3x<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#B6DAFF;width:32px;height:32px;color:#000;text-align:center"|567<br />
|style="border:0px;background-color:#DAB6FF;width:32px;height:32px;color:#000;text-align:center"|657<br />
|style="border:0px;background-color:#FFB6FF;width:32px;height:32px;color:#000;text-align:center"|757<br />
|style="border:0px;background-color:#FF91FF;width:32px;height:32px;color:#000;text-align:center"|747<br />
|style="border:0px;background-color:#FFB6B6;width:32px;height:32px;color:#000;text-align:center"|755<br />
|style="border:0px;background-color:#FFDA91;width:32px;height:32px;color:#000;text-align:center"|764<br />
|style="border:0px;background-color:#FFFF48;width:32px;height:32px;color:#000;text-align:center"|772<br />
|style="border:0px;background-color:#FFFF6D;width:32px;height:32px;color:#000;text-align:center"|773<br />
|style="border:0px;background-color:#B6FF48;width:32px;height:32px;color:#000;text-align:center"|572<br />
|style="border:0px;background-color:#91FF6D;width:32px;height:32px;color:#000;text-align:center"|473<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#91DAFF;width:32px;height:32px;color:#000;text-align:center"|467<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#777;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|}<br />
<br />
Note that some of the colors are duplicates: $0B and $1A = 040, $2B and $3B = 276.<br />
<br />
Monochrome works the same as the 2C02 (consistent across '''all''' RGB PPUs), but unlike the 2C02, emphasis on the RGB chips works differently; rather than "darkening" the specific color chosen, it sets the corresponding channel to full brightness instead.<br />
<br />
=== 2C05-99 ===<br />
<br />
The Sharp Famicom Titler (AN-510) contains a RC2C05-99 PPU, whose RGB output is fed into a X0858CE "encoder" chip. This chip handles the conversion from RGB(S) into Composite, and S-Video. In the process, it seems to also desaturate the output palette by encoding YIQ, but with a 0.5 gain on the Q channel (<code>Q = Q * 0.5</code>). Otherwise, the raw internal palette of the 2C05-99 PPU itself is believed to be identical to that of the 2C03. Due to technological limitations with video overlay (at the time), this was likely done in an attempt to make the RGB palette resemble its composite versions, as a standard 2C02 could not be used.<br />
<br />
{|class="wikitable"<br />
|-<br />
! style="text-align:center"|<br />
! style="text-align:center"|$x0<br />
! style="text-align:center"|$x1<br />
! style="text-align:center"|$x2<br />
! style="text-align:center"|$x3<br />
! style="text-align:center"|$x4<br />
! style="text-align:center"|$x5<br />
! style="text-align:center"|$x6<br />
! style="text-align:center"|$x7<br />
! style="text-align:center"|$x8<br />
! style="text-align:center"|$x9<br />
! style="text-align:center"|$xA<br />
! style="text-align:center"|$xB<br />
! style="text-align:center"|$xC<br />
! style="text-align:center"|$xD<br />
! style="text-align:center"|$xE<br />
! style="text-align:center"|$xF<br />
|-<br />
! style="text-align:center"|$0x<br />
|style="border:0px;background-color:#86858A;width:32px;height:32px;color:#fff;text-align:center"|$00<br />
|style="border:0px;background-color:#16317D;width:32px;height:32px;color:#fff;text-align:center"|$01<br />
|style="border:0px;background-color:#0B0995;width:32px;height:32px;color:#fff;text-align:center"|$02<br />
|style="border:0px;background-color:#8575C3;width:32px;height:32px;color:#fff;text-align:center"|$03<br />
|style="border:0px;background-color:#7E2F57;width:32px;height:32px;color:#fff;text-align:center"|$04<br />
|style="border:0px;background-color:#923457;width:32px;height:32px;color:#fff;text-align:center"|$05<br />
|style="border:0px;background-color:#98591C;width:32px;height:32px;color:#fff;text-align:center"|$06<br />
|style="border:0px;background-color:#896B27;width:32px;height:32px;color:#fff;text-align:center"|$07<br />
|style="border:0px;background-color:#605117;width:32px;height:32px;color:#fff;text-align:center"|$08<br />
|style="border:0px;background-color:#2C4013;width:32px;height:32px;color:#fff;text-align:center"|$09<br />
|style="border:0px;background-color:#155543;width:32px;height:32px;color:#fff;text-align:center"|$0A<br />
|style="border:0px;background-color:#1A6B29;width:32px;height:32px;color:#fff;text-align:center"|$0B<br />
|style="border:0px;background-color:#0C3C4D;width:32px;height:32px;color:#fff;text-align:center"|$0C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$0D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$0E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$0F<br />
|-<br />
! style="text-align:center"|$1x<br />
|style="border:0px;background-color:#CCCED2;width:32px;height:32px;color:#000;text-align:center"|$10<br />
|style="border:0px;background-color:#2768BB;width:32px;height:32px;color:#fff;text-align:center"|$11<br />
|style="border:0px;background-color:#1E4FC5;width:32px;height:32px;color:#fff;text-align:center"|$12<br />
|style="border:0px;background-color:#7C30AF;width:32px;height:32px;color:#fff;text-align:center"|$13<br />
|style="border:0px;background-color:#9638B2;width:32px;height:32px;color:#fff;text-align:center"|$14<br />
|style="border:0px;background-color:#BE4172;width:32px;height:32px;color:#fff;text-align:center"|$15<br />
|style="border:0px;background-color:#B13305;width:32px;height:32px;color:#fff;text-align:center"|$16<br />
|style="border:0px;background-color:#C09035;width:32px;height:32px;color:#fff;text-align:center"|$17<br />
|style="border:0px;background-color:#8C792D;width:32px;height:32px;color:#fff;text-align:center"|$18<br />
|style="border:0px;background-color:#497B32;width:32px;height:32px;color:#fff;text-align:center"|$19<br />
|style="border:0px;background-color:#1D6C2A;width:32px;height:32px;color:#fff;text-align:center"|$1A<br />
|style="border:0px;background-color:#31938A;width:32px;height:32px;color:#fff;text-align:center"|$1B<br />
|style="border:0px;background-color:#2D7C9A;width:32px;height:32px;color:#fff;text-align:center"|$1C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1F<br />
|-<br />
! style="text-align:center"|$2x<br />
|style="border:0px;background-color:#FDFFFF;width:32px;height:32px;color:#000;text-align:center"|$20<br />
|style="border:0px;background-color:#96BDEF;width:32px;height:32px;color:#000;text-align:center"|$21<br />
|style="border:0px;background-color:#A2A8E6;width:32px;height:32px;color:#000;text-align:center"|$22<br />
|style="border:0px;background-color:#CE9FE0;width:32px;height:32px;color:#000;text-align:center"|$23<br />
|style="border:0px;background-color:#BF43B3;width:32px;height:32px;color:#fff;text-align:center"|$24<br />
|style="border:0px;background-color:#E6A7E5;width:32px;height:32px;color:#000;text-align:center"|$25<br />
|style="border:0px;background-color:#DCAB41;width:32px;height:32px;color:#000;text-align:center"|$26<br />
|style="border:0px;background-color:#E7C54B;width:32px;height:32px;color:#000;text-align:center"|$27<br />
|style="border:0px;background-color:#DFD85E;width:32px;height:32px;color:#000;text-align:center"|$28<br />
|style="border:0px;background-color:#92C150;width:32px;height:32px;color:#000;text-align:center"|$29<br />
|style="border:0px;background-color:#3FBB4A;width:32px;height:32px;color:#000;text-align:center"|$2A<br />
|style="border:0px;background-color:#96EAF2;width:32px;height:32px;color:#000;text-align:center"|$2B<br />
|style="border:0px;background-color:#53D8FD;width:32px;height:32px;color:#000;text-align:center"|$2C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#777;text-align:center"|$2D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$2E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$2F<br />
|-<br />
! style="text-align:center"|$3x<br />
|style="border:0px;background-color:#FDFFFF;width:32px;height:32px;color:#000;text-align:center"|$30<br />
|style="border:0px;background-color:#C7DFFA;width:32px;height:32px;color:#000;text-align:center"|$31<br />
|style="border:0px;background-color:#DACDF2;width:32px;height:32px;color:#000;text-align:center"|$32<br />
|style="border:0px;background-color:#F5D6F8;width:32px;height:32px;color:#000;text-align:center"|$33<br />
|style="border:0px;background-color:#EABCED;width:32px;height:32px;color:#000;text-align:center"|$34<br />
|style="border:0px;background-color:#EED1CA;width:32px;height:32px;color:#000;text-align:center"|$35<br />
|style="border:0px;background-color:#F5E7BC;width:32px;height:32px;color:#000;text-align:center"|$36<br />
|style="border:0px;background-color:#FCFB9C;width:32px;height:32px;color:#000;text-align:center"|$37<br />
|style="border:0px;background-color:#FFFFC0;width:32px;height:32px;color:#000;text-align:center"|$38<br />
|style="border:0px;background-color:#D8F4A2;width:32px;height:32px;color:#000;text-align:center"|$39<br />
|style="border:0px;background-color:#C2F0B5;width:32px;height:32px;color:#000;text-align:center"|$3A<br />
|style="border:0px;background-color:#96EAF2;width:32px;height:32px;color:#000;text-align:center"|$3B<br />
|style="border:0px;background-color:#BFE2FF;width:32px;height:32px;color:#000;text-align:center"|$3C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#777;text-align:center"|$3D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$3E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$3F<br />
|}<br />
<br />
=== 2C04 ===<br />
All four 2C04 PPUs contain the same master palette, but in different permutations. It's almost a superset of the 2C03/5 palette, adding four greys, six other colors, and making the bright yellow more pure.<br />
<br />
Much like the 2C03 and 2C02, using the greyscale bit in [[PPUMASK]] will remap the palette by index, not by color. This means that with the scrambled palettes, each row will remap to the colors in the $0X column for that 2C04 version.<br />
<br />
Visualization tool: [https://www.nesdev.org/rgbppu/ RGB PPU Palette Converter]<br />
<br />
'''No version of the 2C04 was ever made with the below ordering''', but it shows the similarity to the 2C03:<br />
{|class="wikitable"<br />
|-<br />
|style="border:0px;background-color:#6D6D6D;width:32px;height:32px;color:#fff;text-align:center"|333<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|014<br />
|style="border:0px;background-color:#0000DA;width:32px;height:32px;color:#fff;text-align:center"|006<br />
|style="border:0px;background-color:#6D48DA;width:32px;height:32px;color:#fff;text-align:center"|326<br />
|style="border:0px;background-color:#91006D;width:32px;height:32px;color:#fff;text-align:center"|403<br />
|style="border:0px;background-color:#B6006D;width:32px;height:32px;color:#fff;text-align:center"|503<br />
|style="border:0px;background-color:#B62400;width:32px;height:32px;color:#fff;text-align:center"|510<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|420<br />
|style="border:0px;background-color:#6D4800;width:32px;height:32px;color:#fff;text-align:center"|320<br />
|style="border:0px;background-color:#244800;width:32px;height:32px;color:#fff;text-align:center"|120<br />
|style="border:0px;background-color:#006D24;width:32px;height:32px;color:#fff;text-align:center"|031<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|022<br />
|style="border:0px;background-color:#242424;width:32px;height:32px;color:#fff;text-align:center"|111<br />
|style="border:0px;background-color:#00006D;width:32px;height:32px;color:#fff;text-align:center"|003<br />
|style="border:0px;background-color:#004800;width:32px;height:32px;color:#fff;text-align:center"|020<br />
|-<br />
|style="border:0px;background-color:#B6B6B6;width:32px;height:32px;color:#000;text-align:center"|555<br />
|style="border:0px;background-color:#006DDA;width:32px;height:32px;color:#fff;text-align:center"|036<br />
|style="border:0px;background-color:#0048FF;width:32px;height:32px;color:#fff;text-align:center"|027<br />
|style="border:0px;background-color:#9100FF;width:32px;height:32px;color:#fff;text-align:center"|407<br />
|style="border:0px;background-color:#B600FF;width:32px;height:32px;color:#fff;text-align:center"|507<br />
|style="border:0px;background-color:#FF0091;width:32px;height:32px;color:#fff;text-align:center"|704<br />
|style="border:0px;background-color:#FF0000;width:32px;height:32px;color:#fff;text-align:center"|700<br />
|style="border:0px;background-color:#DA6D00;width:32px;height:32px;color:#000;text-align:center"|630<br />
|style="border:0px;background-color:#916D00;width:32px;height:32px;color:#fff;text-align:center"|430<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|140<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#00B66D;width:32px;height:32px;color:#fff;text-align:center"|053<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|044<br />
|style="border:0px;background-color:#484848;width:32px;height:32px;color:#fff;text-align:center"|222<br />
|style="border:0px;background-color:#480000;width:32px;height:32px;color:#fff;text-align:center"|200<br />
|style="border:0px;background-color:#6D2400;width:32px;height:32px;color:#fff;text-align:center"|310<br />
|-<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#6DB6FF;width:32px;height:32px;color:#000;text-align:center"|357<br />
|style="border:0px;background-color:#9191FF;width:32px;height:32px;color:#000;text-align:center"|447<br />
|style="border:0px;background-color:#DA6DFF;width:32px;height:32px;color:#000;text-align:center"|637<br />
|style="border:0px;background-color:#FF00FF;width:32px;height:32px;color:#fff;text-align:center"|707<br />
|style="border:0px;background-color:#FF6DFF;width:32px;height:32px;color:#000;text-align:center"|737<br />
|style="border:0px;background-color:#FF9100;width:32px;height:32px;color:#000;text-align:center"|740<br />
|style="border:0px;background-color:#FFB600;width:32px;height:32px;color:#000;text-align:center"|750<br />
|style="border:0px;background-color:#DADA00;width:32px;height:32px;color:#000;text-align:center"|660<br />
|style="border:0px;background-color:#6DDA00;width:32px;height:32px;color:#000;text-align:center"|360<br />
|style="border:0px;background-color:#00FF00;width:32px;height:32px;color:#000;text-align:center"|070<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#00FFFF;width:32px;height:32px;color:#000;text-align:center"|077<br />
|style="border:0px;background-color:#919191;width:32px;height:32px;color:#000;text-align:center"|444<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|-<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#B6DAFF;width:32px;height:32px;color:#000;text-align:center"|567<br />
|style="border:0px;background-color:#DAB6FF;width:32px;height:32px;color:#000;text-align:center"|657<br />
|style="border:0px;background-color:#FFB6FF;width:32px;height:32px;color:#000;text-align:center"|757<br />
|style="border:0px;background-color:#FF91FF;width:32px;height:32px;color:#000;text-align:center"|747<br />
|style="border:0px;background-color:#FFB6B6;width:32px;height:32px;color:#000;text-align:center"|755<br />
|style="border:0px;background-color:#FFDA91;width:32px;height:32px;color:#000;text-align:center"|764<br />
|style="border:0px;background-color:#FFFF00;width:32px;height:32px;color:#000;text-align:center"|770<br />
|style="border:0px;background-color:#FFFF6D;width:32px;height:32px;color:#000;text-align:center"|773<br />
|style="border:0px;background-color:#B6FF48;width:32px;height:32px;color:#000;text-align:center"|572<br />
|style="border:0px;background-color:#91FF6D;width:32px;height:32px;color:#000;text-align:center"|473<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#91DAFF;width:32px;height:32px;color:#000;text-align:center"|467<br />
|style="border:0px;background-color:#DADADA;width:32px;height:32px;color:#000;text-align:center"|666<br />
|style="border:0px;background-color:#DAB66D;width:32px;height:32px;color:#000;text-align:center"|653<br />
|style="border:0px;background-color:#FFDA00;width:32px;height:32px;color:#000;text-align:center"|760<br />
|}<br />
<!-- <br />
This image shows all the colors except the six shades of grey:<br />
<br />
[[Image:2C04_Palette_(Voronoi).png]] --><br />
The [[PPUMASK]] monochrome bit has the same implementation as on the 2C02, and so it has an unintuitive effect on the 2C04 PPUs; rather than forcing colors to grayscale, it instead forces them to the first column.<br />
<br />
==== RP2C04-0001 ====<br />
MAME's source claims that ''Baseball'', ''Freedom Force'', ''Gradius'', ''Hogan's Alley'', ''Mach Rider'', ''Pinball'', and ''Platoon'' require this palette.<br />
<br />
755,637,700,447,044,120,222,704,777,333,750,503,403,660,320,777<br />
357,653,310,360,467,657,764,027,760,276,000,200,666,444,707,014<br />
003,567,757,070,077,022,053,507,000,420,747,510,407,006,740,000<br />
000,140,555,031,572,326,770,630,020,036,040,111,773,737,430,473<br />
<br />
<div style="margin-left: 2em;"><br />
<div class="mw-collapsible mw-collapsed" style="border:1px solid #a2a9b1; padding: 5px; display: inline-block; min-width: 25em; overflow:auto;"><br />
<div style="font-weight:bold;line-height:1.6;">Palette colors</div><br />
<div class="mw-collapsible-content"><br />
{|class="wikitable"<br />
|-<br />
! style="text-align:center"|<br />
! style="text-align:center"|$x0<br />
! style="text-align:center"|$x1<br />
! style="text-align:center"|$x2<br />
! style="text-align:center"|$x3<br />
! style="text-align:center"|$x4<br />
! style="text-align:center"|$x5<br />
! style="text-align:center"|$x6<br />
! style="text-align:center"|$x7<br />
! style="text-align:center"|$x8<br />
! style="text-align:center"|$x9<br />
! style="text-align:center"|$xA<br />
! style="text-align:center"|$xB<br />
! style="text-align:center"|$xC<br />
! style="text-align:center"|$xD<br />
! style="text-align:center"|$xE<br />
! style="text-align:center"|$xF<br />
|-<br />
! style="text-align:center"|$0x<br />
|style="border:0px;background-color:#FFB6B6;width:32px;height:32px;color:#000;text-align:center"|755<br />
|style="border:0px;background-color:#DA6DFF;width:32px;height:32px;color:#000;text-align:center"|637<br />
|style="border:0px;background-color:#FF0000;width:32px;height:32px;color:#fff;text-align:center"|700<br />
|style="border:0px;background-color:#9191FF;width:32px;height:32px;color:#000;text-align:center"|447<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|044<br />
|style="border:0px;background-color:#244800;width:32px;height:32px;color:#fff;text-align:center"|120<br />
|style="border:0px;background-color:#484848;width:32px;height:32px;color:#fff;text-align:center"|222<br />
|style="border:0px;background-color:#FF0091;width:32px;height:32px;color:#fff;text-align:center"|704<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#6D6D6D;width:32px;height:32px;color:#fff;text-align:center"|333<br />
|style="border:0px;background-color:#FFB600;width:32px;height:32px;color:#000;text-align:center"|750<br />
|style="border:0px;background-color:#B6006D;width:32px;height:32px;color:#fff;text-align:center"|503<br />
|style="border:0px;background-color:#91006D;width:32px;height:32px;color:#fff;text-align:center"|403<br />
|style="border:0px;background-color:#DADA00;width:32px;height:32px;color:#000;text-align:center"|660<br />
|style="border:0px;background-color:#6D4800;width:32px;height:32px;color:#fff;text-align:center"|320<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|-<br />
! style="text-align:center"|$1x<br />
|style="border:0px;background-color:#6DB6FF;width:32px;height:32px;color:#000;text-align:center"|357<br />
|style="border:0px;background-color:#DAB66D;width:32px;height:32px;color:#000;text-align:center"|653<br />
|style="border:0px;background-color:#6D2400;width:32px;height:32px;color:#fff;text-align:center"|310<br />
|style="border:0px;background-color:#6DDA00;width:32px;height:32px;color:#000;text-align:center"|360<br />
|style="border:0px;background-color:#91DAFF;width:32px;height:32px;color:#000;text-align:center"|467<br />
|style="border:0px;background-color:#DAB6FF;width:32px;height:32px;color:#000;text-align:center"|657<br />
|style="border:0px;background-color:#FFDA91;width:32px;height:32px;color:#000;text-align:center"|764<br />
|style="border:0px;background-color:#0048FF;width:32px;height:32px;color:#fff;text-align:center"|027<br />
|style="border:0px;background-color:#FFDA00;width:32px;height:32px;color:#000;text-align:center"|760<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#480000;width:32px;height:32px;color:#fff;text-align:center"|200<br />
|style="border:0px;background-color:#DADADA;width:32px;height:32px;color:#000;text-align:center"|666<br />
|style="border:0px;background-color:#919191;width:32px;height:32px;color:#000;text-align:center"|444<br />
|style="border:0px;background-color:#FF00FF;width:32px;height:32px;color:#fff;text-align:center"|707<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|014<br />
|-<br />
! style="text-align:center"|$2x<br />
|style="border:0px;background-color:#00006D;width:32px;height:32px;color:#fff;text-align:center"|003<br />
|style="border:0px;background-color:#B6DAFF;width:32px;height:32px;color:#000;text-align:center"|567<br />
|style="border:0px;background-color:#FFB6FF;width:32px;height:32px;color:#000;text-align:center"|757<br />
|style="border:0px;background-color:#00FF00;width:32px;height:32px;color:#000;text-align:center"|070<br />
|style="border:0px;background-color:#00FFFF;width:32px;height:32px;color:#000;text-align:center"|077<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|022<br />
|style="border:0px;background-color:#00B66D;width:32px;height:32px;color:#fff;text-align:center"|053<br />
|style="border:0px;background-color:#B600FF;width:32px;height:32px;color:#fff;text-align:center"|507<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|420<br />
|style="border:0px;background-color:#FF91FF;width:32px;height:32px;color:#000;text-align:center"|747<br />
|style="border:0px;background-color:#B62400;width:32px;height:32px;color:#fff;text-align:center"|510<br />
|style="border:0px;background-color:#9100FF;width:32px;height:32px;color:#fff;text-align:center"|407<br />
|style="border:0px;background-color:#0000DA;width:32px;height:32px;color:#fff;text-align:center"|006<br />
|style="border:0px;background-color:#FF9100;width:32px;height:32px;color:#000;text-align:center"|740<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|-<br />
! style="text-align:center"|$3x<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|140<br />
|style="border:0px;background-color:#B6B6B6;width:32px;height:32px;color:#000;text-align:center"|555<br />
|style="border:0px;background-color:#006D24;width:32px;height:32px;color:#fff;text-align:center"|031<br />
|style="border:0px;background-color:#B6FF48;width:32px;height:32px;color:#000;text-align:center"|572<br />
|style="border:0px;background-color:#6D48DA;width:32px;height:32px;color:#fff;text-align:center"|326<br />
|style="border:0px;background-color:#FFFF00;width:32px;height:32px;color:#000;text-align:center"|770<br />
|style="border:0px;background-color:#DA6D00;width:32px;height:32px;color:#000;text-align:center"|630<br />
|style="border:0px;background-color:#004800;width:32px;height:32px;color:#fff;text-align:center"|020<br />
|style="border:0px;background-color:#006DDA;width:32px;height:32px;color:#fff;text-align:center"|036<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#242424;width:32px;height:32px;color:#fff;text-align:center"|111<br />
|style="border:0px;background-color:#FFFF6D;width:32px;height:32px;color:#000;text-align:center"|773<br />
|style="border:0px;background-color:#FF6DFF;width:32px;height:32px;color:#000;text-align:center"|737<br />
|style="border:0px;background-color:#916D00;width:32px;height:32px;color:#fff;text-align:center"|430<br />
|style="border:0px;background-color:#91FF6D;width:32px;height:32px;color:#000;text-align:center"|473<br />
|}<br />
</div></div></div><br />
<br />
==== RP2C04-0002 ====<br />
MAME's source claims that ''Castlevania'', ''Mach Rider (Endurance Course)'', ''Raid on Bungeling Bay'', ''Slalom'', ''Soccer'', ''Stroke & Match Golf'' (both versions), and ''Wrecking Crew'' require this palette.<br />
<br />
000,750,430,572,473,737,044,567,700,407,773,747,777,637,467,040<br />
020,357,510,666,053,360,200,447,222,707,003,276,657,320,000,326<br />
403,764,740,757,036,310,555,006,507,760,333,120,027,000,660,777<br />
653,111,070,630,022,014,704,140,000,077,420,770,755,503,031,444<br />
<br />
<div style="margin-left: 2em;"><br />
<div class="mw-collapsible mw-collapsed" style="border:1px solid #a2a9b1; padding: 5px; display: inline-block; min-width: 25em; overflow:auto;"><br />
<div style="font-weight:bold;line-height:1.6;">Palette colors</div><br />
<div class="mw-collapsible-content"><br />
{|class="wikitable"<br />
|-<br />
! style="text-align:center"|<br />
! style="text-align:center"|$x0<br />
! style="text-align:center"|$x1<br />
! style="text-align:center"|$x2<br />
! style="text-align:center"|$x3<br />
! style="text-align:center"|$x4<br />
! style="text-align:center"|$x5<br />
! style="text-align:center"|$x6<br />
! style="text-align:center"|$x7<br />
! style="text-align:center"|$x8<br />
! style="text-align:center"|$x9<br />
! style="text-align:center"|$xA<br />
! style="text-align:center"|$xB<br />
! style="text-align:center"|$xC<br />
! style="text-align:center"|$xD<br />
! style="text-align:center"|$xE<br />
! style="text-align:center"|$xF<br />
|-<br />
! style="text-align:center"|$0x<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#FFB600;width:32px;height:32px;color:#000;text-align:center"|750<br />
|style="border:0px;background-color:#916D00;width:32px;height:32px;color:#fff;text-align:center"|430<br />
|style="border:0px;background-color:#B6FF48;width:32px;height:32px;color:#000;text-align:center"|572<br />
|style="border:0px;background-color:#91FF6D;width:32px;height:32px;color:#000;text-align:center"|473<br />
|style="border:0px;background-color:#FF6DFF;width:32px;height:32px;color:#000;text-align:center"|737<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|044<br />
|style="border:0px;background-color:#B6DAFF;width:32px;height:32px;color:#000;text-align:center"|567<br />
|style="border:0px;background-color:#FF0000;width:32px;height:32px;color:#fff;text-align:center"|700<br />
|style="border:0px;background-color:#9100FF;width:32px;height:32px;color:#fff;text-align:center"|407<br />
|style="border:0px;background-color:#FFFF6D;width:32px;height:32px;color:#000;text-align:center"|773<br />
|style="border:0px;background-color:#FF91FF;width:32px;height:32px;color:#000;text-align:center"|747<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#DA6DFF;width:32px;height:32px;color:#000;text-align:center"|637<br />
|style="border:0px;background-color:#91DAFF;width:32px;height:32px;color:#000;text-align:center"|467<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|-<br />
! style="text-align:center"|$1x<br />
|style="border:0px;background-color:#004800;width:32px;height:32px;color:#fff;text-align:center"|020<br />
|style="border:0px;background-color:#6DB6FF;width:32px;height:32px;color:#000;text-align:center"|357<br />
|style="border:0px;background-color:#B62400;width:32px;height:32px;color:#fff;text-align:center"|510<br />
|style="border:0px;background-color:#DADADA;width:32px;height:32px;color:#000;text-align:center"|666<br />
|style="border:0px;background-color:#00B66D;width:32px;height:32px;color:#fff;text-align:center"|053<br />
|style="border:0px;background-color:#6DDA00;width:32px;height:32px;color:#000;text-align:center"|360<br />
|style="border:0px;background-color:#480000;width:32px;height:32px;color:#fff;text-align:center"|200<br />
|style="border:0px;background-color:#9191FF;width:32px;height:32px;color:#000;text-align:center"|447<br />
|style="border:0px;background-color:#484848;width:32px;height:32px;color:#fff;text-align:center"|222<br />
|style="border:0px;background-color:#FF00FF;width:32px;height:32px;color:#fff;text-align:center"|707<br />
|style="border:0px;background-color:#00006D;width:32px;height:32px;color:#fff;text-align:center"|003<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#DAB6FF;width:32px;height:32px;color:#000;text-align:center"|657<br />
|style="border:0px;background-color:#6D4800;width:32px;height:32px;color:#fff;text-align:center"|320<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#6D48DA;width:32px;height:32px;color:#fff;text-align:center"|326<br />
|-<br />
! style="text-align:center"|$2x<br />
|style="border:0px;background-color:#91006D;width:32px;height:32px;color:#fff;text-align:center"|403<br />
|style="border:0px;background-color:#FFDA91;width:32px;height:32px;color:#000;text-align:center"|764<br />
|style="border:0px;background-color:#FF9100;width:32px;height:32px;color:#000;text-align:center"|740<br />
|style="border:0px;background-color:#FFB6FF;width:32px;height:32px;color:#000;text-align:center"|757<br />
|style="border:0px;background-color:#006DDA;width:32px;height:32px;color:#fff;text-align:center"|036<br />
|style="border:0px;background-color:#6D2400;width:32px;height:32px;color:#fff;text-align:center"|310<br />
|style="border:0px;background-color:#B6B6B6;width:32px;height:32px;color:#000;text-align:center"|555<br />
|style="border:0px;background-color:#0000DA;width:32px;height:32px;color:#fff;text-align:center"|006<br />
|style="border:0px;background-color:#B600FF;width:32px;height:32px;color:#fff;text-align:center"|507<br />
|style="border:0px;background-color:#FFDA00;width:32px;height:32px;color:#000;text-align:center"|760<br />
|style="border:0px;background-color:#6D6D6D;width:32px;height:32px;color:#fff;text-align:center"|333<br />
|style="border:0px;background-color:#244800;width:32px;height:32px;color:#fff;text-align:center"|120<br />
|style="border:0px;background-color:#0048FF;width:32px;height:32px;color:#fff;text-align:center"|027<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#DADA00;width:32px;height:32px;color:#000;text-align:center"|660<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|-<br />
! style="text-align:center"|$3x<br />
|style="border:0px;background-color:#DAB66D;width:32px;height:32px;color:#000;text-align:center"|653<br />
|style="border:0px;background-color:#242424;width:32px;height:32px;color:#fff;text-align:center"|111<br />
|style="border:0px;background-color:#00FF00;width:32px;height:32px;color:#000;text-align:center"|070<br />
|style="border:0px;background-color:#DA6D00;width:32px;height:32px;color:#000;text-align:center"|630<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|022<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|014<br />
|style="border:0px;background-color:#FF0091;width:32px;height:32px;color:#fff;text-align:center"|704<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|140<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#00FFFF;width:32px;height:32px;color:#000;text-align:center"|077<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|420<br />
|style="border:0px;background-color:#FFFF00;width:32px;height:32px;color:#000;text-align:center"|770<br />
|style="border:0px;background-color:#FFB6B6;width:32px;height:32px;color:#000;text-align:center"|755<br />
|style="border:0px;background-color:#B6006D;width:32px;height:32px;color:#fff;text-align:center"|503<br />
|style="border:0px;background-color:#006D24;width:32px;height:32px;color:#fff;text-align:center"|031<br />
|style="border:0px;background-color:#919191;width:32px;height:32px;color:#000;text-align:center"|444<br />
|}<br />
</div></div></div><br />
<br />
==== RP2C04-0003 ====<br />
MAME's source claims that ''Balloon Fight'', ''Dr. Mario'', ''Excitebike'' (US), ''Goonies'', and ''Soccer'' require this palette.<br />
<br />
507,737,473,555,040,777,567,120,014,000,764,320,704,666,653,467<br />
447,044,503,027,140,430,630,053,333,326,000,006,700,510,747,755<br />
637,020,003,770,111,750,740,777,360,403,357,707,036,444,000,310<br />
077,200,572,757,420,070,660,222,031,000,657,773,407,276,760,022<br />
<br />
<div style="margin-left: 2em;"><br />
<div class="mw-collapsible mw-collapsed" style="border:1px solid #a2a9b1; padding: 5px; display: inline-block; min-width: 25em; overflow:auto;"><br />
<div style="font-weight:bold;line-height:1.6;">Palette colors</div><br />
<div class="mw-collapsible-content"><br />
{|class="wikitable"<br />
|-<br />
! style="text-align:center"|<br />
! style="text-align:center"|$x0<br />
! style="text-align:center"|$x1<br />
! style="text-align:center"|$x2<br />
! style="text-align:center"|$x3<br />
! style="text-align:center"|$x4<br />
! style="text-align:center"|$x5<br />
! style="text-align:center"|$x6<br />
! style="text-align:center"|$x7<br />
! style="text-align:center"|$x8<br />
! style="text-align:center"|$x9<br />
! style="text-align:center"|$xA<br />
! style="text-align:center"|$xB<br />
! style="text-align:center"|$xC<br />
! style="text-align:center"|$xD<br />
! style="text-align:center"|$xE<br />
! style="text-align:center"|$xF<br />
|-<br />
! style="text-align:center"|$0x<br />
|style="border:0px;background-color:#B600FF;width:32px;height:32px;color:#fff;text-align:center"|507<br />
|style="border:0px;background-color:#FF6DFF;width:32px;height:32px;color:#000;text-align:center"|737<br />
|style="border:0px;background-color:#91FF6D;width:32px;height:32px;color:#000;text-align:center"|473<br />
|style="border:0px;background-color:#B6B6B6;width:32px;height:32px;color:#000;text-align:center"|555<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#B6DAFF;width:32px;height:32px;color:#000;text-align:center"|567<br />
|style="border:0px;background-color:#244800;width:32px;height:32px;color:#fff;text-align:center"|120<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|014<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#FFDA91;width:32px;height:32px;color:#000;text-align:center"|764<br />
|style="border:0px;background-color:#6D4800;width:32px;height:32px;color:#fff;text-align:center"|320<br />
|style="border:0px;background-color:#FF0091;width:32px;height:32px;color:#fff;text-align:center"|704<br />
|style="border:0px;background-color:#DADADA;width:32px;height:32px;color:#000;text-align:center"|666<br />
|style="border:0px;background-color:#DAB66D;width:32px;height:32px;color:#000;text-align:center"|653<br />
|style="border:0px;background-color:#91DAFF;width:32px;height:32px;color:#000;text-align:center"|467<br />
|-<br />
! style="text-align:center"|$1x<br />
|style="border:0px;background-color:#9191FF;width:32px;height:32px;color:#000;text-align:center"|447<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|044<br />
|style="border:0px;background-color:#B6006D;width:32px;height:32px;color:#fff;text-align:center"|503<br />
|style="border:0px;background-color:#0048FF;width:32px;height:32px;color:#fff;text-align:center"|027<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|140<br />
|style="border:0px;background-color:#916D00;width:32px;height:32px;color:#fff;text-align:center"|430<br />
|style="border:0px;background-color:#DA6D00;width:32px;height:32px;color:#000;text-align:center"|630<br />
|style="border:0px;background-color:#00B66D;width:32px;height:32px;color:#fff;text-align:center"|053<br />
|style="border:0px;background-color:#6D6D6D;width:32px;height:32px;color:#fff;text-align:center"|333<br />
|style="border:0px;background-color:#6D48DA;width:32px;height:32px;color:#fff;text-align:center"|326<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#0000DA;width:32px;height:32px;color:#fff;text-align:center"|006<br />
|style="border:0px;background-color:#FF0000;width:32px;height:32px;color:#fff;text-align:center"|700<br />
|style="border:0px;background-color:#B62400;width:32px;height:32px;color:#fff;text-align:center"|510<br />
|style="border:0px;background-color:#FF91FF;width:32px;height:32px;color:#000;text-align:center"|747<br />
|style="border:0px;background-color:#FFB6B6;width:32px;height:32px;color:#000;text-align:center"|755<br />
|-<br />
! style="text-align:center"|$2x<br />
|style="border:0px;background-color:#DA6DFF;width:32px;height:32px;color:#000;text-align:center"|637<br />
|style="border:0px;background-color:#004800;width:32px;height:32px;color:#fff;text-align:center"|020<br />
|style="border:0px;background-color:#00006D;width:32px;height:32px;color:#fff;text-align:center"|003<br />
|style="border:0px;background-color:#FFFF00;width:32px;height:32px;color:#000;text-align:center"|770<br />
|style="border:0px;background-color:#242424;width:32px;height:32px;color:#fff;text-align:center"|111<br />
|style="border:0px;background-color:#FFB600;width:32px;height:32px;color:#000;text-align:center"|750<br />
|style="border:0px;background-color:#FF9100;width:32px;height:32px;color:#000;text-align:center"|740<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#6DDA00;width:32px;height:32px;color:#000;text-align:center"|360<br />
|style="border:0px;background-color:#91006D;width:32px;height:32px;color:#fff;text-align:center"|403<br />
|style="border:0px;background-color:#6DB6FF;width:32px;height:32px;color:#000;text-align:center"|357<br />
|style="border:0px;background-color:#FF00FF;width:32px;height:32px;color:#fff;text-align:center"|707<br />
|style="border:0px;background-color:#006DDA;width:32px;height:32px;color:#fff;text-align:center"|036<br />
|style="border:0px;background-color:#919191;width:32px;height:32px;color:#000;text-align:center"|444<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#6D2400;width:32px;height:32px;color:#fff;text-align:center"|310<br />
|-<br />
! style="text-align:center"|$3x<br />
|style="border:0px;background-color:#00FFFF;width:32px;height:32px;color:#000;text-align:center"|077<br />
|style="border:0px;background-color:#480000;width:32px;height:32px;color:#fff;text-align:center"|200<br />
|style="border:0px;background-color:#B6FF48;width:32px;height:32px;color:#000;text-align:center"|572<br />
|style="border:0px;background-color:#FFB6FF;width:32px;height:32px;color:#000;text-align:center"|757<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|420<br />
|style="border:0px;background-color:#00FF00;width:32px;height:32px;color:#000;text-align:center"|070<br />
|style="border:0px;background-color:#DADA00;width:32px;height:32px;color:#000;text-align:center"|660<br />
|style="border:0px;background-color:#484848;width:32px;height:32px;color:#fff;text-align:center"|222<br />
|style="border:0px;background-color:#006D24;width:32px;height:32px;color:#fff;text-align:center"|031<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#DAB6FF;width:32px;height:32px;color:#000;text-align:center"|657<br />
|style="border:0px;background-color:#FFFF6D;width:32px;height:32px;color:#000;text-align:center"|773<br />
|style="border:0px;background-color:#9100FF;width:32px;height:32px;color:#fff;text-align:center"|407<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#FFDA00;width:32px;height:32px;color:#000;text-align:center"|760<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|022<br />
|}<br />
</div></div></div><br />
<br />
==== RP2C04-0004 ====<br />
MAME's source claims that ''Clu Clu Land'', ''Excitebike'' (Japan), ''Ice Climber'' (both versions), and ''Super Mario Bros.'' require this palette.<br />
<br />
430,326,044,660,000,755,014,630,555,310,070,003,764,770,040,572<br />
737,200,027,747,000,222,510,740,653,053,447,140,403,000,473,357<br />
503,031,420,006,407,507,333,704,022,666,036,020,111,773,444,707<br />
757,777,320,700,760,276,777,467,000,750,637,567,360,657,077,120<br />
<br />
<div style="margin-left: 2em;"><br />
<div class="mw-collapsible mw-collapsed" style="border:1px solid #a2a9b1; padding: 5px; display: inline-block; min-width: 25em; overflow:auto;"><br />
<div style="font-weight:bold;line-height:1.6;">Palette colors</div><br />
<div class="mw-collapsible-content"><br />
{|class="wikitable"<br />
|-<br />
! style="text-align:center"|<br />
! style="text-align:center"|$x0<br />
! style="text-align:center"|$x1<br />
! style="text-align:center"|$x2<br />
! style="text-align:center"|$x3<br />
! style="text-align:center"|$x4<br />
! style="text-align:center"|$x5<br />
! style="text-align:center"|$x6<br />
! style="text-align:center"|$x7<br />
! style="text-align:center"|$x8<br />
! style="text-align:center"|$x9<br />
! style="text-align:center"|$xA<br />
! style="text-align:center"|$xB<br />
! style="text-align:center"|$xC<br />
! style="text-align:center"|$xD<br />
! style="text-align:center"|$xE<br />
! style="text-align:center"|$xF<br />
|-<br />
! style="text-align:center"|$0x<br />
|style="border:0px;background-color:#916D00;width:32px;height:32px;color:#fff;text-align:center"|430<br />
|style="border:0px;background-color:#6D48DA;width:32px;height:32px;color:#fff;text-align:center"|326<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|044<br />
|style="border:0px;background-color:#DADA00;width:32px;height:32px;color:#000;text-align:center"|660<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#FFB6B6;width:32px;height:32px;color:#000;text-align:center"|755<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|014<br />
|style="border:0px;background-color:#DA6D00;width:32px;height:32px;color:#000;text-align:center"|630<br />
|style="border:0px;background-color:#B6B6B6;width:32px;height:32px;color:#000;text-align:center"|555<br />
|style="border:0px;background-color:#6D2400;width:32px;height:32px;color:#fff;text-align:center"|310<br />
|style="border:0px;background-color:#00FF00;width:32px;height:32px;color:#000;text-align:center"|070<br />
|style="border:0px;background-color:#00006D;width:32px;height:32px;color:#fff;text-align:center"|003<br />
|style="border:0px;background-color:#FFDA91;width:32px;height:32px;color:#000;text-align:center"|764<br />
|style="border:0px;background-color:#FFFF00;width:32px;height:32px;color:#000;text-align:center"|770<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#B6FF48;width:32px;height:32px;color:#000;text-align:center"|572<br />
|-<br />
! style="text-align:center"|$1x<br />
|style="border:0px;background-color:#FF6DFF;width:32px;height:32px;color:#000;text-align:center"|737<br />
|style="border:0px;background-color:#480000;width:32px;height:32px;color:#fff;text-align:center"|200<br />
|style="border:0px;background-color:#0048FF;width:32px;height:32px;color:#fff;text-align:center"|027<br />
|style="border:0px;background-color:#FF91FF;width:32px;height:32px;color:#000;text-align:center"|747<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#484848;width:32px;height:32px;color:#fff;text-align:center"|222<br />
|style="border:0px;background-color:#B62400;width:32px;height:32px;color:#fff;text-align:center"|510<br />
|style="border:0px;background-color:#FF9100;width:32px;height:32px;color:#000;text-align:center"|740<br />
|style="border:0px;background-color:#DAB66D;width:32px;height:32px;color:#000;text-align:center"|653<br />
|style="border:0px;background-color:#00B66D;width:32px;height:32px;color:#fff;text-align:center"|053<br />
|style="border:0px;background-color:#9191FF;width:32px;height:32px;color:#000;text-align:center"|447<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|140<br />
|style="border:0px;background-color:#91006D;width:32px;height:32px;color:#fff;text-align:center"|403<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#91FF6D;width:32px;height:32px;color:#000;text-align:center"|473<br />
|style="border:0px;background-color:#6DB6FF;width:32px;height:32px;color:#000;text-align:center"|357<br />
|-<br />
! style="text-align:center"|$2x<br />
|style="border:0px;background-color:#B6006D;width:32px;height:32px;color:#fff;text-align:center"|503<br />
|style="border:0px;background-color:#006D24;width:32px;height:32px;color:#fff;text-align:center"|031<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|420<br />
|style="border:0px;background-color:#0000DA;width:32px;height:32px;color:#fff;text-align:center"|006<br />
|style="border:0px;background-color:#9100FF;width:32px;height:32px;color:#fff;text-align:center"|407<br />
|style="border:0px;background-color:#B600FF;width:32px;height:32px;color:#fff;text-align:center"|507<br />
|style="border:0px;background-color:#6D6D6D;width:32px;height:32px;color:#fff;text-align:center"|333<br />
|style="border:0px;background-color:#FF0091;width:32px;height:32px;color:#fff;text-align:center"|704<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|022<br />
|style="border:0px;background-color:#DADADA;width:32px;height:32px;color:#000;text-align:center"|666<br />
|style="border:0px;background-color:#006DDA;width:32px;height:32px;color:#fff;text-align:center"|036<br />
|style="border:0px;background-color:#004800;width:32px;height:32px;color:#fff;text-align:center"|020<br />
|style="border:0px;background-color:#242424;width:32px;height:32px;color:#fff;text-align:center"|111<br />
|style="border:0px;background-color:#FFFF6D;width:32px;height:32px;color:#000;text-align:center"|773<br />
|style="border:0px;background-color:#919191;width:32px;height:32px;color:#000;text-align:center"|444<br />
|style="border:0px;background-color:#FF00FF;width:32px;height:32px;color:#fff;text-align:center"|707<br />
|-<br />
! style="text-align:center"|$3x<br />
|style="border:0px;background-color:#FFB6FF;width:32px;height:32px;color:#000;text-align:center"|757<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#6D4800;width:32px;height:32px;color:#fff;text-align:center"|320<br />
|style="border:0px;background-color:#FF0000;width:32px;height:32px;color:#fff;text-align:center"|700<br />
|style="border:0px;background-color:#FFDA00;width:32px;height:32px;color:#000;text-align:center"|760<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#91DAFF;width:32px;height:32px;color:#000;text-align:center"|467<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#FFB600;width:32px;height:32px;color:#000;text-align:center"|750<br />
|style="border:0px;background-color:#DA6DFF;width:32px;height:32px;color:#000;text-align:center"|637<br />
|style="border:0px;background-color:#B6DAFF;width:32px;height:32px;color:#000;text-align:center"|567<br />
|style="border:0px;background-color:#6DDA00;width:32px;height:32px;color:#000;text-align:center"|360<br />
|style="border:0px;background-color:#DAB6FF;width:32px;height:32px;color:#000;text-align:center"|657<br />
|style="border:0px;background-color:#00FFFF;width:32px;height:32px;color:#000;text-align:center"|077<br />
|style="border:0px;background-color:#244800;width:32px;height:32px;color:#fff;text-align:center"|120<br />
|}<br />
</div></div></div><br />
<br />
==== Games compatible with multiple different PPUs ====<br />
Some games don't require that arcade owners have the correct physical PPU.<br />
<br />
At the very least, the following games use some of the DIP switches to support multiple different PPUs:<br />
* Atari RBI Baseball<br />
* Battle City<br />
* Star Luster<br />
* Super Sky Kid<br />
* Super Xevious<br />
* Tetris (Tengen)<br />
* TKO Boxing<br />
<br />
==== LUT approach ====<br />
<br />
Emulator authors may implement the 2C04 variants as a LUT indexing the "ordered" palette. This has the added advantage of being able to use preexisting .pal files if the end user wishes to do so.<br />
<br />
Repeating colors such as 000 and 777 may index into the same entry of the "ordered" palette, as this is functionally identical.<br />
<nowiki>const unsigned char PaletteLUT_2C04_0001 [64] ={<br />
0x35,0x23,0x16,0x22,0x1C,0x09,0x1D,0x15,0x20,0x00,0x27,0x05,0x04,0x28,0x08,0x20,<br />
0x21,0x3E,0x1F,0x29,0x3C,0x32,0x36,0x12,0x3F,0x2B,0x2E,0x1E,0x3D,0x2D,0x24,0x01,<br />
0x0E,0x31,0x33,0x2A,0x2C,0x0C,0x1B,0x14,0x2E,0x07,0x34,0x06,0x13,0x02,0x26,0x2E,<br />
0x2E,0x19,0x10,0x0A,0x39,0x03,0x37,0x17,0x0F,0x11,0x0B,0x0D,0x38,0x25,0x18,0x3A<br />
};<br />
<br />
const unsigned char PaletteLUT_2C04_0002 [64] ={<br />
0x2E,0x27,0x18,0x39,0x3A,0x25,0x1C,0x31,0x16,0x13,0x38,0x34,0x20,0x23,0x3C,0x0B,<br />
0x0F,0x21,0x06,0x3D,0x1B,0x29,0x1E,0x22,0x1D,0x24,0x0E,0x2B,0x32,0x08,0x2E,0x03,<br />
0x04,0x36,0x26,0x33,0x11,0x1F,0x10,0x02,0x14,0x3F,0x00,0x09,0x12,0x2E,0x28,0x20,<br />
0x3E,0x0D,0x2A,0x17,0x0C,0x01,0x15,0x19,0x2E,0x2C,0x07,0x37,0x35,0x05,0x0A,0x2D<br />
};<br />
<br />
const unsigned char PaletteLUT_2C04_0003 [64] ={<br />
0x14,0x25,0x3A,0x10,0x0B,0x20,0x31,0x09,0x01,0x2E,0x36,0x08,0x15,0x3D,0x3E,0x3C,<br />
0x22,0x1C,0x05,0x12,0x19,0x18,0x17,0x1B,0x00,0x03,0x2E,0x02,0x16,0x06,0x34,0x35,<br />
0x23,0x0F,0x0E,0x37,0x0D,0x27,0x26,0x20,0x29,0x04,0x21,0x24,0x11,0x2D,0x2E,0x1F,<br />
0x2C,0x1E,0x39,0x33,0x07,0x2A,0x28,0x1D,0x0A,0x2E,0x32,0x38,0x13,0x2B,0x3F,0x0C<br />
};<br />
<br />
const unsigned char PaletteLUT_2C04_0004 [64] ={<br />
0x18,0x03,0x1C,0x28,0x2E,0x35,0x01,0x17,0x10,0x1F,0x2A,0x0E,0x36,0x37,0x0B,0x39,<br />
0x25,0x1E,0x12,0x34,0x2E,0x1D,0x06,0x26,0x3E,0x1B,0x22,0x19,0x04,0x2E,0x3A,0x21,<br />
0x05,0x0A,0x07,0x02,0x13,0x14,0x00,0x15,0x0C,0x3D,0x11,0x0F,0x0D,0x38,0x2D,0x24,<br />
0x33,0x20,0x08,0x16,0x3F,0x2B,0x20,0x3C,0x2E,0x27,0x23,0x31,0x29,0x32,0x2C,0x09<br />
};</nowiki><br />
<br />
== Backdrop color (palette index 0) uses ==<br />
<br />
During forced blanking, when neither background nor sprites are enabled in [[PPU registers|PPUMASK ($2001)]], the picture will show the backdrop color.<br />
If only the background or sprites are disabled, or if the left 8 pixels are clipped off, the PPU continues its [[PPU rendering|normal video memory access pattern]] but uses the backdrop color for anything disabled.<br />
<br />
== The background palette direct access ==<br />
<br />
During forced blanking, if the current VRAM address ever points to a palette register (i.e., $3F00-$3FFF), then the color in that palette register will be output to the screen instead of the backdrop color, for as long as the VRAM address is pointing there during the forced blanking. This can be used to display colors from the normally unused $3F04/$3F08/$3F0C palette locations. (Looking at the relevant circuitry in [[Visual 2C02]], this happens because the palette RAM's output is not disconnected from the video output circuitry when not rendering.)<br />
<br />
A loop that fills the palette will cause each color in turn to be shown on the screen. To avoid artifacts while loading the palette, it should be updated in the [[The frame and NMIs|VBlank]] period.<br />
<br />
== Color names ==<br />
When programmers and artists are communicating, it's often useful to have human-readable names for colors.<br />
Many graphic designers who have done web or game work will be familiar with [[wikipedia:Web colors#HTML color names|HTML color names]].<br />
<br />
=== Luma ===<br />
<br />
* $0F: Black<br />
* $00: Dark gray<br />
* $10: Light gray or silver<br />
* $20: White<br />
* $01-$0C: Dark colors, medium mixed with black<br />
* $11-$1C: Medium colors, similar brightness to dark gray<br />
* $21-$2C: Light colors, similar brightness to light gray<br />
* $31-$3C: Pale colors, light mixed with white<br />
<br />
=== Chroma ===<br />
Names for hues:<br />
* $x0: Gray<br />
* $x1: Azure<br />
* $x2: Blue<br />
* $x3: Violet<br />
* $x4: Magenta<br />
* $x5: Rose<br />
* $x6: Red or maroon<br />
* $x7: Orange<br />
* $x8: Yellow or olive<br />
* $x9: Chartreuse<br />
* $xA: Green<br />
* $xB: Spring<br />
* $xC: Cyan<br />
<br />
=== RGBI ===<br />
These NES colors approximate colors in 16-color RGBI palettes, such as the CGA, EGA, or classic Windows palette, though the NES doesn't really have particularly good approximations:<br />
* $0F: 0/Black<br />
* $02: 1/Navy<br />
* $1A: 2/Green<br />
* $1C: 3/Teal<br />
* $06: 4/Maroon<br />
* $14: 5/Purple<br />
* $18: 6/Olive ($17 for the brown in CGA/EGA in RGB)<br />
* $10: 7/Silver<br />
* $00: 8/Gray<br />
* $12: 9/Blue<br />
* $2A: 10/Lime<br />
* $2C: 11/Aqua/Cyan<br />
* $16: 12/Red<br />
* $24: 13/Fuchsia/Magenta<br />
* $28: 14/Yellow<br />
* $30: 15/White<br />
<br />
== See also ==<br />
* [[NTSC video]] - details of the NTSC signal generation and how it produces the palette<br />
* [[PAL video]]<br />
* [[:Category:Palettes|Palettes (gallery)]] - a few different visualizations of PPU palettes.<br />
* [//forums.nesdev.org/viewtopic.php?t=13264 Another palette test] - Simple test ROM to display the palette.<br />
* [[Full palette demo]] - Demo that displays the entire palette with all emphasis settings at once.<br />
* [//www.nesdev.org/rgbppu/ RGB PPU Palette Converter] - RGB PPU palette conversion and visualization tool, [//forums.nesdev.org/viewtopic.php?p=104217 written by WhoaMan].<br />
<br />
== References ==<br />
* [//forums.nesdev.org/viewtopic.php?p=98955#p98955 Re: Various questions about the color palette and emulators] - 2012 collection of 2C03, 2C04, 2C05 palettes.</div>Bregaladhttps://www.nesdev.org/w/index.php?title=PPU_palettes&diff=21646PPU palettes2024-03-05T10:02:36Z<p>Bregalad: /* Memory Map */ Include unused colors entrues in the memory map</p>
<hr />
<div>The NES has a limited selection of color outputs. A 6-bit value in the palette memory area corresponds to one of 64 outputs. The [[Colour emphasis|emphasis]] bits of the [[PPUMASK]] register ($2001) provide an additional color modifier.<br />
<br />
For more information on how the colors are generated on an NTSC NES, see: [[NTSC video]]. For additional information on how the colors are generated on a PAL NES, see: [[PAL video]].<br />
<br />
== Memory Map ==<br />
The palette for the background runs from VRAM $3F00 to $3F0F; the palette for the sprites runs from $3F10 to $3F1F. Each color takes up one byte.<br />
<br />
{| class="wikitable"<br />
! Address || Purpose<br />
|-<br />
| $3F00 || Universal background color<br />
|-<br />
| $3F01-$3F03 || Background palette 0<br />
|-<br />
| $3F04 || Normally unused color 1<br />
|-<br />
| $3F05-$3F07 || Background palette 1<br />
|-<br />
| $3F08 || Normally unused color 2<br />
|-<br />
| $3F09-$3F0B || Background palette 2<br />
|-<br />
| $3F0C || Normally unused color 3<br />
|-<br />
| $3F0D-$3F0F || Background palette 3<br />
|-<br />
| $3F10 || Mirror of universal background color<br />
|-<br />
| $3F11-$3F13 || Sprite palette 0<br />
|-<br />
| $3F14 || Mirror of unused color 1<br />
|-<br />
| $3F15-$3F17 || Sprite palette 1<br />
|-<br />
| $3F18 || Mirror of unused color 2<br />
|-<br />
| $3F19-$3F1B || Sprite palette 2<br />
|-<br />
| $3F1C || Mirror of unused color 3<br />
|-<br />
| $3F1D-$3F1F || Sprite palette 3<br />
|}<br />
<br />
Each palette has three colors. Each 16x16 pixel area of the background can use the backdrop color and the three colors from one of the four background palettes. The choice of palette for each 16x16 pixel area is controlled by bits in the attribute table at the end of each [[PPU nametables|nametable]].<br />
Each sprite can use the three colors from one of the sprite palettes. The choice of palette is in attribute 2 of each sprite (see [[PPU OAM]]).<br />
<br />
Addresses $3F04/$3F08/$3F0C are not used by the PPU when normally rendering (since the pattern values that would otherwise select those cells select the backdrop color instead). They can still be shown using the background palette direct access, explained below.<br />
<br />
Addresses $3F10/$3F14/$3F18/$3F1C are mirrors of $3F00/$3F04/$3F08/$3F0C. Note that this goes for writing as well as reading.<br />
A symptom of not having implemented this correctly in an emulator is the sky being black in ''Super Mario Bros.'', which writes the backdrop color through $3F10.<br />
<br />
Thus, indices into the palette are formed as follows:<br />
43210<br />
|||||<br />
|||++- Pixel value from tile data<br />
|++--- Palette number from attribute table or OAM<br />
+----- Background/Sprite select<br />
As in some second-generation game consoles, values in the NES palette are based on [[wikipedia:HSL and HSV|hue and brightness]]:<br />
76543210<br />
||||||||<br />
||||++++- Hue (phase, determines NTSC/PAL chroma)<br />
||++----- Value (voltage, determines NTSC/PAL luma)<br />
++------- Unimplemented, reads back as 0<br />
Hue $0 is light gray, $1-$C are blue to red to green to cyan, $D is dark gray, and $E-$F are mirrors of $1D (black).<br />
<br />
It works this way because of the way colors are represented in a composite NTSC or PAL signal, with the phase of a color subcarrier controlling the hue. For details regarding signal generation and color decoding, see [[NTSC video]].<br />
<br />
The canonical code for "black" is $0F.<br />
<br />
The 2C03 RGB PPU used in the PlayChoice-10 and 2C05-99 in the Famicom Titler renders hue $D as black, not dark gray.<br />
The 2C04 PPUs used in many [[Vs. System]] arcade games have completely different palettes as a copy protection measure.<br />
<br />
== Palettes ==<br />
<br />
The 2C02 (NTSC) and 2C07 (PAL) PPU is used to generate an analog composite video signal. These were used in most home consoles.<br />
<br />
The 2C03, 2C04, and 2C05, on the other hand, all output analog red, green, blue, and sync (RGBS) signals. The sync signal contains horizontal and vertical sync pulses in the same format as an all-black composite signal.<br />
Each of the three video channels uses a 3-bit DAC driven by a look-up table in a 64x9-bit ROM inside the PPU.<br />
The look-up tables (one digit for each of red, green, and blue, in order) are given below.<br />
<br />
RGB PPUs were used mostly in arcade machines (e.g. [[Vs. System]], Playchoice 10), as well as the Sharp Famicom Titler.<br />
<br />
=== 2C02 ===<br />
The RF Famicom, AV Famicom, NES (both front- and top-loading), and the North American version of the Sharp Nintendo TV use the 2C02 PPU.<br />
Unlike some other consoles' video circuits, the 2C02 does not generate RGB video and then encode that to composite.<br />
Instead it generates [[NTSC video]] directly in the composite domain, decoded by the television receiver into RGB to drive its picture tube.<br />
<br />
{{mbox<br />
| type = warning<br />
| text = <font size=+1>Do not use color $0D. It results in a "blacker than black" signal that may cause problems for some TVs.</font><br />
<hr><br />
Further details on $0D and its effects can be found [[Color_$0D_games|here.]]}}<br />
<br />
Most emulators can use a predefined palette, such as one commonly stored in common [[.pal]] format, in which each triplet represents the sRGB color that results from decoding a large flat area with a given palette value.<br />
<br />
See [[NTSC_video#Composite_decoding|this page]] for more details on a general algorithm to decode a PPU composite signal to color RGB.<br />
<br />
The following palette was generated using [https://github.com/Gumball2415/palgen-persune Persune's palette generator @v0.12.0] with the following arguments: <code>palgen-persune.py -phs -5.0 -o 2C02G -f ".txt MediaWiki"</code><br />
<br />
{|class="wikitable"<br />
|-<br />
|style="border:0px;background-color:#626262;width:32px;height:32px;color:#fff;text-align:center"|$00<br />
|style="border:0px;background-color:#001FB2;width:32px;height:32px;color:#fff;text-align:center"|$01<br />
|style="border:0px;background-color:#2404C8;width:32px;height:32px;color:#fff;text-align:center"|$02<br />
|style="border:0px;background-color:#5200B2;width:32px;height:32px;color:#fff;text-align:center"|$03<br />
|style="border:0px;background-color:#730076;width:32px;height:32px;color:#fff;text-align:center"|$04<br />
|style="border:0px;background-color:#800024;width:32px;height:32px;color:#fff;text-align:center"|$05<br />
|style="border:0px;background-color:#730B00;width:32px;height:32px;color:#fff;text-align:center"|$06<br />
|style="border:0px;background-color:#522800;width:32px;height:32px;color:#fff;text-align:center"|$07<br />
|style="border:0px;background-color:#244400;width:32px;height:32px;color:#fff;text-align:center"|$08<br />
|style="border:0px;background-color:#005700;width:32px;height:32px;color:#fff;text-align:center"|$09<br />
|style="border:0px;background-color:#005C00;width:32px;height:32px;color:#fff;text-align:center"|$0A<br />
|style="border:0px;background-color:#005324;width:32px;height:32px;color:#fff;text-align:center"|$0B<br />
|style="border:0px;background-color:#003C76;width:32px;height:32px;color:#fff;text-align:center"|$0C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|[[Color_$0D_games#Effects|<s style="color:red">$0D</s>]]<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$0E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$0F<br />
|-<br />
|style="border:0px;background-color:#ABABAB;width:32px;height:32px;color:#000;text-align:center"|$10<br />
|style="border:0px;background-color:#0D57FF;width:32px;height:32px;color:#fff;text-align:center"|$11<br />
|style="border:0px;background-color:#4B30FF;width:32px;height:32px;color:#fff;text-align:center"|$12<br />
|style="border:0px;background-color:#8A13FF;width:32px;height:32px;color:#fff;text-align:center"|$13<br />
|style="border:0px;background-color:#BC08D6;width:32px;height:32px;color:#fff;text-align:center"|$14<br />
|style="border:0px;background-color:#D21269;width:32px;height:32px;color:#fff;text-align:center"|$15<br />
|style="border:0px;background-color:#C72E00;width:32px;height:32px;color:#fff;text-align:center"|$16<br />
|style="border:0px;background-color:#9D5400;width:32px;height:32px;color:#fff;text-align:center"|$17<br />
|style="border:0px;background-color:#607B00;width:32px;height:32px;color:#fff;text-align:center"|$18<br />
|style="border:0px;background-color:#209800;width:32px;height:32px;color:#fff;text-align:center"|$19<br />
|style="border:0px;background-color:#00A300;width:32px;height:32px;color:#fff;text-align:center"|$1A<br />
|style="border:0px;background-color:#009942;width:32px;height:32px;color:#fff;text-align:center"|$1B<br />
|style="border:0px;background-color:#007DB4;width:32px;height:32px;color:#fff;text-align:center"|$1C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1F<br />
|-<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|$20<br />
|style="border:0px;background-color:#53AEFF;width:32px;height:32px;color:#000;text-align:center"|$21<br />
|style="border:0px;background-color:#9085FF;width:32px;height:32px;color:#000;text-align:center"|$22<br />
|style="border:0px;background-color:#D365FF;width:32px;height:32px;color:#000;text-align:center"|$23<br />
|style="border:0px;background-color:#FF57FF;width:32px;height:32px;color:#000;text-align:center"|$24<br />
|style="border:0px;background-color:#FF5DCF;width:32px;height:32px;color:#000;text-align:center"|$25<br />
|style="border:0px;background-color:#FF7757;width:32px;height:32px;color:#000;text-align:center"|$26<br />
|style="border:0px;background-color:#FA9E00;width:32px;height:32px;color:#000;text-align:center"|$27<br />
|style="border:0px;background-color:#BDC700;width:32px;height:32px;color:#000;text-align:center"|$28<br />
|style="border:0px;background-color:#7AE700;width:32px;height:32px;color:#000;text-align:center"|$29<br />
|style="border:0px;background-color:#43F611;width:32px;height:32px;color:#000;text-align:center"|$2A<br />
|style="border:0px;background-color:#26EF7E;width:32px;height:32px;color:#000;text-align:center"|$2B<br />
|style="border:0px;background-color:#2CD5F6;width:32px;height:32px;color:#000;text-align:center"|$2C<br />
|style="border:0px;background-color:#4E4E4E;width:32px;height:32px;color:#fff;text-align:center"|$2D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$2E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$2F<br />
|-<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|$30<br />
|style="border:0px;background-color:#B6E1FF;width:32px;height:32px;color:#000;text-align:center"|$31<br />
|style="border:0px;background-color:#CED1FF;width:32px;height:32px;color:#000;text-align:center"|$32<br />
|style="border:0px;background-color:#E9C3FF;width:32px;height:32px;color:#000;text-align:center"|$33<br />
|style="border:0px;background-color:#FFBCFF;width:32px;height:32px;color:#000;text-align:center"|$34<br />
|style="border:0px;background-color:#FFBDF4;width:32px;height:32px;color:#000;text-align:center"|$35<br />
|style="border:0px;background-color:#FFC6C3;width:32px;height:32px;color:#000;text-align:center"|$36<br />
|style="border:0px;background-color:#FFD59A;width:32px;height:32px;color:#000;text-align:center"|$37<br />
|style="border:0px;background-color:#E9E681;width:32px;height:32px;color:#000;text-align:center"|$38<br />
|style="border:0px;background-color:#CEF481;width:32px;height:32px;color:#000;text-align:center"|$39<br />
|style="border:0px;background-color:#B6FB9A;width:32px;height:32px;color:#000;text-align:center"|$3A<br />
|style="border:0px;background-color:#A9FAC3;width:32px;height:32px;color:#000;text-align:center"|$3B<br />
|style="border:0px;background-color:#A9F0F4;width:32px;height:32px;color:#000;text-align:center"|$3C<br />
|style="border:0px;background-color:#B8B8B8;width:32px;height:32px;color:#000;text-align:center"|$3D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$3E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$3F<br />
|}<br />
<br />
Other tools for generating a palette include [http://bisqwit.iki.fi/utils/nespalette.php one by Bisqwit] and [http://drag.wootest.net/misc/palgen.html one by Drag].<br />
These simulate generating a large area of one flat color and then decoding that with the adjustment knobs set to various settings.<br />
<br />
=== 2C07 ===<br />
<br />
The PAL PPU (2C07) generates a composite [[PAL video]] signal, which has a -15 degree hue shift relative to the 2C02 due to a different colorburst reference phase generated by the PPU ($x7 rather than $x8), in addition to the PAL colorburst phase being defined as -U ± 45 degrees.<br />
<br />
The following palette was generated using [https://github.com/Gumball2415/palgen-persune Persune's palette generator @v0.12.0] with the following arguments: <code>palgen-persune.py -ppu "2C07" -o 2C07 -f ".txt MediaWiki"</code><br />
<br />
{|class="wikitable"<br />
|-<br />
|style="border:0px;background-color:#626262;width:32px;height:32px;color:#fff;text-align:center"|$00<br />
|style="border:0px;background-color:#002E98;width:32px;height:32px;color:#fff;text-align:center"|$01<br />
|style="border:0px;background-color:#0C11C2;width:32px;height:32px;color:#fff;text-align:center"|$02<br />
|style="border:0px;background-color:#3B00C2;width:32px;height:32px;color:#fff;text-align:center"|$03<br />
|style="border:0px;background-color:#650098;width:32px;height:32px;color:#fff;text-align:center"|$04<br />
|style="border:0px;background-color:#7D004E;width:32px;height:32px;color:#fff;text-align:center"|$05<br />
|style="border:0px;background-color:#7D0000;width:32px;height:32px;color:#fff;text-align:center"|$06<br />
|style="border:0px;background-color:#651900;width:32px;height:32px;color:#fff;text-align:center"|$07<br />
|style="border:0px;background-color:#3B3600;width:32px;height:32px;color:#fff;text-align:center"|$08<br />
|style="border:0px;background-color:#0C4F00;width:32px;height:32px;color:#fff;text-align:center"|$09<br />
|style="border:0px;background-color:#005B00;width:32px;height:32px;color:#fff;text-align:center"|$0A<br />
|style="border:0px;background-color:#005900;width:32px;height:32px;color:#fff;text-align:center"|$0B<br />
|style="border:0px;background-color:#00494E;width:32px;height:32px;color:#fff;text-align:center"|$0C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|[[Color_$0D_games#Effects|<s style="color:red">$0D</s>]]<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$0E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$0F<br />
|-<br />
|style="border:0px;background-color:#ABABAB;width:32px;height:32px;color:#000;text-align:center"|$10<br />
|style="border:0px;background-color:#0064F4;width:32px;height:32px;color:#fff;text-align:center"|$11<br />
|style="border:0px;background-color:#353CFF;width:32px;height:32px;color:#fff;text-align:center"|$12<br />
|style="border:0px;background-color:#761BFF;width:32px;height:32px;color:#fff;text-align:center"|$13<br />
|style="border:0px;background-color:#AE0AF4;width:32px;height:32px;color:#fff;text-align:center"|$14<br />
|style="border:0px;background-color:#CF0C8F;width:32px;height:32px;color:#fff;text-align:center"|$15<br />
|style="border:0px;background-color:#CF231C;width:32px;height:32px;color:#fff;text-align:center"|$16<br />
|style="border:0px;background-color:#AE4700;width:32px;height:32px;color:#fff;text-align:center"|$17<br />
|style="border:0px;background-color:#766F00;width:32px;height:32px;color:#fff;text-align:center"|$18<br />
|style="border:0px;background-color:#359000;width:32px;height:32px;color:#fff;text-align:center"|$19<br />
|style="border:0px;background-color:#00A100;width:32px;height:32px;color:#fff;text-align:center"|$1A<br />
|style="border:0px;background-color:#009E1C;width:32px;height:32px;color:#fff;text-align:center"|$1B<br />
|style="border:0px;background-color:#00888F;width:32px;height:32px;color:#fff;text-align:center"|$1C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1F<br />
|-<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|$20<br />
|style="border:0px;background-color:#4AB5FF;width:32px;height:32px;color:#000;text-align:center"|$21<br />
|style="border:0px;background-color:#858CFF;width:32px;height:32px;color:#000;text-align:center"|$22<br />
|style="border:0px;background-color:#C86AFF;width:32px;height:32px;color:#000;text-align:center"|$23<br />
|style="border:0px;background-color:#FF58FF;width:32px;height:32px;color:#000;text-align:center"|$24<br />
|style="border:0px;background-color:#FF5BE2;width:32px;height:32px;color:#000;text-align:center"|$25<br />
|style="border:0px;background-color:#FF726A;width:32px;height:32px;color:#000;text-align:center"|$26<br />
|style="border:0px;background-color:#FF9702;width:32px;height:32px;color:#000;text-align:center"|$27<br />
|style="border:0px;background-color:#C8C100;width:32px;height:32px;color:#000;text-align:center"|$28<br />
|style="border:0px;background-color:#85E300;width:32px;height:32px;color:#000;text-align:center"|$29<br />
|style="border:0px;background-color:#4AF502;width:32px;height:32px;color:#000;text-align:center"|$2A<br />
|style="border:0px;background-color:#29F26A;width:32px;height:32px;color:#000;text-align:center"|$2B<br />
|style="border:0px;background-color:#29DBE2;width:32px;height:32px;color:#000;text-align:center"|$2C<br />
|style="border:0px;background-color:#4E4E4E;width:32px;height:32px;color:#fff;text-align:center"|$2D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$2E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$2F<br />
|-<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|$30<br />
|style="border:0px;background-color:#B6E1FF;width:32px;height:32px;color:#000;text-align:center"|$31<br />
|style="border:0px;background-color:#CED1FF;width:32px;height:32px;color:#000;text-align:center"|$32<br />
|style="border:0px;background-color:#E9C3FF;width:32px;height:32px;color:#000;text-align:center"|$33<br />
|style="border:0px;background-color:#FFBCFF;width:32px;height:32px;color:#000;text-align:center"|$34<br />
|style="border:0px;background-color:#FFBDF4;width:32px;height:32px;color:#000;text-align:center"|$35<br />
|style="border:0px;background-color:#FFC6C3;width:32px;height:32px;color:#000;text-align:center"|$36<br />
|style="border:0px;background-color:#FFD59A;width:32px;height:32px;color:#000;text-align:center"|$37<br />
|style="border:0px;background-color:#E9E681;width:32px;height:32px;color:#000;text-align:center"|$38<br />
|style="border:0px;background-color:#CEF481;width:32px;height:32px;color:#000;text-align:center"|$39<br />
|style="border:0px;background-color:#B6FB9A;width:32px;height:32px;color:#000;text-align:center"|$3A<br />
|style="border:0px;background-color:#A9FAC3;width:32px;height:32px;color:#000;text-align:center"|$3B<br />
|style="border:0px;background-color:#A9F0F4;width:32px;height:32px;color:#000;text-align:center"|$3C<br />
|style="border:0px;background-color:#B8B8B8;width:32px;height:32px;color:#000;text-align:center"|$3D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$3E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$3F<br />
|}<br />
<br />
=== 2C03 and 2C05 ===<br />
This palette is intentionally similar to the NES's standard palette, but notably is missing the greys in entries $2D and $3D.<br />
The 2C03 is used in ''Vs. Duck Hunt'', ''Vs. Tennis'', all PlayChoice games, and the Sharp C1 (Famicom TV).<br />
The 2C05 is used in some later Vs. games as a copy protection measure. A variant of the 2C05 without copy protection measures is present in the Sharp Famicom Titler, albeit with adjustments to the output (see below).<br />
Both have historically been used in RGB mods for the NES, as a circuit implementing <code>A0' = A0 xor (A1 nor A2)</code> can swap PPUCTRL and PPUMASK to make a 2C05 behave as a 2C03.<br />
<br />
The formula for mapping the DAC integer channel value to 8-bit per channel color is <code>C = 255 * DAC / 7</code>.<br />
<br />
{|class="wikitable"<br />
|-<br />
! style="text-align:center"|<br />
! style="text-align:center"|$x0<br />
! style="text-align:center"|$x1<br />
! style="text-align:center"|$x2<br />
! style="text-align:center"|$x3<br />
! style="text-align:center"|$x4<br />
! style="text-align:center"|$x5<br />
! style="text-align:center"|$x6<br />
! style="text-align:center"|$x7<br />
! style="text-align:center"|$x8<br />
! style="text-align:center"|$x9<br />
! style="text-align:center"|$xA<br />
! style="text-align:center"|$xB<br />
! style="text-align:center"|$xC<br />
! style="text-align:center"|$xD<br />
! style="text-align:center"|$xE<br />
! style="text-align:center"|$xF<br />
|-<br />
! style="text-align:center"|$0x<br />
|style="border:0px;background-color:#6D6D6D;width:32px;height:32px;color:#fff;text-align:center"|333<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|014<br />
|style="border:0px;background-color:#0000DA;width:32px;height:32px;color:#fff;text-align:center"|006<br />
|style="border:0px;background-color:#6D48DA;width:32px;height:32px;color:#fff;text-align:center"|326<br />
|style="border:0px;background-color:#91006D;width:32px;height:32px;color:#fff;text-align:center"|403<br />
|style="border:0px;background-color:#B6006D;width:32px;height:32px;color:#fff;text-align:center"|503<br />
|style="border:0px;background-color:#B62400;width:32px;height:32px;color:#fff;text-align:center"|510<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|420<br />
|style="border:0px;background-color:#6D4800;width:32px;height:32px;color:#fff;text-align:center"|320<br />
|style="border:0px;background-color:#244800;width:32px;height:32px;color:#fff;text-align:center"|120<br />
|style="border:0px;background-color:#006D24;width:32px;height:32px;color:#fff;text-align:center"|031<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|022<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|-<br />
! style="text-align:center"|$1x<br />
|style="border:0px;background-color:#B6B6B6;width:32px;height:32px;color:#000;text-align:center"|555<br />
|style="border:0px;background-color:#006DDA;width:32px;height:32px;color:#fff;text-align:center"|036<br />
|style="border:0px;background-color:#0048FF;width:32px;height:32px;color:#fff;text-align:center"|027<br />
|style="border:0px;background-color:#9100FF;width:32px;height:32px;color:#fff;text-align:center"|407<br />
|style="border:0px;background-color:#B600FF;width:32px;height:32px;color:#fff;text-align:center"|507<br />
|style="border:0px;background-color:#FF0091;width:32px;height:32px;color:#fff;text-align:center"|704<br />
|style="border:0px;background-color:#FF0000;width:32px;height:32px;color:#fff;text-align:center"|700<br />
|style="border:0px;background-color:#DA6D00;width:32px;height:32px;color:#000;text-align:center"|630<br />
|style="border:0px;background-color:#916D00;width:32px;height:32px;color:#fff;text-align:center"|430<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|140<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#00B66D;width:32px;height:32px;color:#fff;text-align:center"|053<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|044<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|-<br />
! style="text-align:center"|$2x<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#6DB6FF;width:32px;height:32px;color:#000;text-align:center"|357<br />
|style="border:0px;background-color:#9191FF;width:32px;height:32px;color:#000;text-align:center"|447<br />
|style="border:0px;background-color:#DA6DFF;width:32px;height:32px;color:#000;text-align:center"|637<br />
|style="border:0px;background-color:#FF00FF;width:32px;height:32px;color:#fff;text-align:center"|707<br />
|style="border:0px;background-color:#FF6DFF;width:32px;height:32px;color:#000;text-align:center"|737<br />
|style="border:0px;background-color:#FF9100;width:32px;height:32px;color:#000;text-align:center"|740<br />
|style="border:0px;background-color:#FFB600;width:32px;height:32px;color:#000;text-align:center"|750<br />
|style="border:0px;background-color:#DADA00;width:32px;height:32px;color:#000;text-align:center"|660<br />
|style="border:0px;background-color:#6DDA00;width:32px;height:32px;color:#000;text-align:center"|360<br />
|style="border:0px;background-color:#00FF00;width:32px;height:32px;color:#000;text-align:center"|070<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#00FFFF;width:32px;height:32px;color:#000;text-align:center"|077<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#777;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|-<br />
! style="text-align:center"|$3x<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#B6DAFF;width:32px;height:32px;color:#000;text-align:center"|567<br />
|style="border:0px;background-color:#DAB6FF;width:32px;height:32px;color:#000;text-align:center"|657<br />
|style="border:0px;background-color:#FFB6FF;width:32px;height:32px;color:#000;text-align:center"|757<br />
|style="border:0px;background-color:#FF91FF;width:32px;height:32px;color:#000;text-align:center"|747<br />
|style="border:0px;background-color:#FFB6B6;width:32px;height:32px;color:#000;text-align:center"|755<br />
|style="border:0px;background-color:#FFDA91;width:32px;height:32px;color:#000;text-align:center"|764<br />
|style="border:0px;background-color:#FFFF48;width:32px;height:32px;color:#000;text-align:center"|772<br />
|style="border:0px;background-color:#FFFF6D;width:32px;height:32px;color:#000;text-align:center"|773<br />
|style="border:0px;background-color:#B6FF48;width:32px;height:32px;color:#000;text-align:center"|572<br />
|style="border:0px;background-color:#91FF6D;width:32px;height:32px;color:#000;text-align:center"|473<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#91DAFF;width:32px;height:32px;color:#000;text-align:center"|467<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#777;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|}<br />
<br />
Note that some of the colors are duplicates: $0B and $1A = 040, $2B and $3B = 276.<br />
<br />
Monochrome works the same as the 2C02 (consistent across '''all''' RGB PPUs), but unlike the 2C02, emphasis on the RGB chips works differently; rather than "darkening" the specific color chosen, it sets the corresponding channel to full brightness instead.<br />
<br />
=== 2C05-99 ===<br />
<br />
The Sharp Famicom Titler (AN-510) contains a RC2C05-99 PPU, whose RGB output is fed into a X0858CE "encoder" chip. This chip handles the conversion from RGB(S) into Composite, and S-Video. In the process, it seems to also desaturate the output palette by encoding YIQ, but with a 0.5 gain on the Q channel (<code>Q = Q * 0.5</code>). Otherwise, the raw internal palette of the 2C05-99 PPU itself is believed to be identical to that of the 2C03. Due to technological limitations with video overlay (at the time), this was likely done in an attempt to make the RGB palette resemble its composite versions, as a standard 2C02 could not be used.<br />
<br />
{|class="wikitable"<br />
|-<br />
! style="text-align:center"|<br />
! style="text-align:center"|$x0<br />
! style="text-align:center"|$x1<br />
! style="text-align:center"|$x2<br />
! style="text-align:center"|$x3<br />
! style="text-align:center"|$x4<br />
! style="text-align:center"|$x5<br />
! style="text-align:center"|$x6<br />
! style="text-align:center"|$x7<br />
! style="text-align:center"|$x8<br />
! style="text-align:center"|$x9<br />
! style="text-align:center"|$xA<br />
! style="text-align:center"|$xB<br />
! style="text-align:center"|$xC<br />
! style="text-align:center"|$xD<br />
! style="text-align:center"|$xE<br />
! style="text-align:center"|$xF<br />
|-<br />
! style="text-align:center"|$0x<br />
|style="border:0px;background-color:#86858A;width:32px;height:32px;color:#fff;text-align:center"|$00<br />
|style="border:0px;background-color:#16317D;width:32px;height:32px;color:#fff;text-align:center"|$01<br />
|style="border:0px;background-color:#0B0995;width:32px;height:32px;color:#fff;text-align:center"|$02<br />
|style="border:0px;background-color:#8575C3;width:32px;height:32px;color:#fff;text-align:center"|$03<br />
|style="border:0px;background-color:#7E2F57;width:32px;height:32px;color:#fff;text-align:center"|$04<br />
|style="border:0px;background-color:#923457;width:32px;height:32px;color:#fff;text-align:center"|$05<br />
|style="border:0px;background-color:#98591C;width:32px;height:32px;color:#fff;text-align:center"|$06<br />
|style="border:0px;background-color:#896B27;width:32px;height:32px;color:#fff;text-align:center"|$07<br />
|style="border:0px;background-color:#605117;width:32px;height:32px;color:#fff;text-align:center"|$08<br />
|style="border:0px;background-color:#2C4013;width:32px;height:32px;color:#fff;text-align:center"|$09<br />
|style="border:0px;background-color:#155543;width:32px;height:32px;color:#fff;text-align:center"|$0A<br />
|style="border:0px;background-color:#1A6B29;width:32px;height:32px;color:#fff;text-align:center"|$0B<br />
|style="border:0px;background-color:#0C3C4D;width:32px;height:32px;color:#fff;text-align:center"|$0C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$0D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$0E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$0F<br />
|-<br />
! style="text-align:center"|$1x<br />
|style="border:0px;background-color:#CCCED2;width:32px;height:32px;color:#000;text-align:center"|$10<br />
|style="border:0px;background-color:#2768BB;width:32px;height:32px;color:#fff;text-align:center"|$11<br />
|style="border:0px;background-color:#1E4FC5;width:32px;height:32px;color:#fff;text-align:center"|$12<br />
|style="border:0px;background-color:#7C30AF;width:32px;height:32px;color:#fff;text-align:center"|$13<br />
|style="border:0px;background-color:#9638B2;width:32px;height:32px;color:#fff;text-align:center"|$14<br />
|style="border:0px;background-color:#BE4172;width:32px;height:32px;color:#fff;text-align:center"|$15<br />
|style="border:0px;background-color:#B13305;width:32px;height:32px;color:#fff;text-align:center"|$16<br />
|style="border:0px;background-color:#C09035;width:32px;height:32px;color:#fff;text-align:center"|$17<br />
|style="border:0px;background-color:#8C792D;width:32px;height:32px;color:#fff;text-align:center"|$18<br />
|style="border:0px;background-color:#497B32;width:32px;height:32px;color:#fff;text-align:center"|$19<br />
|style="border:0px;background-color:#1D6C2A;width:32px;height:32px;color:#fff;text-align:center"|$1A<br />
|style="border:0px;background-color:#31938A;width:32px;height:32px;color:#fff;text-align:center"|$1B<br />
|style="border:0px;background-color:#2D7C9A;width:32px;height:32px;color:#fff;text-align:center"|$1C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$1F<br />
|-<br />
! style="text-align:center"|$2x<br />
|style="border:0px;background-color:#FDFFFF;width:32px;height:32px;color:#000;text-align:center"|$20<br />
|style="border:0px;background-color:#96BDEF;width:32px;height:32px;color:#000;text-align:center"|$21<br />
|style="border:0px;background-color:#A2A8E6;width:32px;height:32px;color:#000;text-align:center"|$22<br />
|style="border:0px;background-color:#CE9FE0;width:32px;height:32px;color:#000;text-align:center"|$23<br />
|style="border:0px;background-color:#BF43B3;width:32px;height:32px;color:#fff;text-align:center"|$24<br />
|style="border:0px;background-color:#E6A7E5;width:32px;height:32px;color:#000;text-align:center"|$25<br />
|style="border:0px;background-color:#DCAB41;width:32px;height:32px;color:#000;text-align:center"|$26<br />
|style="border:0px;background-color:#E7C54B;width:32px;height:32px;color:#000;text-align:center"|$27<br />
|style="border:0px;background-color:#DFD85E;width:32px;height:32px;color:#000;text-align:center"|$28<br />
|style="border:0px;background-color:#92C150;width:32px;height:32px;color:#000;text-align:center"|$29<br />
|style="border:0px;background-color:#3FBB4A;width:32px;height:32px;color:#000;text-align:center"|$2A<br />
|style="border:0px;background-color:#96EAF2;width:32px;height:32px;color:#000;text-align:center"|$2B<br />
|style="border:0px;background-color:#53D8FD;width:32px;height:32px;color:#000;text-align:center"|$2C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#777;text-align:center"|$2D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$2E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$2F<br />
|-<br />
! style="text-align:center"|$3x<br />
|style="border:0px;background-color:#FDFFFF;width:32px;height:32px;color:#000;text-align:center"|$30<br />
|style="border:0px;background-color:#C7DFFA;width:32px;height:32px;color:#000;text-align:center"|$31<br />
|style="border:0px;background-color:#DACDF2;width:32px;height:32px;color:#000;text-align:center"|$32<br />
|style="border:0px;background-color:#F5D6F8;width:32px;height:32px;color:#000;text-align:center"|$33<br />
|style="border:0px;background-color:#EABCED;width:32px;height:32px;color:#000;text-align:center"|$34<br />
|style="border:0px;background-color:#EED1CA;width:32px;height:32px;color:#000;text-align:center"|$35<br />
|style="border:0px;background-color:#F5E7BC;width:32px;height:32px;color:#000;text-align:center"|$36<br />
|style="border:0px;background-color:#FCFB9C;width:32px;height:32px;color:#000;text-align:center"|$37<br />
|style="border:0px;background-color:#FFFFC0;width:32px;height:32px;color:#000;text-align:center"|$38<br />
|style="border:0px;background-color:#D8F4A2;width:32px;height:32px;color:#000;text-align:center"|$39<br />
|style="border:0px;background-color:#C2F0B5;width:32px;height:32px;color:#000;text-align:center"|$3A<br />
|style="border:0px;background-color:#96EAF2;width:32px;height:32px;color:#000;text-align:center"|$3B<br />
|style="border:0px;background-color:#BFE2FF;width:32px;height:32px;color:#000;text-align:center"|$3C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#777;text-align:center"|$3D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$3E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|$3F<br />
|}<br />
<br />
=== 2C04 ===<br />
All four 2C04 PPUs contain the same master palette, but in different permutations. It's almost a superset of the 2C03/5 palette, adding four greys, six other colors, and making the bright yellow more pure.<br />
<br />
Much like the 2C03 and 2C02, using the greyscale bit in [[PPUMASK]] will remap the palette by index, not by color. This means that with the scrambled palettes, each row will remap to the colors in the $0X column for that 2C04 version.<br />
<br />
Visualization tool: [https://www.nesdev.org/rgbppu/ RGB PPU Palette Converter]<br />
<br />
'''No version of the 2C04 was ever made with the below ordering''', but it shows the similarity to the 2C03:<br />
{|class="wikitable"<br />
|-<br />
|style="border:0px;background-color:#6D6D6D;width:32px;height:32px;color:#fff;text-align:center"|333<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|014<br />
|style="border:0px;background-color:#0000DA;width:32px;height:32px;color:#fff;text-align:center"|006<br />
|style="border:0px;background-color:#6D48DA;width:32px;height:32px;color:#fff;text-align:center"|326<br />
|style="border:0px;background-color:#91006D;width:32px;height:32px;color:#fff;text-align:center"|403<br />
|style="border:0px;background-color:#B6006D;width:32px;height:32px;color:#fff;text-align:center"|503<br />
|style="border:0px;background-color:#B62400;width:32px;height:32px;color:#fff;text-align:center"|510<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|420<br />
|style="border:0px;background-color:#6D4800;width:32px;height:32px;color:#fff;text-align:center"|320<br />
|style="border:0px;background-color:#244800;width:32px;height:32px;color:#fff;text-align:center"|120<br />
|style="border:0px;background-color:#006D24;width:32px;height:32px;color:#fff;text-align:center"|031<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|022<br />
|style="border:0px;background-color:#242424;width:32px;height:32px;color:#fff;text-align:center"|111<br />
|style="border:0px;background-color:#00006D;width:32px;height:32px;color:#fff;text-align:center"|003<br />
|style="border:0px;background-color:#004800;width:32px;height:32px;color:#fff;text-align:center"|020<br />
|-<br />
|style="border:0px;background-color:#B6B6B6;width:32px;height:32px;color:#000;text-align:center"|555<br />
|style="border:0px;background-color:#006DDA;width:32px;height:32px;color:#fff;text-align:center"|036<br />
|style="border:0px;background-color:#0048FF;width:32px;height:32px;color:#fff;text-align:center"|027<br />
|style="border:0px;background-color:#9100FF;width:32px;height:32px;color:#fff;text-align:center"|407<br />
|style="border:0px;background-color:#B600FF;width:32px;height:32px;color:#fff;text-align:center"|507<br />
|style="border:0px;background-color:#FF0091;width:32px;height:32px;color:#fff;text-align:center"|704<br />
|style="border:0px;background-color:#FF0000;width:32px;height:32px;color:#fff;text-align:center"|700<br />
|style="border:0px;background-color:#DA6D00;width:32px;height:32px;color:#000;text-align:center"|630<br />
|style="border:0px;background-color:#916D00;width:32px;height:32px;color:#fff;text-align:center"|430<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|140<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#00B66D;width:32px;height:32px;color:#fff;text-align:center"|053<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|044<br />
|style="border:0px;background-color:#484848;width:32px;height:32px;color:#fff;text-align:center"|222<br />
|style="border:0px;background-color:#480000;width:32px;height:32px;color:#fff;text-align:center"|200<br />
|style="border:0px;background-color:#6D2400;width:32px;height:32px;color:#fff;text-align:center"|310<br />
|-<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#6DB6FF;width:32px;height:32px;color:#000;text-align:center"|357<br />
|style="border:0px;background-color:#9191FF;width:32px;height:32px;color:#000;text-align:center"|447<br />
|style="border:0px;background-color:#DA6DFF;width:32px;height:32px;color:#000;text-align:center"|637<br />
|style="border:0px;background-color:#FF00FF;width:32px;height:32px;color:#fff;text-align:center"|707<br />
|style="border:0px;background-color:#FF6DFF;width:32px;height:32px;color:#000;text-align:center"|737<br />
|style="border:0px;background-color:#FF9100;width:32px;height:32px;color:#000;text-align:center"|740<br />
|style="border:0px;background-color:#FFB600;width:32px;height:32px;color:#000;text-align:center"|750<br />
|style="border:0px;background-color:#DADA00;width:32px;height:32px;color:#000;text-align:center"|660<br />
|style="border:0px;background-color:#6DDA00;width:32px;height:32px;color:#000;text-align:center"|360<br />
|style="border:0px;background-color:#00FF00;width:32px;height:32px;color:#000;text-align:center"|070<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#00FFFF;width:32px;height:32px;color:#000;text-align:center"|077<br />
|style="border:0px;background-color:#919191;width:32px;height:32px;color:#000;text-align:center"|444<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|-<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#B6DAFF;width:32px;height:32px;color:#000;text-align:center"|567<br />
|style="border:0px;background-color:#DAB6FF;width:32px;height:32px;color:#000;text-align:center"|657<br />
|style="border:0px;background-color:#FFB6FF;width:32px;height:32px;color:#000;text-align:center"|757<br />
|style="border:0px;background-color:#FF91FF;width:32px;height:32px;color:#000;text-align:center"|747<br />
|style="border:0px;background-color:#FFB6B6;width:32px;height:32px;color:#000;text-align:center"|755<br />
|style="border:0px;background-color:#FFDA91;width:32px;height:32px;color:#000;text-align:center"|764<br />
|style="border:0px;background-color:#FFFF00;width:32px;height:32px;color:#000;text-align:center"|770<br />
|style="border:0px;background-color:#FFFF6D;width:32px;height:32px;color:#000;text-align:center"|773<br />
|style="border:0px;background-color:#B6FF48;width:32px;height:32px;color:#000;text-align:center"|572<br />
|style="border:0px;background-color:#91FF6D;width:32px;height:32px;color:#000;text-align:center"|473<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#91DAFF;width:32px;height:32px;color:#000;text-align:center"|467<br />
|style="border:0px;background-color:#DADADA;width:32px;height:32px;color:#000;text-align:center"|666<br />
|style="border:0px;background-color:#DAB66D;width:32px;height:32px;color:#000;text-align:center"|653<br />
|style="border:0px;background-color:#FFDA00;width:32px;height:32px;color:#000;text-align:center"|760<br />
|}<br />
<!-- <br />
This image shows all the colors except the six shades of grey:<br />
<br />
[[Image:2C04_Palette_(Voronoi).png]] --><br />
The [[PPUMASK]] monochrome bit has the same implementation as on the 2C02, and so it has an unintuitive effect on the 2C04 PPUs; rather than forcing colors to grayscale, it instead forces them to the first column.<br />
<br />
==== RP2C04-0001 ====<br />
MAME's source claims that ''Baseball'', ''Freedom Force'', ''Gradius'', ''Hogan's Alley'', ''Mach Rider'', ''Pinball'', and ''Platoon'' require this palette.<br />
<br />
755,637,700,447,044,120,222,704,777,333,750,503,403,660,320,777<br />
357,653,310,360,467,657,764,027,760,276,000,200,666,444,707,014<br />
003,567,757,070,077,022,053,507,000,420,747,510,407,006,740,000<br />
000,140,555,031,572,326,770,630,020,036,040,111,773,737,430,473<br />
<br />
<div style="margin-left: 2em;"><br />
<div class="mw-collapsible mw-collapsed" style="border:1px solid #a2a9b1; padding: 5px; display: inline-block; min-width: 25em; overflow:auto;"><br />
<div style="font-weight:bold;line-height:1.6;">Palette colors</div><br />
<div class="mw-collapsible-content"><br />
{|class="wikitable"<br />
|-<br />
! style="text-align:center"|<br />
! style="text-align:center"|$x0<br />
! style="text-align:center"|$x1<br />
! style="text-align:center"|$x2<br />
! style="text-align:center"|$x3<br />
! style="text-align:center"|$x4<br />
! style="text-align:center"|$x5<br />
! style="text-align:center"|$x6<br />
! style="text-align:center"|$x7<br />
! style="text-align:center"|$x8<br />
! style="text-align:center"|$x9<br />
! style="text-align:center"|$xA<br />
! style="text-align:center"|$xB<br />
! style="text-align:center"|$xC<br />
! style="text-align:center"|$xD<br />
! style="text-align:center"|$xE<br />
! style="text-align:center"|$xF<br />
|-<br />
! style="text-align:center"|$0x<br />
|style="border:0px;background-color:#FFB6B6;width:32px;height:32px;color:#000;text-align:center"|755<br />
|style="border:0px;background-color:#DA6DFF;width:32px;height:32px;color:#000;text-align:center"|637<br />
|style="border:0px;background-color:#FF0000;width:32px;height:32px;color:#fff;text-align:center"|700<br />
|style="border:0px;background-color:#9191FF;width:32px;height:32px;color:#000;text-align:center"|447<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|044<br />
|style="border:0px;background-color:#244800;width:32px;height:32px;color:#fff;text-align:center"|120<br />
|style="border:0px;background-color:#484848;width:32px;height:32px;color:#fff;text-align:center"|222<br />
|style="border:0px;background-color:#FF0091;width:32px;height:32px;color:#fff;text-align:center"|704<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#6D6D6D;width:32px;height:32px;color:#fff;text-align:center"|333<br />
|style="border:0px;background-color:#FFB600;width:32px;height:32px;color:#000;text-align:center"|750<br />
|style="border:0px;background-color:#B6006D;width:32px;height:32px;color:#fff;text-align:center"|503<br />
|style="border:0px;background-color:#91006D;width:32px;height:32px;color:#fff;text-align:center"|403<br />
|style="border:0px;background-color:#DADA00;width:32px;height:32px;color:#000;text-align:center"|660<br />
|style="border:0px;background-color:#6D4800;width:32px;height:32px;color:#fff;text-align:center"|320<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|-<br />
! style="text-align:center"|$1x<br />
|style="border:0px;background-color:#6DB6FF;width:32px;height:32px;color:#000;text-align:center"|357<br />
|style="border:0px;background-color:#DAB66D;width:32px;height:32px;color:#000;text-align:center"|653<br />
|style="border:0px;background-color:#6D2400;width:32px;height:32px;color:#fff;text-align:center"|310<br />
|style="border:0px;background-color:#6DDA00;width:32px;height:32px;color:#000;text-align:center"|360<br />
|style="border:0px;background-color:#91DAFF;width:32px;height:32px;color:#000;text-align:center"|467<br />
|style="border:0px;background-color:#DAB6FF;width:32px;height:32px;color:#000;text-align:center"|657<br />
|style="border:0px;background-color:#FFDA91;width:32px;height:32px;color:#000;text-align:center"|764<br />
|style="border:0px;background-color:#0048FF;width:32px;height:32px;color:#fff;text-align:center"|027<br />
|style="border:0px;background-color:#FFDA00;width:32px;height:32px;color:#000;text-align:center"|760<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#480000;width:32px;height:32px;color:#fff;text-align:center"|200<br />
|style="border:0px;background-color:#DADADA;width:32px;height:32px;color:#000;text-align:center"|666<br />
|style="border:0px;background-color:#919191;width:32px;height:32px;color:#000;text-align:center"|444<br />
|style="border:0px;background-color:#FF00FF;width:32px;height:32px;color:#fff;text-align:center"|707<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|014<br />
|-<br />
! style="text-align:center"|$2x<br />
|style="border:0px;background-color:#00006D;width:32px;height:32px;color:#fff;text-align:center"|003<br />
|style="border:0px;background-color:#B6DAFF;width:32px;height:32px;color:#000;text-align:center"|567<br />
|style="border:0px;background-color:#FFB6FF;width:32px;height:32px;color:#000;text-align:center"|757<br />
|style="border:0px;background-color:#00FF00;width:32px;height:32px;color:#000;text-align:center"|070<br />
|style="border:0px;background-color:#00FFFF;width:32px;height:32px;color:#000;text-align:center"|077<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|022<br />
|style="border:0px;background-color:#00B66D;width:32px;height:32px;color:#fff;text-align:center"|053<br />
|style="border:0px;background-color:#B600FF;width:32px;height:32px;color:#fff;text-align:center"|507<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|420<br />
|style="border:0px;background-color:#FF91FF;width:32px;height:32px;color:#000;text-align:center"|747<br />
|style="border:0px;background-color:#B62400;width:32px;height:32px;color:#fff;text-align:center"|510<br />
|style="border:0px;background-color:#9100FF;width:32px;height:32px;color:#fff;text-align:center"|407<br />
|style="border:0px;background-color:#0000DA;width:32px;height:32px;color:#fff;text-align:center"|006<br />
|style="border:0px;background-color:#FF9100;width:32px;height:32px;color:#000;text-align:center"|740<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|-<br />
! style="text-align:center"|$3x<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|140<br />
|style="border:0px;background-color:#B6B6B6;width:32px;height:32px;color:#000;text-align:center"|555<br />
|style="border:0px;background-color:#006D24;width:32px;height:32px;color:#fff;text-align:center"|031<br />
|style="border:0px;background-color:#B6FF48;width:32px;height:32px;color:#000;text-align:center"|572<br />
|style="border:0px;background-color:#6D48DA;width:32px;height:32px;color:#fff;text-align:center"|326<br />
|style="border:0px;background-color:#FFFF00;width:32px;height:32px;color:#000;text-align:center"|770<br />
|style="border:0px;background-color:#DA6D00;width:32px;height:32px;color:#000;text-align:center"|630<br />
|style="border:0px;background-color:#004800;width:32px;height:32px;color:#fff;text-align:center"|020<br />
|style="border:0px;background-color:#006DDA;width:32px;height:32px;color:#fff;text-align:center"|036<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#242424;width:32px;height:32px;color:#fff;text-align:center"|111<br />
|style="border:0px;background-color:#FFFF6D;width:32px;height:32px;color:#000;text-align:center"|773<br />
|style="border:0px;background-color:#FF6DFF;width:32px;height:32px;color:#000;text-align:center"|737<br />
|style="border:0px;background-color:#916D00;width:32px;height:32px;color:#fff;text-align:center"|430<br />
|style="border:0px;background-color:#91FF6D;width:32px;height:32px;color:#000;text-align:center"|473<br />
|}<br />
</div></div></div><br />
<br />
==== RP2C04-0002 ====<br />
MAME's source claims that ''Castlevania'', ''Mach Rider (Endurance Course)'', ''Raid on Bungeling Bay'', ''Slalom'', ''Soccer'', ''Stroke & Match Golf'' (both versions), and ''Wrecking Crew'' require this palette.<br />
<br />
000,750,430,572,473,737,044,567,700,407,773,747,777,637,467,040<br />
020,357,510,666,053,360,200,447,222,707,003,276,657,320,000,326<br />
403,764,740,757,036,310,555,006,507,760,333,120,027,000,660,777<br />
653,111,070,630,022,014,704,140,000,077,420,770,755,503,031,444<br />
<br />
<div style="margin-left: 2em;"><br />
<div class="mw-collapsible mw-collapsed" style="border:1px solid #a2a9b1; padding: 5px; display: inline-block; min-width: 25em; overflow:auto;"><br />
<div style="font-weight:bold;line-height:1.6;">Palette colors</div><br />
<div class="mw-collapsible-content"><br />
{|class="wikitable"<br />
|-<br />
! style="text-align:center"|<br />
! style="text-align:center"|$x0<br />
! style="text-align:center"|$x1<br />
! style="text-align:center"|$x2<br />
! style="text-align:center"|$x3<br />
! style="text-align:center"|$x4<br />
! style="text-align:center"|$x5<br />
! style="text-align:center"|$x6<br />
! style="text-align:center"|$x7<br />
! style="text-align:center"|$x8<br />
! style="text-align:center"|$x9<br />
! style="text-align:center"|$xA<br />
! style="text-align:center"|$xB<br />
! style="text-align:center"|$xC<br />
! style="text-align:center"|$xD<br />
! style="text-align:center"|$xE<br />
! style="text-align:center"|$xF<br />
|-<br />
! style="text-align:center"|$0x<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#FFB600;width:32px;height:32px;color:#000;text-align:center"|750<br />
|style="border:0px;background-color:#916D00;width:32px;height:32px;color:#fff;text-align:center"|430<br />
|style="border:0px;background-color:#B6FF48;width:32px;height:32px;color:#000;text-align:center"|572<br />
|style="border:0px;background-color:#91FF6D;width:32px;height:32px;color:#000;text-align:center"|473<br />
|style="border:0px;background-color:#FF6DFF;width:32px;height:32px;color:#000;text-align:center"|737<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|044<br />
|style="border:0px;background-color:#B6DAFF;width:32px;height:32px;color:#000;text-align:center"|567<br />
|style="border:0px;background-color:#FF0000;width:32px;height:32px;color:#fff;text-align:center"|700<br />
|style="border:0px;background-color:#9100FF;width:32px;height:32px;color:#fff;text-align:center"|407<br />
|style="border:0px;background-color:#FFFF6D;width:32px;height:32px;color:#000;text-align:center"|773<br />
|style="border:0px;background-color:#FF91FF;width:32px;height:32px;color:#000;text-align:center"|747<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#DA6DFF;width:32px;height:32px;color:#000;text-align:center"|637<br />
|style="border:0px;background-color:#91DAFF;width:32px;height:32px;color:#000;text-align:center"|467<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|-<br />
! style="text-align:center"|$1x<br />
|style="border:0px;background-color:#004800;width:32px;height:32px;color:#fff;text-align:center"|020<br />
|style="border:0px;background-color:#6DB6FF;width:32px;height:32px;color:#000;text-align:center"|357<br />
|style="border:0px;background-color:#B62400;width:32px;height:32px;color:#fff;text-align:center"|510<br />
|style="border:0px;background-color:#DADADA;width:32px;height:32px;color:#000;text-align:center"|666<br />
|style="border:0px;background-color:#00B66D;width:32px;height:32px;color:#fff;text-align:center"|053<br />
|style="border:0px;background-color:#6DDA00;width:32px;height:32px;color:#000;text-align:center"|360<br />
|style="border:0px;background-color:#480000;width:32px;height:32px;color:#fff;text-align:center"|200<br />
|style="border:0px;background-color:#9191FF;width:32px;height:32px;color:#000;text-align:center"|447<br />
|style="border:0px;background-color:#484848;width:32px;height:32px;color:#fff;text-align:center"|222<br />
|style="border:0px;background-color:#FF00FF;width:32px;height:32px;color:#fff;text-align:center"|707<br />
|style="border:0px;background-color:#00006D;width:32px;height:32px;color:#fff;text-align:center"|003<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#DAB6FF;width:32px;height:32px;color:#000;text-align:center"|657<br />
|style="border:0px;background-color:#6D4800;width:32px;height:32px;color:#fff;text-align:center"|320<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#6D48DA;width:32px;height:32px;color:#fff;text-align:center"|326<br />
|-<br />
! style="text-align:center"|$2x<br />
|style="border:0px;background-color:#91006D;width:32px;height:32px;color:#fff;text-align:center"|403<br />
|style="border:0px;background-color:#FFDA91;width:32px;height:32px;color:#000;text-align:center"|764<br />
|style="border:0px;background-color:#FF9100;width:32px;height:32px;color:#000;text-align:center"|740<br />
|style="border:0px;background-color:#FFB6FF;width:32px;height:32px;color:#000;text-align:center"|757<br />
|style="border:0px;background-color:#006DDA;width:32px;height:32px;color:#fff;text-align:center"|036<br />
|style="border:0px;background-color:#6D2400;width:32px;height:32px;color:#fff;text-align:center"|310<br />
|style="border:0px;background-color:#B6B6B6;width:32px;height:32px;color:#000;text-align:center"|555<br />
|style="border:0px;background-color:#0000DA;width:32px;height:32px;color:#fff;text-align:center"|006<br />
|style="border:0px;background-color:#B600FF;width:32px;height:32px;color:#fff;text-align:center"|507<br />
|style="border:0px;background-color:#FFDA00;width:32px;height:32px;color:#000;text-align:center"|760<br />
|style="border:0px;background-color:#6D6D6D;width:32px;height:32px;color:#fff;text-align:center"|333<br />
|style="border:0px;background-color:#244800;width:32px;height:32px;color:#fff;text-align:center"|120<br />
|style="border:0px;background-color:#0048FF;width:32px;height:32px;color:#fff;text-align:center"|027<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#DADA00;width:32px;height:32px;color:#000;text-align:center"|660<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|-<br />
! style="text-align:center"|$3x<br />
|style="border:0px;background-color:#DAB66D;width:32px;height:32px;color:#000;text-align:center"|653<br />
|style="border:0px;background-color:#242424;width:32px;height:32px;color:#fff;text-align:center"|111<br />
|style="border:0px;background-color:#00FF00;width:32px;height:32px;color:#000;text-align:center"|070<br />
|style="border:0px;background-color:#DA6D00;width:32px;height:32px;color:#000;text-align:center"|630<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|022<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|014<br />
|style="border:0px;background-color:#FF0091;width:32px;height:32px;color:#fff;text-align:center"|704<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|140<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#00FFFF;width:32px;height:32px;color:#000;text-align:center"|077<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|420<br />
|style="border:0px;background-color:#FFFF00;width:32px;height:32px;color:#000;text-align:center"|770<br />
|style="border:0px;background-color:#FFB6B6;width:32px;height:32px;color:#000;text-align:center"|755<br />
|style="border:0px;background-color:#B6006D;width:32px;height:32px;color:#fff;text-align:center"|503<br />
|style="border:0px;background-color:#006D24;width:32px;height:32px;color:#fff;text-align:center"|031<br />
|style="border:0px;background-color:#919191;width:32px;height:32px;color:#000;text-align:center"|444<br />
|}<br />
</div></div></div><br />
<br />
==== RP2C04-0003 ====<br />
MAME's source claims that ''Balloon Fight'', ''Dr. Mario'', ''Excitebike'' (US), ''Goonies'', and ''Soccer'' require this palette.<br />
<br />
507,737,473,555,040,777,567,120,014,000,764,320,704,666,653,467<br />
447,044,503,027,140,430,630,053,333,326,000,006,700,510,747,755<br />
637,020,003,770,111,750,740,777,360,403,357,707,036,444,000,310<br />
077,200,572,757,420,070,660,222,031,000,657,773,407,276,760,022<br />
<br />
<div style="margin-left: 2em;"><br />
<div class="mw-collapsible mw-collapsed" style="border:1px solid #a2a9b1; padding: 5px; display: inline-block; min-width: 25em; overflow:auto;"><br />
<div style="font-weight:bold;line-height:1.6;">Palette colors</div><br />
<div class="mw-collapsible-content"><br />
{|class="wikitable"<br />
|-<br />
! style="text-align:center"|<br />
! style="text-align:center"|$x0<br />
! style="text-align:center"|$x1<br />
! style="text-align:center"|$x2<br />
! style="text-align:center"|$x3<br />
! style="text-align:center"|$x4<br />
! style="text-align:center"|$x5<br />
! style="text-align:center"|$x6<br />
! style="text-align:center"|$x7<br />
! style="text-align:center"|$x8<br />
! style="text-align:center"|$x9<br />
! style="text-align:center"|$xA<br />
! style="text-align:center"|$xB<br />
! style="text-align:center"|$xC<br />
! style="text-align:center"|$xD<br />
! style="text-align:center"|$xE<br />
! style="text-align:center"|$xF<br />
|-<br />
! style="text-align:center"|$0x<br />
|style="border:0px;background-color:#B600FF;width:32px;height:32px;color:#fff;text-align:center"|507<br />
|style="border:0px;background-color:#FF6DFF;width:32px;height:32px;color:#000;text-align:center"|737<br />
|style="border:0px;background-color:#91FF6D;width:32px;height:32px;color:#000;text-align:center"|473<br />
|style="border:0px;background-color:#B6B6B6;width:32px;height:32px;color:#000;text-align:center"|555<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#B6DAFF;width:32px;height:32px;color:#000;text-align:center"|567<br />
|style="border:0px;background-color:#244800;width:32px;height:32px;color:#fff;text-align:center"|120<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|014<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#FFDA91;width:32px;height:32px;color:#000;text-align:center"|764<br />
|style="border:0px;background-color:#6D4800;width:32px;height:32px;color:#fff;text-align:center"|320<br />
|style="border:0px;background-color:#FF0091;width:32px;height:32px;color:#fff;text-align:center"|704<br />
|style="border:0px;background-color:#DADADA;width:32px;height:32px;color:#000;text-align:center"|666<br />
|style="border:0px;background-color:#DAB66D;width:32px;height:32px;color:#000;text-align:center"|653<br />
|style="border:0px;background-color:#91DAFF;width:32px;height:32px;color:#000;text-align:center"|467<br />
|-<br />
! style="text-align:center"|$1x<br />
|style="border:0px;background-color:#9191FF;width:32px;height:32px;color:#000;text-align:center"|447<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|044<br />
|style="border:0px;background-color:#B6006D;width:32px;height:32px;color:#fff;text-align:center"|503<br />
|style="border:0px;background-color:#0048FF;width:32px;height:32px;color:#fff;text-align:center"|027<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|140<br />
|style="border:0px;background-color:#916D00;width:32px;height:32px;color:#fff;text-align:center"|430<br />
|style="border:0px;background-color:#DA6D00;width:32px;height:32px;color:#000;text-align:center"|630<br />
|style="border:0px;background-color:#00B66D;width:32px;height:32px;color:#fff;text-align:center"|053<br />
|style="border:0px;background-color:#6D6D6D;width:32px;height:32px;color:#fff;text-align:center"|333<br />
|style="border:0px;background-color:#6D48DA;width:32px;height:32px;color:#fff;text-align:center"|326<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#0000DA;width:32px;height:32px;color:#fff;text-align:center"|006<br />
|style="border:0px;background-color:#FF0000;width:32px;height:32px;color:#fff;text-align:center"|700<br />
|style="border:0px;background-color:#B62400;width:32px;height:32px;color:#fff;text-align:center"|510<br />
|style="border:0px;background-color:#FF91FF;width:32px;height:32px;color:#000;text-align:center"|747<br />
|style="border:0px;background-color:#FFB6B6;width:32px;height:32px;color:#000;text-align:center"|755<br />
|-<br />
! style="text-align:center"|$2x<br />
|style="border:0px;background-color:#DA6DFF;width:32px;height:32px;color:#000;text-align:center"|637<br />
|style="border:0px;background-color:#004800;width:32px;height:32px;color:#fff;text-align:center"|020<br />
|style="border:0px;background-color:#00006D;width:32px;height:32px;color:#fff;text-align:center"|003<br />
|style="border:0px;background-color:#FFFF00;width:32px;height:32px;color:#000;text-align:center"|770<br />
|style="border:0px;background-color:#242424;width:32px;height:32px;color:#fff;text-align:center"|111<br />
|style="border:0px;background-color:#FFB600;width:32px;height:32px;color:#000;text-align:center"|750<br />
|style="border:0px;background-color:#FF9100;width:32px;height:32px;color:#000;text-align:center"|740<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#6DDA00;width:32px;height:32px;color:#000;text-align:center"|360<br />
|style="border:0px;background-color:#91006D;width:32px;height:32px;color:#fff;text-align:center"|403<br />
|style="border:0px;background-color:#6DB6FF;width:32px;height:32px;color:#000;text-align:center"|357<br />
|style="border:0px;background-color:#FF00FF;width:32px;height:32px;color:#fff;text-align:center"|707<br />
|style="border:0px;background-color:#006DDA;width:32px;height:32px;color:#fff;text-align:center"|036<br />
|style="border:0px;background-color:#919191;width:32px;height:32px;color:#000;text-align:center"|444<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#6D2400;width:32px;height:32px;color:#fff;text-align:center"|310<br />
|-<br />
! style="text-align:center"|$3x<br />
|style="border:0px;background-color:#00FFFF;width:32px;height:32px;color:#000;text-align:center"|077<br />
|style="border:0px;background-color:#480000;width:32px;height:32px;color:#fff;text-align:center"|200<br />
|style="border:0px;background-color:#B6FF48;width:32px;height:32px;color:#000;text-align:center"|572<br />
|style="border:0px;background-color:#FFB6FF;width:32px;height:32px;color:#000;text-align:center"|757<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|420<br />
|style="border:0px;background-color:#00FF00;width:32px;height:32px;color:#000;text-align:center"|070<br />
|style="border:0px;background-color:#DADA00;width:32px;height:32px;color:#000;text-align:center"|660<br />
|style="border:0px;background-color:#484848;width:32px;height:32px;color:#fff;text-align:center"|222<br />
|style="border:0px;background-color:#006D24;width:32px;height:32px;color:#fff;text-align:center"|031<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#DAB6FF;width:32px;height:32px;color:#000;text-align:center"|657<br />
|style="border:0px;background-color:#FFFF6D;width:32px;height:32px;color:#000;text-align:center"|773<br />
|style="border:0px;background-color:#9100FF;width:32px;height:32px;color:#fff;text-align:center"|407<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#FFDA00;width:32px;height:32px;color:#000;text-align:center"|760<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|022<br />
|}<br />
</div></div></div><br />
<br />
==== RP2C04-0004 ====<br />
MAME's source claims that ''Clu Clu Land'', ''Excitebike'' (Japan), ''Ice Climber'' (both versions), and ''Super Mario Bros.'' require this palette.<br />
<br />
430,326,044,660,000,755,014,630,555,310,070,003,764,770,040,572<br />
737,200,027,747,000,222,510,740,653,053,447,140,403,000,473,357<br />
503,031,420,006,407,507,333,704,022,666,036,020,111,773,444,707<br />
757,777,320,700,760,276,777,467,000,750,637,567,360,657,077,120<br />
<br />
<div style="margin-left: 2em;"><br />
<div class="mw-collapsible mw-collapsed" style="border:1px solid #a2a9b1; padding: 5px; display: inline-block; min-width: 25em; overflow:auto;"><br />
<div style="font-weight:bold;line-height:1.6;">Palette colors</div><br />
<div class="mw-collapsible-content"><br />
{|class="wikitable"<br />
|-<br />
! style="text-align:center"|<br />
! style="text-align:center"|$x0<br />
! style="text-align:center"|$x1<br />
! style="text-align:center"|$x2<br />
! style="text-align:center"|$x3<br />
! style="text-align:center"|$x4<br />
! style="text-align:center"|$x5<br />
! style="text-align:center"|$x6<br />
! style="text-align:center"|$x7<br />
! style="text-align:center"|$x8<br />
! style="text-align:center"|$x9<br />
! style="text-align:center"|$xA<br />
! style="text-align:center"|$xB<br />
! style="text-align:center"|$xC<br />
! style="text-align:center"|$xD<br />
! style="text-align:center"|$xE<br />
! style="text-align:center"|$xF<br />
|-<br />
! style="text-align:center"|$0x<br />
|style="border:0px;background-color:#916D00;width:32px;height:32px;color:#fff;text-align:center"|430<br />
|style="border:0px;background-color:#6D48DA;width:32px;height:32px;color:#fff;text-align:center"|326<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|044<br />
|style="border:0px;background-color:#DADA00;width:32px;height:32px;color:#000;text-align:center"|660<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#FFB6B6;width:32px;height:32px;color:#000;text-align:center"|755<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|014<br />
|style="border:0px;background-color:#DA6D00;width:32px;height:32px;color:#000;text-align:center"|630<br />
|style="border:0px;background-color:#B6B6B6;width:32px;height:32px;color:#000;text-align:center"|555<br />
|style="border:0px;background-color:#6D2400;width:32px;height:32px;color:#fff;text-align:center"|310<br />
|style="border:0px;background-color:#00FF00;width:32px;height:32px;color:#000;text-align:center"|070<br />
|style="border:0px;background-color:#00006D;width:32px;height:32px;color:#fff;text-align:center"|003<br />
|style="border:0px;background-color:#FFDA91;width:32px;height:32px;color:#000;text-align:center"|764<br />
|style="border:0px;background-color:#FFFF00;width:32px;height:32px;color:#000;text-align:center"|770<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#B6FF48;width:32px;height:32px;color:#000;text-align:center"|572<br />
|-<br />
! style="text-align:center"|$1x<br />
|style="border:0px;background-color:#FF6DFF;width:32px;height:32px;color:#000;text-align:center"|737<br />
|style="border:0px;background-color:#480000;width:32px;height:32px;color:#fff;text-align:center"|200<br />
|style="border:0px;background-color:#0048FF;width:32px;height:32px;color:#fff;text-align:center"|027<br />
|style="border:0px;background-color:#FF91FF;width:32px;height:32px;color:#000;text-align:center"|747<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#484848;width:32px;height:32px;color:#fff;text-align:center"|222<br />
|style="border:0px;background-color:#B62400;width:32px;height:32px;color:#fff;text-align:center"|510<br />
|style="border:0px;background-color:#FF9100;width:32px;height:32px;color:#000;text-align:center"|740<br />
|style="border:0px;background-color:#DAB66D;width:32px;height:32px;color:#000;text-align:center"|653<br />
|style="border:0px;background-color:#00B66D;width:32px;height:32px;color:#fff;text-align:center"|053<br />
|style="border:0px;background-color:#9191FF;width:32px;height:32px;color:#000;text-align:center"|447<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|140<br />
|style="border:0px;background-color:#91006D;width:32px;height:32px;color:#fff;text-align:center"|403<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#91FF6D;width:32px;height:32px;color:#000;text-align:center"|473<br />
|style="border:0px;background-color:#6DB6FF;width:32px;height:32px;color:#000;text-align:center"|357<br />
|-<br />
! style="text-align:center"|$2x<br />
|style="border:0px;background-color:#B6006D;width:32px;height:32px;color:#fff;text-align:center"|503<br />
|style="border:0px;background-color:#006D24;width:32px;height:32px;color:#fff;text-align:center"|031<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|420<br />
|style="border:0px;background-color:#0000DA;width:32px;height:32px;color:#fff;text-align:center"|006<br />
|style="border:0px;background-color:#9100FF;width:32px;height:32px;color:#fff;text-align:center"|407<br />
|style="border:0px;background-color:#B600FF;width:32px;height:32px;color:#fff;text-align:center"|507<br />
|style="border:0px;background-color:#6D6D6D;width:32px;height:32px;color:#fff;text-align:center"|333<br />
|style="border:0px;background-color:#FF0091;width:32px;height:32px;color:#fff;text-align:center"|704<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|022<br />
|style="border:0px;background-color:#DADADA;width:32px;height:32px;color:#000;text-align:center"|666<br />
|style="border:0px;background-color:#006DDA;width:32px;height:32px;color:#fff;text-align:center"|036<br />
|style="border:0px;background-color:#004800;width:32px;height:32px;color:#fff;text-align:center"|020<br />
|style="border:0px;background-color:#242424;width:32px;height:32px;color:#fff;text-align:center"|111<br />
|style="border:0px;background-color:#FFFF6D;width:32px;height:32px;color:#000;text-align:center"|773<br />
|style="border:0px;background-color:#919191;width:32px;height:32px;color:#000;text-align:center"|444<br />
|style="border:0px;background-color:#FF00FF;width:32px;height:32px;color:#fff;text-align:center"|707<br />
|-<br />
! style="text-align:center"|$3x<br />
|style="border:0px;background-color:#FFB6FF;width:32px;height:32px;color:#000;text-align:center"|757<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#6D4800;width:32px;height:32px;color:#fff;text-align:center"|320<br />
|style="border:0px;background-color:#FF0000;width:32px;height:32px;color:#fff;text-align:center"|700<br />
|style="border:0px;background-color:#FFDA00;width:32px;height:32px;color:#000;text-align:center"|760<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#91DAFF;width:32px;height:32px;color:#000;text-align:center"|467<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#FFB600;width:32px;height:32px;color:#000;text-align:center"|750<br />
|style="border:0px;background-color:#DA6DFF;width:32px;height:32px;color:#000;text-align:center"|637<br />
|style="border:0px;background-color:#B6DAFF;width:32px;height:32px;color:#000;text-align:center"|567<br />
|style="border:0px;background-color:#6DDA00;width:32px;height:32px;color:#000;text-align:center"|360<br />
|style="border:0px;background-color:#DAB6FF;width:32px;height:32px;color:#000;text-align:center"|657<br />
|style="border:0px;background-color:#00FFFF;width:32px;height:32px;color:#000;text-align:center"|077<br />
|style="border:0px;background-color:#244800;width:32px;height:32px;color:#fff;text-align:center"|120<br />
|}<br />
</div></div></div><br />
<br />
==== Games compatible with multiple different PPUs ====<br />
Some games don't require that arcade owners have the correct physical PPU.<br />
<br />
At the very least, the following games use some of the DIP switches to support multiple different PPUs:<br />
* Atari RBI Baseball<br />
* Battle City<br />
* Star Luster<br />
* Super Sky Kid<br />
* Super Xevious<br />
* Tetris (Tengen)<br />
* TKO Boxing<br />
<br />
==== LUT approach ====<br />
<br />
Emulator authors may implement the 2C04 variants as a LUT indexing the "ordered" palette. This has the added advantage of being able to use preexisting .pal files if the end user wishes to do so.<br />
<br />
Repeating colors such as 000 and 777 may index into the same entry of the "ordered" palette, as this is functionally identical.<br />
<nowiki>const unsigned char PaletteLUT_2C04_0001 [64] ={<br />
0x35,0x23,0x16,0x22,0x1C,0x09,0x1D,0x15,0x20,0x00,0x27,0x05,0x04,0x28,0x08,0x20,<br />
0x21,0x3E,0x1F,0x29,0x3C,0x32,0x36,0x12,0x3F,0x2B,0x2E,0x1E,0x3D,0x2D,0x24,0x01,<br />
0x0E,0x31,0x33,0x2A,0x2C,0x0C,0x1B,0x14,0x2E,0x07,0x34,0x06,0x13,0x02,0x26,0x2E,<br />
0x2E,0x19,0x10,0x0A,0x39,0x03,0x37,0x17,0x0F,0x11,0x0B,0x0D,0x38,0x25,0x18,0x3A<br />
};<br />
<br />
const unsigned char PaletteLUT_2C04_0002 [64] ={<br />
0x2E,0x27,0x18,0x39,0x3A,0x25,0x1C,0x31,0x16,0x13,0x38,0x34,0x20,0x23,0x3C,0x0B,<br />
0x0F,0x21,0x06,0x3D,0x1B,0x29,0x1E,0x22,0x1D,0x24,0x0E,0x2B,0x32,0x08,0x2E,0x03,<br />
0x04,0x36,0x26,0x33,0x11,0x1F,0x10,0x02,0x14,0x3F,0x00,0x09,0x12,0x2E,0x28,0x20,<br />
0x3E,0x0D,0x2A,0x17,0x0C,0x01,0x15,0x19,0x2E,0x2C,0x07,0x37,0x35,0x05,0x0A,0x2D<br />
};<br />
<br />
const unsigned char PaletteLUT_2C04_0003 [64] ={<br />
0x14,0x25,0x3A,0x10,0x0B,0x20,0x31,0x09,0x01,0x2E,0x36,0x08,0x15,0x3D,0x3E,0x3C,<br />
0x22,0x1C,0x05,0x12,0x19,0x18,0x17,0x1B,0x00,0x03,0x2E,0x02,0x16,0x06,0x34,0x35,<br />
0x23,0x0F,0x0E,0x37,0x0D,0x27,0x26,0x20,0x29,0x04,0x21,0x24,0x11,0x2D,0x2E,0x1F,<br />
0x2C,0x1E,0x39,0x33,0x07,0x2A,0x28,0x1D,0x0A,0x2E,0x32,0x38,0x13,0x2B,0x3F,0x0C<br />
};<br />
<br />
const unsigned char PaletteLUT_2C04_0004 [64] ={<br />
0x18,0x03,0x1C,0x28,0x2E,0x35,0x01,0x17,0x10,0x1F,0x2A,0x0E,0x36,0x37,0x0B,0x39,<br />
0x25,0x1E,0x12,0x34,0x2E,0x1D,0x06,0x26,0x3E,0x1B,0x22,0x19,0x04,0x2E,0x3A,0x21,<br />
0x05,0x0A,0x07,0x02,0x13,0x14,0x00,0x15,0x0C,0x3D,0x11,0x0F,0x0D,0x38,0x2D,0x24,<br />
0x33,0x20,0x08,0x16,0x3F,0x2B,0x20,0x3C,0x2E,0x27,0x23,0x31,0x29,0x32,0x2C,0x09<br />
};</nowiki><br />
<br />
== Backdrop color (palette index 0) uses ==<br />
<br />
During forced blanking, when neither background nor sprites are enabled in [[PPU registers|PPUMASK ($2001)]], the picture will show the backdrop color.<br />
If only the background or sprites are disabled, or if the left 8 pixels are clipped off, the PPU continues its [[PPU rendering|normal video memory access pattern]] but uses the backdrop color for anything disabled.<br />
<br />
== The background palette hack ==<br />
<br />
During forced blanking, if the current VRAM address ever points to a palette register (i.e., $3F00-$3FFF), then the color in that palette register will be output to the screen instead of the backdrop color, for as long as the VRAM address is pointing there during the forced blanking. This can be used to display colors from the normally unused $3F04/$3F08/$3F0C palette locations. (Looking at the relevant circuitry in [[Visual 2C02]], this happens because the palette RAM's output is not disconnected from the video output circuitry when not rendering.)<br />
<br />
A loop that fills the palette will cause each color in turn to be shown on the screen, so to avoid rainbow artifacts while loading the palette, wait for a real vertical blank first using an [[NMI]] technique.<br />
<br />
== Color names ==<br />
When programmers and artists are communicating, it's often useful to have human-readable names for colors.<br />
Many graphic designers who have done web or game work will be familiar with [[wikipedia:Web colors#HTML color names|HTML color names]].<br />
<br />
=== Luma ===<br />
<br />
* $0F: Black<br />
* $00: Dark gray<br />
* $10: Light gray or silver<br />
* $20: White<br />
* $01-$0C: Dark colors, medium mixed with black<br />
* $11-$1C: Medium colors, similar brightness to dark gray<br />
* $21-$2C: Light colors, similar brightness to light gray<br />
* $31-$3C: Pale colors, light mixed with white<br />
<br />
=== Chroma ===<br />
Names for hues:<br />
* $x0: Gray<br />
* $x1: Azure<br />
* $x2: Blue<br />
* $x3: Violet<br />
* $x4: Magenta<br />
* $x5: Rose<br />
* $x6: Red or maroon<br />
* $x7: Orange<br />
* $x8: Yellow or olive<br />
* $x9: Chartreuse<br />
* $xA: Green<br />
* $xB: Spring<br />
* $xC: Cyan<br />
<br />
=== RGBI ===<br />
These NES colors approximate colors in 16-color RGBI palettes, such as the CGA, EGA, or classic Windows palette, though the NES doesn't really have particularly good approximations:<br />
* $0F: 0/Black<br />
* $02: 1/Navy<br />
* $1A: 2/Green<br />
* $1C: 3/Teal<br />
* $06: 4/Maroon<br />
* $14: 5/Purple<br />
* $18: 6/Olive ($17 for the brown in CGA/EGA in RGB)<br />
* $10: 7/Silver<br />
* $00: 8/Gray<br />
* $12: 9/Blue<br />
* $2A: 10/Lime<br />
* $2C: 11/Aqua/Cyan<br />
* $16: 12/Red<br />
* $24: 13/Fuchsia/Magenta<br />
* $28: 14/Yellow<br />
* $30: 15/White<br />
<br />
== See also ==<br />
* [[NTSC video]] - details of the NTSC signal generation and how it produces the palette<br />
* [[PAL video]]<br />
* [[:Category:Palettes|Palettes (gallery)]] - a few different visualizations of PPU palettes.<br />
* [//forums.nesdev.org/viewtopic.php?t=13264 Another palette test] - Simple test ROM to display the palette.<br />
* [[Full palette demo]] - Demo that displays the entire palette with all emphasis settings at once.<br />
* [//www.nesdev.org/rgbppu/ RGB PPU Palette Converter] - RGB PPU palette conversion and visualization tool, [//forums.nesdev.org/viewtopic.php?p=104217 written by WhoaMan].<br />
<br />
== References ==<br />
* [//forums.nesdev.org/viewtopic.php?p=98955#p98955 Re: Various questions about the color palette and emulators] - 2012 collection of 2C03, 2C04, 2C05 palettes.</div>Bregaladhttps://www.nesdev.org/w/index.php?title=PPU_nametables&diff=21642PPU nametables2024-03-02T22:49:35Z<p>Bregalad: Nametable fetches can also be in the AT's range (i.e. Negative scroll). CIRAM doesn't have to be disabled for 4-screen mirroring.</p>
<hr />
<div>A '''nametable''' is a 1024 byte area of memory used by the PPU to lay out backgrounds.<br />
Each byte in the nametable controls one 8x8 pixel character cell, and each nametable has 30 rows of 32 tiles each, for 960 ($3C0) bytes; the 64 ($40) remaining bytes are used by each nametable's [[PPU attribute tables|attribute table]].<br />
With each tile being 8x8 pixels, this makes a total of 256x240 pixels in one map, the same size as one full screen.<br />
<br />
<div style="float:right; margin-left: 1em"><br />
(0,0) (256,0) (511,0)<br />
+-----------+-----------+<br />
| | |<br />
| | |<br />
| $2000 | $2400 |<br />
| | |<br />
| | |<br />
(0,240)+-----------+-----------+(511,240)<br />
| | |<br />
| | |<br />
| $2800 | $2C00 |<br />
| | |<br />
| | |<br />
+-----------+-----------+<br />
(0,479) (256,479) (511,479)<br />
</div><br />
:''See also: [[PPU memory map]]''<br />
==Mirroring==<br />
{{main|Mirroring}}<br />
The NES has four logical nametables, arranged in a 2x2 pattern. Each occupies a 1 KiB chunk of PPU address space, starting at $2000 at the top left, $2400 at the top right, $2800 at the bottom left, and $2C00 at the bottom right.<br />
<br />
But the NES system board itself has only 2 KiB of VRAM (called CIRAM, stored in a separate SRAM chip), enough for two physical nametables; hardware on the cartridge controls address bit 10 of CIRAM to map one nametable on top of another.<br />
* Vertical mirroring: $2000 equals $2800 and $2400 equals $2C00 (e.g. ''Super Mario Bros.'')<br />
* Horizontal mirroring: $2000 equals $2400 and $2800 equals $2C00 (e.g. ''Kid Icarus'')<br />
* One-screen mirroring: All nametables refer to the same memory at any given time, and the mapper directly manipulates CIRAM address bit 10 (e.g. many [[Rare]] games using [[AxROM]])<br />
* Four-screen mirroring: The cartridge contains additional VRAM used for all nametables (e.g. ''Gauntlet'', ''Rad Racer 2'')<br />
* Other: Some advanced mappers can present arbitrary combinations of CIRAM, VRAM, or even CHR ROM in the nametable area. Such exotic setups are rarely used.<br />
<br />
== Background evaluation ==<br />
{{main|PPU rendering}}<br />
Conceptually, the PPU does this 33 times for each scanline:<br />
<br />
# Fetch a nametable entry from $2000-$2FFF.<br />
# Fetch the corresponding attribute table entry from $23C0-$2FFF and increment the current VRAM address within the same row.<br />
# Fetch the low-order byte of an 8x1 pixel sliver of pattern table from $0000-$0FF7 or $1000-$1FF7.<br />
# Fetch the high-order byte of this sliver from an address 8 bytes higher.<br />
# Turn the attribute data and the pattern table data into palette indices, and combine them with data from [[PPU sprite evaluation|sprite data]] using [[PPU sprite priority|priority]].<br />
<br />
It also does a fetch of a 34th (nametable, attribute, pattern) tuple that is never used, but some [[mapper]]s rely on this fetch for timing purposes.<br />
<br />
== See also ==<br />
<br />
* [[PPU attribute tables]]</div>Bregaladhttps://www.nesdev.org/w/index.php?title=PPU_memory_map&diff=21641PPU memory map2024-03-02T22:43:51Z<p>Bregalad: </p>
<hr />
<div>=== PPU memory map ===<br />
<br />
The [[PPU]] addresses a 14-bit (16kB) address space, $0000-$3FFF, completely separate from the CPU's address bus. It is either directly accessed by the PPU itself, or via the CPU with [[PPU registers|memory mapped registers]] at $2006 and $2007.<br />
<br />
{| class="tabular"<br />
! Address range || Size || Description || Mapped by<br />
|-<br />
| $0000-$0FFF || $1000 || [[PPU pattern tables|Pattern table]] 0 || Cartridge<br />
|-<br />
| $1000-$1FFF || $1000 || Pattern table 1 || Cartridge<br />
|-<br />
| $2000-$23BF || $0400 || [[PPU nametables|Nametable]] 0 || Cartridge<br />
|-<br />
| $2400-$27FF || $0400 || Nametable 1 || Cartridge<br />
|-<br />
| $2800-$2BFF || $0400 || Nametable 2 || Cartridge<br />
|-<br />
| $2C00-$2FFF || $0400 || Nametable 3 || Cartridge<br />
|-<br />
| $3000-$3EFF || $0F00 || Unused || Cartridge<br />
|-<br />
| $3F00-$3F1F || $0020 || [[PPU palettes|Palette RAM]] indexes || Internal to PPU<br />
|-<br />
| $3F20-$3FFF || $00E0 || Mirrors of $3F00-$3F1F || Internal to PPU<br />
|}<br />
<br />
== Hardware mapping ==<br />
<br />
The NES has 2kB of RAM dedicated to the PPU, usually mapped to the nametable address space from $2000-$2FFF, but this can be rerouted through custom cartridge wiring. The mappings above are the addresses from which the PPU uses to fetch data during rendering. The actual devices that the PPU fetches pattern, name table and attribute table data from is configured by the cartridge.<br />
<br />
* $0000-1FFF is normally mapped by the cartridge to a [[CHR ROM vs. CHR RAM|CHR-ROM or CHR-RAM]], often with a bank switching mechanism.<br />
<br />
* $2000-2FFF is normally mapped to the 2kB NES internal VRAM, providing 2 nametables with a [[Mirroring#Nametable_Mirroring|mirroring]] configuration controlled by the cartridge, but it can be partly or fully remapped to ROM or RAM on the cartridge, allowing up to 4 simultaneous nametables.<br />
<br />
* $3000-3EFF is usually a mirror of the 2kB region from $2000-2EFF. The PPU does not render from this address range, so this space has negligible utility.<br />
<br />
* $3F00-3FFF is not configurable, always mapped to the internal palette control.<br />
<br />
== OAM ==<br />
In addition, the PPU internally contains 256 bytes of memory known as [[PPU OAM|Object Attribute Memory]] which determines how sprites are rendered. The CPU can manipulate this memory through [[PPU registers|memory mapped registers]] at [[OAMADDR]] ($2003), [[OAMDATA]] ($2004), and [[OAMDMA]] ($4014). OAM can be viewed as an array with 64 entries. Each entry has 4 bytes: the sprite Y coordinate, the sprite tile number, the sprite attribute, and the sprite X coordinate. <br />
<br />
{| class="tabular"<br />
! Address Low Nibble || Description<br />
|-<br />
| $0, $4, $8, $C || Sprite Y coordinate<br />
|-<br />
| $1, $5, $9, $D || Sprite tile #<br />
|-<br />
| $2, $6, $A, $E || Sprite attribute<br />
|-<br />
| $3, $7, $B, $F || Sprite X coordinate<br />
|}</div>Bregaladhttps://www.nesdev.org/w/index.php?title=PPU_memory_map&diff=21640PPU memory map2024-03-02T22:36:27Z<p>Bregalad: $3000-$3F00 is unused by PPU, it as a mirror of $2000-$2F00 if the cartridge maps it that way</p>
<hr />
<div>=== PPU memory map ===<br />
<br />
The [[PPU]] addresses a 14-bit (16kB) address space, $0000-3FFF, completely separate from the CPU's address bus. It is either directly accessed by the PPU itself, or via the CPU with [[PPU registers|memory mapped registers]] at $2006 and $2007.<br />
<br />
The NES has 2kB of RAM dedicated to the PPU, normally mapped to the nametable address space from $2000-2FFF, but this can be rerouted through custom cartridge wiring.<br />
<br />
{| class="tabular"<br />
! Address range || Size || Description || Mapped by<br />
|-<br />
| $0000-$0FFF || $1000 || [[PPU pattern tables|Pattern table]] 0 || Cartridge<br />
|-<br />
| $1000-$1FFF || $1000 || Pattern table 1 || Cartridge<br />
|-<br />
| $2000-$23BF || $0400 || [[PPU nametables|Nametable]] 0 || Cartridge<br />
|-<br />
| $2400-$27FF || $0400 || Nametable 1 || Cartridge<br />
|-<br />
| $2800-$2BFF || $0400 || Nametable 2 || Cartridge<br />
|-<br />
| $2C00-$2FFF || $0400 || Nametable 3 || Cartridge<br />
|-<br />
| $3000-$3EFF || $0F00 || Unused || Cartridge<br />
|-<br />
| $3F00-$3F1F || $0020 || [[PPU palettes|Palette RAM]] indexes || Internal to PPU<br />
|-<br />
| $3F20-$3FFF || $00E0 || Mirrors of $3F00-$3F1F || Internal to PPU<br />
|}<br />
<br />
In addition, the PPU internally contains 256 bytes of memory known as [[PPU OAM|Object Attribute Memory]] which determines how sprites are rendered. The CPU can manipulate this memory through [[PPU registers|memory mapped registers]] at [[OAMADDR]] ($2003), [[OAMDATA]] ($2004), and [[OAMDMA]] ($4014). OAM can be viewed as an array with 64 entries. Each entry has 4 bytes: the sprite Y coordinate, the sprite tile number, the sprite attribute, and the sprite X coordinate. <br />
<br />
{| class="tabular"<br />
! Address Low Nibble || Description<br />
|-<br />
| $00, $04, $08, $0C || Sprite Y coordinate<br />
|-<br />
| $01, $05, $09, $0D || Sprite tile #<br />
|-<br />
| $02, $06, $0A, $0E || Sprite attribute<br />
|-<br />
| $03, $07, $0B, $0F || Sprite X coordinate<br />
|}<br />
<br />
== Hardware mapping ==<br />
<br />
The mappings above are the addresses from which the PPU uses to fetch data during rendering. The actual device that the PPU fetches pattern, name table and attribute table data from is configured by the cartridge.<br />
<br />
* $0000-1FFF is normally mapped by the cartridge to a [[CHR ROM vs. CHR RAM|CHR-ROM or CHR-RAM]], often with a bank switching mechanism.<br />
<br />
* $2000-2FFF is normally mapped to the 2kB NES internal VRAM, providing 2 nametables with a [[Mirroring#Nametable_Mirroring|mirroring]] configuration controlled by the cartridge, but it can be partly or fully remapped to ROM or RAM on the cartridge, allowing up to 4 simultaneous nametables.<br />
<br />
* $3000-3EFF is usually a mirror of the 2kB region from $2000-2EFF. The PPU does not render from this address range, so this space has negligible utility.<br />
<br />
* $3F00-3FFF is not configurable, always mapped to the internal palette control.</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:Overscan&diff=15207Talk:Overscan2019-10-15T07:00:45Z<p>Bregalad: Undo revision 17120 by 38.141.52.250 (talk)</p>
<hr />
<div>== PAL DAR ==<br />
If I'm doing the math correctly, PAL display aspect ratio is ≈1.48:1, or close enough to 3:2. So do PAL games basically come pre-widescreen? How does the vertical alignment compare?—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 18:53, 9 April 2013 (MDT)<br />
:I have no access to a PAL NES, PAL famiclone, or PAL TV, but I'm getting in the neighborhood of 1.39:1. Could you explain the math that leads to 1.48:1? But for this comment, assume that the 240px of the NES picture is in fact vertically centered on the 288px tall PAL picture. A widescreen TV will show 216px minus overscan, and overscan is (I'll guess) 12px per side, so anything designed for a 192px tall safe area will fit properly. And the old Nintendo BG planning sheet did assume a 192px tall safe area. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 19:29, 9 April 2013 (MDT)<br />
::Just going on what was said in the page: 1.3862 × 256 ÷ 240 = 1.4786. Am I doing that wrong? —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 19:46, 9 April 2013 (MDT)<br />
:::Oh, my fault, I misread your first comment. 1.48 is the DAR. I've been so focused on getting proper PAR that sometimes I forget about DAR. But you'd need a DAR near 1.78 to be widescreen friendly. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 21:38, 9 April 2013 (MDT)<br />
::::Having a vertical active area of 200px (back of the envelope: 256×9÷16×1.3862) puts "de-letterboxed widescreen PAL 16:9" as convenient as 4:3 SDTV, which is perhaps worth keeping in mind.—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 01:02, 10 April 2013 (MDT)<br />
<br />
== Difference between PocketNES safe area and title safe area? ==<br />
<br />
Why is those two areas displayed, since it is generally admitted that data will be displayed in all cases in both of those areas ? This makes the smallest of the bunch (title safe area) useless since it is smaller than data that we know will be displayed in all cases; as such in my opinion it is irrelevant to overscan.<br />
[[Special:Contributions/208.71.141.54|208.71.141.54]] 00:06, 13 April 2018 (MDT)<br />
It's me there I forgot to log in.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 00:06, 13 April 2018 (MDT)<br />
<br />
:I always thought PocketNES was a strange inclusion here. There's lots of emulator environments on low resolution screens that might apply (e.g. VGA 320x200?) I don't really see why many people would care about PocketNES in particular. It's already extremely niche, emulating a 30 year old system on a 15 year old one. :P That said, its inclusion here isn't offensive to me, though it does add a few seconds of confusion to reading this article. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:05, 14 April 2018 (MDT)<br />
::What PocketNES cuts off is a practical maximum for what non-pathological TVs will cut off. Title safe is intended for two things: A. to cover even pathological cases, such as TVs in need of professional H/V-size readjustment, and B. to document the practice embodied in markings on Nintendo's background planning sheets. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 13:58, 14 April 2018 (MDT)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:APU_DMC&diff=13215Talk:APU DMC2019-04-29T19:39:58Z<p>Bregalad: /* DPCM as alternate name */ new section</p>
<hr />
<div>Similarly to the [[APU Noise|noise channel]], the DPCM channel's frequency counter [http://uxul.org/~noname/chips/cpu-2/no-metal/stitched/final/ on the die] is a '''9-bit linear feedback shift register''' (with taps at the 5th and 9th bits); when I take the counter values from the on-die ROM and run the LFSR until the result is '100000000', the cycle counts (for NTSC) match once multiplied by 2. --[[User:Quietust|Quietust]] 05:00, 23 January 2011 (UTC)<br />
<br />
I suspect there's no "address increment", but ''another'' shift register. Just pay attention to the address wrap - if we had a counter, it would wrap to zero, but instead, it wraps to $8000, like ($10000 >> 1).<br />
--[[User:Zepper|Zepper]] 01:49, 6 June 2011 (UTC)<br />
:The generated addresses are linear, and I don't think a shift register can do that. So I'm conjecturing an up-counter here. --[[User:Tepples|Tepples]] 02:30, 6 June 2011 (UTC)<br />
::The DPCM address register is only 15 bits wide (with A15 being connected to the VCC rail @ 2850,5450), and the upper bit (A14) gets initialized to 1 (@ 2565,5365) instead of the last value written to $4012 (and the bottom 6 bits get initialized to 0, but we already know this). --[[User:Quietust|Quietust]] 03:03, 6 June 2011 (UTC)<br />
<br />
== DMC find ==<br />
<br />
<br />
Looks like the DMC silent flag makes difference for $4011 raw output. If this flag is non-zero, the $4011 value written is ignored by the raw output ''only''. I could test a few NSFs and it works flawlessly. --[[User:Zepper|Zepper]] 14:53, 14 November 2011 (UTC)<br />
:By "the DMC silent flag" do you mean bit 4 of $4015? And what exactly do you mean by "ignored by the raw output only"? Do you mean that values are queued up and take effect after the sample period ends? --[[User:Tepples|Tepples]] 15:10, 14 November 2011 (UTC)<br />
<br />
Well, the silent flag is described in the APU DMC section, "''The output unit continuously outputs a 7-bit value to the mixer. It contains an 8-bit right shift register, a bits-remaining counter, a 7-bit delta-counter, and '''a silence flag'''''". Just read the rest of the APU DMC output unit. About the ''raw output'', I mean the timed writes to $4011 register, as listen in Battletoads (drums) for example. --[[User:Zepper|Zepper]] 15:31, 14 November 2011 (UTC)<br />
:So as I understand it, you're saying that in effect, $4011 writes don't take effect if a sample is not playing. Interesting; is there a test ROM for me to run on my PowerPak? --[[User:Tepples|Tepples]] 17:20, 14 November 2011 (UTC)<br />
::Could you point out the location (within the [http://www.qmtpro.com/~nes/chipimages/visual2a03/expert.html Visual 2A03]) of the hardware responsible for this hypothetical behavior? Because if it's there, I can't see it - the internal signal for "write $4011" comes solely from the address+R/W+CLK lines, and when it's active, it ''immediately'' updates the position register (of which only the upper 6 bits are a "delta-counter" - the bottom-most bit is just a simple latch) to match the state of D0-D6. An example, for D6: during a write to $4011, t13375 activates and connects node 13255 to node 10616 (D6), then that updates t13885 and causes node 10957 to be set to the inverse of node 13255, then that updates t13872 and causes node 10881 (PCM_OUT6) to be set to the inverse of node 10957, which works out to be the value of D6. --[[User:Quietust|Quietust]] 22:55, 14 November 2011 (UTC)<br />
<br />
Thanks for verifying it. I suspected it's empirical. It works only when '''emulating''' $4011, as such behavior do not exist in the hardware. In short words, it's a trick that can be used for emulation only, avoiding sound pops. Sorry for the inconvenience, if any. --[[User:Zepper|Zepper]] 00:02, 15 November 2011 (UTC)<br />
:I mentioned something similar in the [[enhancement]] article. But there's still one problem: What happens when the DMC tries to write back to the position register on the same cycle as a $4011 write? --[[User:Tepples|Tepples]] 00:23, 15 November 2011 (UTC)<br />
::Most of the APU "runs" when M2 is low, while writes to registers happen when M2 is high. The logic that updates the DMC position register appears to be an exception, though - I'm not sure what will happen if a $4011 write happens at the same time as an increment/decrement, but I'm guessing the resulting state would be (position +/- 1) AND (data bits). --[[User:Quietust|Quietust]] 00:45, 15 November 2011 (UTC)<br />
<br />
Well, it's the ''$4011 position register'' value (7 bit delta-counter) being treated as wave data (raw) too. Since the ''silence flag'' is not zero, the value is ignored as wave data, working as it should be. --[[User:Zepper|Zepper]] 02:24, 15 November 2011 (UTC)<br />
<br />
== PAL frequency table ==<br />
<br />
Is this table correct? There are two entries I find really strange, for reasons which I outlined here: http://forums.nesdev.org/viewtopic.php?p=94079#p94079<br />
<br />
The two values in question:<br />
<br />
$4 : $114 = 276<br />
$C : $062 = 98<br />
<br />
I think these should have been:<br />
<br />
$4 : $10A = 266<br />
$C : $064 = 100<br />
<br />
I don't have a PAL NES to test, but can someone confirm if the table in this article is correct or not? The NTSC table represents a scheme that consistently uses the best match to a tone in an A440 tuning. The PAL table does the same thing except these two pitches which are significantly detuned. Either our table is wrong, or the chip was designed "wrong", and I'm open to either possibility, but as I said I cannot verify for myself. - [[User:Rainwarrior|Rainwarrior]] 22:50, 18 May 2012 (PDT)<br />
<br />
:With some help from jrlepage, who has a PAL NES, I have verified that the two frequencies are indeed 276 and 98. I guess they implemented the chip incorrectly. Weird. - [[User:Rainwarrior|Rainwarrior]] 17:30, 25 July 2012 (PDT)<br />
<br />
:Just for reference, the table I verified is: 398, 354, 316, 298, 276, 236, 210, 198, 176, 148, 132, 118, 98, 78, 66, 50<br />
:- [[User:Rainwarrior|Rainwarrior]] 17:42, 25 July 2012 (PDT)<br />
<br />
== Pitch table ==<br />
<br />
I removed the pitch names from the table.<br />
<br />
The "pitch table" was really a sample rate table. In the table, the frequencies in Hz are sample points per second, or deltas per second. (When talking about pitch, frequencies in Hz are wave periods per second.) In other words, having pitch names in the table isn't useful. It's as useless as saying CD audio that plays at 44100 samples per second is pitch F11 - 23 cents.<br />
<br />
If I've made a mistake, feel free to revert. --[[User:Bavi H|Bavi H]] ([[User talk:Bavi H|talk]]) 20:53, 28 December 2013 (MST)<br />
<br />
: The important part of the table is ''relative'' pitch. Maybe my table at [[User:Lidnariq/DPCM_mistuning]] would be a better presentation of it, I dunno. While it's definitely not useful to say that "4181.71 Hz is C-8 -1.78c", it is useful to point out that "4709.93 Hz is to 4181.71Hz as C-8 -1.78c is to D-8 +4.16c". —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 21:56, 28 December 2013 (MST)<br />
<br />
:(edit conflict:) I reverted the change. After thinking about it, the table is trying to show the rates were chosen to get particular intervals or a particular scale (not specific pitches). I'm still not comfortable with the absolute pitches in the table (C8 to C11 is at the upper end to above human hearing), but I think I'll leave it there and play around with alternatives before changing it again. --[[User:Bavi H|Bavi H]] ([[User talk:Bavi H|talk]]) 22:00, 28 December 2013 (MST)<br />
<br />
:: It's not as irrelevant as it may seem. The organization of the DPCM samplerates clearly demonstrates that they were designed to be tuned to a scale. (See [http://forums.nesdev.org/viewtopic.php?f=6&t=5473 this thread].) They happen to be nearly useless for this purpose, especially because of the +1 modifier on the sample length that looks like an accident of the implementation, but the design intent is clear. I agree that it's unfortunately misleading to label them with pitches, but I can't think of a simpler way to express their tuning relationships to each other. You can have a matrix with cents and relative intervals, maybe, but I think using letter pitch names gets the idea across quicker and more easily. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 02:05, 29 December 2013 (MST)<br />
<br />
:: As an aside, I've found a use for these pitches in the past when wanting to play a DPCM ramp to adjust triangle volume. By knowing the pitch of the samplerate, I can tune the ramp to a pitch that will be hidden by the existing harmony of the music. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 02:06, 29 December 2013 (MST)<br />
<br />
== Diagrams ==<br />
<br />
The part about using DMC for syncing badly needs visual representation of what's going on. Describing it in pure text form is by essence incomplete.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 05:54, 21 September 2018 (MDT)<br />
<br />
== DPCM as alternate name ==<br />
<br />
The fact this sound channel is also known as "DPCM" should be mentionned, and appropriate page redirection should be introduced.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:39, 29 April 2019 (MDT)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:APU_Triangle&diff=13305Talk:APU Triangle2019-03-20T08:18:55Z<p>Bregalad: Writes to $4008 to silence triangle channel</p>
<hr />
<div>I'm fairly sure triangle can be silenced by writing $00 to $4008, too. Any value with the low 7 bits at 0 will silence the channel, regardless of the value of bit 7.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 02:18, 20 March 2019 (MDT)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:INES&diff=13897Talk:INES2019-01-16T07:49:58Z<p>Bregalad: /* 4-screen mirroring */</p>
<hr />
<div>How does a PlayChoice hint screen work? --[[User:Zzo38|Zzo38]] 19:08, 21 September 2012 (MDT)<br />
<br />
== Last 4 ==<br />
<br />
Should this be "if the last ''5'' bytes are not all zero"? "A general rule of thumb: if the last 4 bytes are not all zero, and the header is not marked for NES 2.0 format, an emulator should either mask off the upper 4 bits of the mapper number or simply refuse to load the ROM." -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 03:45, 14 July 2013 (MDT)<br />
:When I wrote 4 as the rule of thumb, I didn't know how many not-widely-adopted extensions to original iNES were floating around, and I guessed that one or more might have used byte 11 for something, but all of the ROMs I saw with DiskDude and similar tags had at least something in the last four bytes of the header. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 07:48, 14 July 2013 (MDT)<br />
:: Makes sense. Just wanted to check whether it was a typo. -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 09:06, 14 July 2013 (MDT)<br />
:Nestopia checks the last 6, and clears/ignores the last 9. (It also actually does pay attention to bytes 8 and 9)—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 11:21, 14 July 2013 (MDT)<br />
:If the header contains "DiskDude!" or one of those other things (I forget now, but I knew at one time and figured this out), then bit2 of flags 7 will be set; otherwise bit2 and bit3 should both be cleared. This may be another way. --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 19:51, 20 August 2013 (MDT)<br />
<br />
== 4-screen mirroring ==<br />
<br />
Reference needed I'm afraid.<br />
<br />
"Theoretically bit 3 could be used for most mappers that had hard-wired mirroring to transparently provide 4KB of VRAM for 4-screen instead. However, many emulators will ignore this bit except for mappers with prior 4-screen variations."<br />
<br />
I'm fairly confident most emulators will happily gives you 4-screen mirroring when asked for it, even if they are in mappers where such a possibility wasn't used. I remember at some point considering using 4-screen mirroring with CNROM and it worked well.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:55, 13 January 2019 (MST)<br />
<br />
: In my limited experience, most emulators will let you start with 4-screen layout, but if the mapper has a mirroring control register, using it will irrevocably remove the extra nametables. For example, this is what goes wrong when trying to run Vs. Goonies on FCEUX as mapper 75 instead of mapper 151. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 02:13, 13 January 2019 (MST)<br />
<br />
:: Ah ok. This is super weird, such a behaviour would be almost impossible to pull out in real hardware.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 02:20, 13 January 2019 (MST)<br />
<br />
::: As a curious aside, mappers [[NES 2.0 Mapper 356|356]] and [[NES 2.0 Mapper 512|512]] could do that if powered on in 4-screen mode. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:35, 13 January 2019 (MST)<br />
<br />
: How do you think this should be worded? The point I'm trying to be careful about is basically that there are only two ROMs that have ever put this bit to actual meaningful use (4, 206). The rest is "theoretical" because nobody's released a game or test ROMs to verify the hundreds of other mappers that could maybe apply it. Because of that I have very low confidence that "most emulators" will get a completely untested feature correct. Testing this would actually be quite a big research project though. I am trying to keep this describing what exists, and not making it into a rule of "emulator authors should/must do it this way" that might not match reality and give people the expectation that they can safely use such an untested feature. Can you help write an alternative/better way to express this? I'll switch the wording to say "largely untested" for starters, but I'm sure it could be said better. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:28, 13 January 2019 (MST)<br />
<br />
:: Well I don't know exactly, but something like that : "The 4-screen mirroring feature is largely untested with mappers wiout prior games using a 4-screen variation". This means that it's supposed to work, however it's untested and that's what makes the most sense in this contex. Saying "most emulators will ignore the bit" seems overreaching to me. [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:21, 15 January 2019 (MST)<br />
:::I can tell you that Nintendulator and NintendulatorNRS set up nametable mirroring in each mapper's code, and if that mapper has no provisions for 4-Screen Mode, the bit will not have any effect. Emulators that obey the 4-screen bit for any mapper will do so because they enforce that bit outside of the mapper emulation code. It is basically a normative decision to specify whether that bit is supposed to be thought of as "informative" for the mapper emulation code, or as "overriding" anything that the mapper normally does. Unless you want make it obligatory which understanding is correct --- something I would like, but only for NES 2.0 ---, a page like this, which is mostly descriptive of a legacy format, should simply state: "The four-screen bit cannot be assumed to override the normal mirroring settings of mappers that have not existed in four-screen variants during the NES era, or as real hardware for homebrew mappers. Some emulators will allow for such an override, while others (e.g. Nintendulator) do not." [[User:NewRisingSun|NewRisingSun]] ([[User talk:NewRisingSun|talk]]) 01:45, 15 January 2019 (MST)<br />
<br />
::: Nintendulator is just ONE emulator, not "most emulators". Besides, you have to remember that, originally in iNES 1.0, it seemed very clear to me that this bits overriedes other mirroring-related behaviour. For instance, MMC3 has no "provisions for 4-screen mirroring" or anything like that - 4-screen mirroring is an hardware feature that can be installed on any cartridge regardless of it's mapper, and tha happened to have been installed on two officially released MMC3 games. In this regard, I think Nintendulator is actually wrong, if it does not gives you 4 independant nametables when this bit is set with any mapper that does not have complex VRAM features. It should be able to give you NROM/CNROM/GNROM/UNROM/MMC1/MMC2/MMC4, etc... with 4-screen just fine. If it doesn't I'd consider it a bug in the emulator that does not respect the iNES format. HOWEVER with advanced mappers such as MMC5, VRC6 or Namco Mapper, it's understandable the mapper already fucks with nametables and there's no canonical way to implement 4-screen mirroring without conflicting with other features, so in those cases it's fine to ignore the bit.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 02:59, 15 January 2019 (MST)<br />
::::The Everdrive N8 behaves similar to Nintendulator in having the mapper code decide whether 4-screen applies or not; in fact, it incorrectly does not even allow 4-screen on Mapper 206, where it is actually needed. The iNES format makes no explicit statement that the 4-screen bit should override mapper-controlled mirroring any more than the vertical mirroring bit should override mapper-controlled mirroring, so neither alternative is truly "clear". Regardless of which alternative you consider the right one, it obviously remains unsafe to assume that 4-screen overrides mapper-controlled mirroring, and a descriptive page describing a legacy format should state as much. [[User:NewRisingSun|NewRisingSun]] ([[User talk:NewRisingSun|talk]]) 05:45, 15 January 2019 (MST)<br />
<br />
::::Still that is TWO emulators, out of a list of 90+. You'd need to find that behaviour in more than 50 emulators to state "most emulators" - something that is dubious. Also, what is your source for iNES being unclear ? What do you consider an authoritative document that describe the iNES header, and is not clear ?[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 08:46, 15 January 2019 (MST)<br />
:::::It turns out that Nintendulator does support four-screen mirroring on discrete mappers with hard-wired mirroring, though not on MMC1 and such. The Everdrive N8 however I verified to not support it. It is not an emulator, but a flash cart, and a very popular one. I do not have to prove anything about "most emulators" because I have not made any claims about most emulators; rainwarrior did. All I have been saying for the past two posts is that it is not safe to assume anything about the effects of the four-screen bit on boards for which historically no four-screen variant existed. That statement would be true even if one were to agree that iNES "clearly" called for the ability to specify 4-screen mode on any mapper, or at least any hard-wired one, and that all emulators and flash carts that do not allow that were wrong. If a mainstream emulator or popular flash cart will not play 4-screen CNROM correctly, then it's an unsafe choice for a ROM author, regardless of whose fault that is. Basically, my wording would give a piece of advice without making the sweeping claim that rainwarrior's previous version does. [[User:NewRisingSun|NewRisingSun]] ([[User talk:NewRisingSun|talk]]) 09:50, 15 January 2019 (MST)<br />
<br />
Does the Everdrive flash card support 4-screen mirroring at all ? If not that might be why it does not support it in combination with the mappers that didn't use it historically. Also, why indent every answer ? After 6 tabs this gets ridiculous.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:19, 15 January 2019 (MST)<br />
<br />
The Everdrive N8 flash cart supports 4-screen mode for iNES Mapper 004. [[User:NewRisingSun|NewRisingSun]] ([[User talk:NewRisingSun|talk]]) 13:35, 15 January 2019 (MST)<br />
<br />
:Re: Bregalad, I had already removed "many emulators will ignore this bit" and replaced it with the "largely untested" wording. There is no need to argue against "most emulators", that's not something I'm arguing for, nor is anyone else AFAICT. (The word '''most''' was never even used here?) - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:48, 15 January 2019 (MST)<br />
::Indeed, you said "many", not "most"; that was a misquote by Bregalad. Sorry. [[User:NewRisingSun|NewRisingSun]] ([[User talk:NewRisingSun|talk]]) 13:58, 15 January 2019 (MST)<br />
<br />
:::Ok ok, the page is fine now[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 00:49, 16 January 2019 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:INES&diff=13892Talk:INES2019-01-15T20:19:26Z<p>Bregalad: /* 4-screen mirroring */</p>
<hr />
<div>How does a PlayChoice hint screen work? --[[User:Zzo38|Zzo38]] 19:08, 21 September 2012 (MDT)<br />
<br />
== Last 4 ==<br />
<br />
Should this be "if the last ''5'' bytes are not all zero"? "A general rule of thumb: if the last 4 bytes are not all zero, and the header is not marked for NES 2.0 format, an emulator should either mask off the upper 4 bits of the mapper number or simply refuse to load the ROM." -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 03:45, 14 July 2013 (MDT)<br />
:When I wrote 4 as the rule of thumb, I didn't know how many not-widely-adopted extensions to original iNES were floating around, and I guessed that one or more might have used byte 11 for something, but all of the ROMs I saw with DiskDude and similar tags had at least something in the last four bytes of the header. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 07:48, 14 July 2013 (MDT)<br />
:: Makes sense. Just wanted to check whether it was a typo. -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 09:06, 14 July 2013 (MDT)<br />
:Nestopia checks the last 6, and clears/ignores the last 9. (It also actually does pay attention to bytes 8 and 9)—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 11:21, 14 July 2013 (MDT)<br />
:If the header contains "DiskDude!" or one of those other things (I forget now, but I knew at one time and figured this out), then bit2 of flags 7 will be set; otherwise bit2 and bit3 should both be cleared. This may be another way. --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 19:51, 20 August 2013 (MDT)<br />
<br />
== 4-screen mirroring ==<br />
<br />
Reference needed I'm afraid.<br />
<br />
"Theoretically bit 3 could be used for most mappers that had hard-wired mirroring to transparently provide 4KB of VRAM for 4-screen instead. However, many emulators will ignore this bit except for mappers with prior 4-screen variations."<br />
<br />
I'm fairly confident most emulators will happily gives you 4-screen mirroring when asked for it, even if they are in mappers where such a possibility wasn't used. I remember at some point considering using 4-screen mirroring with CNROM and it worked well.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:55, 13 January 2019 (MST)<br />
<br />
: In my limited experience, most emulators will let you start with 4-screen layout, but if the mapper has a mirroring control register, using it will irrevocably remove the extra nametables. For example, this is what goes wrong when trying to run Vs. Goonies on FCEUX as mapper 75 instead of mapper 151. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 02:13, 13 January 2019 (MST)<br />
<br />
:: Ah ok. This is super weird, such a behaviour would be almost impossible to pull out in real hardware.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 02:20, 13 January 2019 (MST)<br />
<br />
::: As a curious aside, mappers [[NES 2.0 Mapper 356|356]] and [[NES 2.0 Mapper 512|512]] could do that if powered on in 4-screen mode. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:35, 13 January 2019 (MST)<br />
<br />
: How do you think this should be worded? The point I'm trying to be careful about is basically that there are only two ROMs that have ever put this bit to actual meaningful use (4, 206). The rest is "theoretical" because nobody's released a game or test ROMs to verify the hundreds of other mappers that could maybe apply it. Because of that I have very low confidence that "most emulators" will get a completely untested feature correct. Testing this would actually be quite a big research project though. I am trying to keep this describing what exists, and not making it into a rule of "emulator authors should/must do it this way" that might not match reality and give people the expectation that they can safely use such an untested feature. Can you help write an alternative/better way to express this? I'll switch the wording to say "largely untested" for starters, but I'm sure it could be said better. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:28, 13 January 2019 (MST)<br />
<br />
:: Well I don't know exactly, but something like that : "The 4-screen mirroring feature is largely untested with mappers wiout prior games using a 4-screen variation". This means that it's supposed to work, however it's untested and that's what makes the most sense in this contex. Saying "most emulators will ignore the bit" seems overreaching to me. [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:21, 15 January 2019 (MST)<br />
:::I can tell you that Nintendulator and NintendulatorNRS set up nametable mirroring in each mapper's code, and if that mapper has no provisions for 4-Screen Mode, the bit will not have any effect. Emulators that obey the 4-screen bit for any mapper will do so because they enforce that bit outside of the mapper emulation code. It is basically a normative decision to specify whether that bit is supposed to be thought of as "informative" for the mapper emulation code, or as "overriding" anything that the mapper normally does. Unless you want make it obligatory which understanding is correct --- something I would like, but only for NES 2.0 ---, a page like this, which is mostly descriptive of a legacy format, should simply state: "The four-screen bit cannot be assumed to override the normal mirroring settings of mappers that have not existed in four-screen variants during the NES era, or as real hardware for homebrew mappers. Some emulators will allow for such an override, while others (e.g. Nintendulator) do not." [[User:NewRisingSun|NewRisingSun]] ([[User talk:NewRisingSun|talk]]) 01:45, 15 January 2019 (MST)<br />
<br />
::: Nintendulator is just ONE emulator, not "most emulators". Besides, you have to remember that, originally in iNES 1.0, it seemed very clear to me that this bits overriedes other mirroring-related behaviour. For instance, MMC3 has no "provisions for 4-screen mirroring" or anything like that - 4-screen mirroring is an hardware feature that can be installed on any cartridge regardless of it's mapper, and tha happened to have been installed on two officially released MMC3 games. In this regard, I think Nintendulator is actually wrong, if it does not gives you 4 independant nametables when this bit is set with any mapper that does not have complex VRAM features. It should be able to give you NROM/CNROM/GNROM/UNROM/MMC1/MMC2/MMC4, etc... with 4-screen just fine. If it doesn't I'd consider it a bug in the emulator that does not respect the iNES format. HOWEVER with advanced mappers such as MMC5, VRC6 or Namco Mapper, it's understandable the mapper already fucks with nametables and there's no canonical way to implement 4-screen mirroring without conflicting with other features, so in those cases it's fine to ignore the bit.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 02:59, 15 January 2019 (MST)<br />
::::The Everdrive N8 behaves similar to Nintendulator in having the mapper code decide whether 4-screen applies or not; in fact, it incorrectly does not even allow 4-screen on Mapper 206, where it is actually needed. The iNES format makes no explicit statement that the 4-screen bit should override mapper-controlled mirroring any more than the vertical mirroring bit should override mapper-controlled mirroring, so neither alternative is truly "clear". Regardless of which alternative you consider the right one, it obviously remains unsafe to assume that 4-screen overrides mapper-controlled mirroring, and a descriptive page describing a legacy format should state as much. [[User:NewRisingSun|NewRisingSun]] ([[User talk:NewRisingSun|talk]]) 05:45, 15 January 2019 (MST)<br />
<br />
::::Still that is TWO emulators, out of a list of 90+. You'd need to find that behaviour in more than 50 emulators to state "most emulators" - something that is dubious. Also, what is your source for iNES being unclear ? What do you consider an authoritative document that describe the iNES header, and is not clear ?[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 08:46, 15 January 2019 (MST)<br />
:::::It turns out that Nintendulator does support four-screen mirroring on discrete mappers with hard-wired mirroring, though not on MMC1 and such. The Everdrive N8 however I verified to not support it. It is not an emulator, but a flash cart, and a very popular one. I do not have to prove anything about "most emulators" because I have not made any claims about most emulators; rainwarrior did. All I have been saying for the past two posts is that it is not safe to assume anything about the effects of the four-screen bit on boards for which historically no four-screen variant existed. That statement would be true even if one were to agree that iNES "clearly" called for the ability to specify 4-screen mode on any mapper, or at least any hard-wired one, and that all emulators and flash carts that do not allow that were wrong. If a mainstream emulator or popular flash cart will not play 4-screen CNROM correctly, then it's an unsafe choice for a ROM author, regardless of whose fault that is. Basically, my wording would give a piece of advice without making the sweeping claim that rainwarrior's previous version does. [[User:NewRisingSun|NewRisingSun]] ([[User talk:NewRisingSun|talk]]) 09:50, 15 January 2019 (MST)<br />
<br />
Does the Everdrive flash card support 4-screen mirroring at all ? If not that might be why it does not support it in combination with the mappers that didn't use it historically. Also, why indent every answer ? After 6 tabs this gets ridiculous.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:19, 15 January 2019 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:INES&diff=13889Talk:INES2019-01-15T15:46:22Z<p>Bregalad: /* 4-screen mirroring */</p>
<hr />
<div>How does a PlayChoice hint screen work? --[[User:Zzo38|Zzo38]] 19:08, 21 September 2012 (MDT)<br />
<br />
== Last 4 ==<br />
<br />
Should this be "if the last ''5'' bytes are not all zero"? "A general rule of thumb: if the last 4 bytes are not all zero, and the header is not marked for NES 2.0 format, an emulator should either mask off the upper 4 bits of the mapper number or simply refuse to load the ROM." -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 03:45, 14 July 2013 (MDT)<br />
:When I wrote 4 as the rule of thumb, I didn't know how many not-widely-adopted extensions to original iNES were floating around, and I guessed that one or more might have used byte 11 for something, but all of the ROMs I saw with DiskDude and similar tags had at least something in the last four bytes of the header. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 07:48, 14 July 2013 (MDT)<br />
:: Makes sense. Just wanted to check whether it was a typo. -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 09:06, 14 July 2013 (MDT)<br />
:Nestopia checks the last 6, and clears/ignores the last 9. (It also actually does pay attention to bytes 8 and 9)—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 11:21, 14 July 2013 (MDT)<br />
:If the header contains "DiskDude!" or one of those other things (I forget now, but I knew at one time and figured this out), then bit2 of flags 7 will be set; otherwise bit2 and bit3 should both be cleared. This may be another way. --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 19:51, 20 August 2013 (MDT)<br />
<br />
== 4-screen mirroring ==<br />
<br />
Reference needed I'm afraid.<br />
<br />
"Theoretically bit 3 could be used for most mappers that had hard-wired mirroring to transparently provide 4KB of VRAM for 4-screen instead. However, many emulators will ignore this bit except for mappers with prior 4-screen variations."<br />
<br />
I'm fairly confident most emulators will happily gives you 4-screen mirroring when asked for it, even if they are in mappers where such a possibility wasn't used. I remember at some point considering using 4-screen mirroring with CNROM and it worked well.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:55, 13 January 2019 (MST)<br />
<br />
: In my limited experience, most emulators will let you start with 4-screen layout, but if the mapper has a mirroring control register, using it will irrevocably remove the extra nametables. For example, this is what goes wrong when trying to run Vs. Goonies on FCEUX as mapper 75 instead of mapper 151. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 02:13, 13 January 2019 (MST)<br />
<br />
:: Ah ok. This is super weird, such a behaviour would be almost impossible to pull out in real hardware.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 02:20, 13 January 2019 (MST)<br />
<br />
::: As a curious aside, mappers [[NES 2.0 Mapper 356|356]] and [[NES 2.0 Mapper 512|512]] could do that if powered on in 4-screen mode. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:35, 13 January 2019 (MST)<br />
<br />
: How do you think this should be worded? The point I'm trying to be careful about is basically that there are only two ROMs that have ever put this bit to actual meaningful use (4, 206). The rest is "theoretical" because nobody's released a game or test ROMs to verify the hundreds of other mappers that could maybe apply it. Because of that I have very low confidence that "most emulators" will get a completely untested feature correct. Testing this would actually be quite a big research project though. I am trying to keep this describing what exists, and not making it into a rule of "emulator authors should/must do it this way" that might not match reality and give people the expectation that they can safely use such an untested feature. Can you help write an alternative/better way to express this? I'll switch the wording to say "largely untested" for starters, but I'm sure it could be said better. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:28, 13 January 2019 (MST)<br />
<br />
:: Well I don't know exactly, but something like that : "The 4-screen mirroring feature is largely untested with mappers wiout prior games using a 4-screen variation". This means that it's supposed to work, however it's untested and that's what makes the most sense in this contex. Saying "most emulators will ignore the bit" seems overreaching to me. [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:21, 15 January 2019 (MST)<br />
:::I can tell you that Nintendulator and NintendulatorNRS set up nametable mirroring in each mapper's code, and if that mapper has no provisions for 4-Screen Mode, the bit will not have any effect. Emulators that obey the 4-screen bit for any mapper will do so because they enforce that bit outside of the mapper emulation code. It is basically a normative decision to specify whether that bit is supposed to be thought of as "informative" for the mapper emulation code, or as "overriding" anything that the mapper normally does. Unless you want make it obligatory which understanding is correct --- something I would like, but only for NES 2.0 ---, a page like this, which is mostly descriptive of a legacy format, should simply state: "The four-screen bit cannot be assumed to override the normal mirroring settings of mappers that have not existed in four-screen variants during the NES era, or as real hardware for homebrew mappers. Some emulators will allow for such an override, while others (e.g. Nintendulator) do not." [[User:NewRisingSun|NewRisingSun]] ([[User talk:NewRisingSun|talk]]) 01:45, 15 January 2019 (MST)<br />
<br />
::: Nintendulator is just ONE emulator, not "most emulators". Besides, you have to remember that, originally in iNES 1.0, it seemed very clear to me that this bits overriedes other mirroring-related behaviour. For instance, MMC3 has no "provisions for 4-screen mirroring" or anything like that - 4-screen mirroring is an hardware feature that can be installed on any cartridge regardless of it's mapper, and tha happened to have been installed on two officially released MMC3 games. In this regard, I think Nintendulator is actually wrong, if it does not gives you 4 independant nametables when this bit is set with any mapper that does not have complex VRAM features. It should be able to give you NROM/CNROM/GNROM/UNROM/MMC1/MMC2/MMC4, etc... with 4-screen just fine. If it doesn't I'd consider it a bug in the emulator that does not respect the iNES format. HOWEVER with advanced mappers such as MMC5, VRC6 or Namco Mapper, it's understandable the mapper already fucks with nametables and there's no canonical way to implement 4-screen mirroring without conflicting with other features, so in those cases it's fine to ignore the bit.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 02:59, 15 January 2019 (MST)<br />
::::The Everdrive N8 behaves similar to Nintendulator in having the mapper code decide whether 4-screen applies or not; in fact, it incorrectly does not even allow 4-screen on Mapper 206, where it is actually needed. The iNES format makes no explicit statement that the 4-screen bit should override mapper-controlled mirroring any more than the vertical mirroring bit should override mapper-controlled mirroring, so neither alternative is truly "clear". Regardless of which alternative you consider the right one, it obviously remains unsafe to assume that 4-screen overrides mapper-controlled mirroring, and a descriptive page describing a legacy format should state as much. [[User:NewRisingSun|NewRisingSun]] ([[User talk:NewRisingSun|talk]]) 05:45, 15 January 2019 (MST)<br />
<br />
::::Still that is TWO emulators, out of a list of 90+. You'd need to find that behaviour in more than 50 emulators to state "most emulators" - something that is dubious. Also, what is your source for iNES being unclear ? What do you consider an authoritative document that describe the iNES header, and is not clear ?[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 08:46, 15 January 2019 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:INES&diff=13887Talk:INES2019-01-15T09:59:29Z<p>Bregalad: /* 4-screen mirroring */</p>
<hr />
<div>How does a PlayChoice hint screen work? --[[User:Zzo38|Zzo38]] 19:08, 21 September 2012 (MDT)<br />
<br />
== Last 4 ==<br />
<br />
Should this be "if the last ''5'' bytes are not all zero"? "A general rule of thumb: if the last 4 bytes are not all zero, and the header is not marked for NES 2.0 format, an emulator should either mask off the upper 4 bits of the mapper number or simply refuse to load the ROM." -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 03:45, 14 July 2013 (MDT)<br />
:When I wrote 4 as the rule of thumb, I didn't know how many not-widely-adopted extensions to original iNES were floating around, and I guessed that one or more might have used byte 11 for something, but all of the ROMs I saw with DiskDude and similar tags had at least something in the last four bytes of the header. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 07:48, 14 July 2013 (MDT)<br />
:: Makes sense. Just wanted to check whether it was a typo. -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 09:06, 14 July 2013 (MDT)<br />
:Nestopia checks the last 6, and clears/ignores the last 9. (It also actually does pay attention to bytes 8 and 9)—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 11:21, 14 July 2013 (MDT)<br />
:If the header contains "DiskDude!" or one of those other things (I forget now, but I knew at one time and figured this out), then bit2 of flags 7 will be set; otherwise bit2 and bit3 should both be cleared. This may be another way. --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 19:51, 20 August 2013 (MDT)<br />
<br />
== 4-screen mirroring ==<br />
<br />
Reference needed I'm afraid.<br />
<br />
"Theoretically bit 3 could be used for most mappers that had hard-wired mirroring to transparently provide 4KB of VRAM for 4-screen instead. However, many emulators will ignore this bit except for mappers with prior 4-screen variations."<br />
<br />
I'm fairly confident most emulators will happily gives you 4-screen mirroring when asked for it, even if they are in mappers where such a possibility wasn't used. I remember at some point considering using 4-screen mirroring with CNROM and it worked well.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:55, 13 January 2019 (MST)<br />
<br />
: In my limited experience, most emulators will let you start with 4-screen layout, but if the mapper has a mirroring control register, using it will irrevocably remove the extra nametables. For example, this is what goes wrong when trying to run Vs. Goonies on FCEUX as mapper 75 instead of mapper 151. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 02:13, 13 January 2019 (MST)<br />
<br />
:: Ah ok. This is super weird, such a behaviour would be almost impossible to pull out in real hardware.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 02:20, 13 January 2019 (MST)<br />
<br />
::: As a curious aside, mappers [[NES 2.0 Mapper 356|356]] and [[NES 2.0 Mapper 512|512]] could do that if powered on in 4-screen mode. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:35, 13 January 2019 (MST)<br />
<br />
: How do you think this should be worded? The point I'm trying to be careful about is basically that there are only two ROMs that have ever put this bit to actual meaningful use (4, 206). The rest is "theoretical" because nobody's released a game or test ROMs to verify the hundreds of other mappers that could maybe apply it. Because of that I have very low confidence that "most emulators" will get a completely untested feature correct. Testing this would actually be quite a big research project though. I am trying to keep this describing what exists, and not making it into a rule of "emulator authors should/must do it this way" that might not match reality and give people the expectation that they can safely use such an untested feature. Can you help write an alternative/better way to express this? I'll switch the wording to say "largely untested" for starters, but I'm sure it could be said better. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:28, 13 January 2019 (MST)<br />
<br />
:: Well I don't know exactly, but something like that : "The 4-screen mirroring feature is largely untested with mappers wiout prior games using a 4-screen variation". This means that it's supposed to work, however it's untested and that's what makes the most sense in this contex. Saying "most emulators will ignore the bit" seems overreaching to me. [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:21, 15 January 2019 (MST)<br />
:::I can tell you that Nintendulator and NintendulatorNRS set up nametable mirroring in each mapper's code, and if that mapper has no provisions for 4-Screen Mode, the bit will not have any effect. Emulators that obey the 4-screen bit for any mapper will do so because they enforce that bit outside of the mapper emulation code. It is basically a normative decision to specify whether that bit is supposed to be thought of as "informative" for the mapper emulation code, or as "overriding" anything that the mapper normally does. Unless you want make it obligatory which understanding is correct --- something I would like, but only for NES 2.0 ---, a page like this, which is mostly descriptive of a legacy format, should simply state: "The four-screen bit cannot be assumed to override the normal mirroring settings of mappers that have not existed in four-screen variants during the NES era, or as real hardware for homebrew mappers. Some emulators will allow for such an override, while others (e.g. Nintendulator) do not." [[User:NewRisingSun|NewRisingSun]] ([[User talk:NewRisingSun|talk]]) 01:45, 15 January 2019 (MST)<br />
<br />
::: Nintendulator is just ONE emulator, not "most emulators". Besides, you have to remember that, originally in iNES 1.0, it seemed very clear to me that this bits overriedes other mirroring-related behaviour. For instance, MMC3 has no "provitions for 4-screen mirroring" or anything like that - 4-screen mirroring is an hardware feature that can be installed on any cartridge regardless of it's mapper, and tha happened to have been installed on two officially released MMC3 games. In this regard, I think Nintendulator is actually wrong, if it does not gives you 4 independant nametables when this bit is set with any mapper that does not have complex VRAM features. It should be able to give you NROM/CNROM/GNROM/UNROM/MMC1/MMC2/MMC4, etc... with 4-screen just fine. If it doesn't I'd consider it a bug in the emulator that does not respect the iNES format. HOWEVER with advanced mappers such as MMC5, VRC6 or Namo Mapper, it's understandable the mapper already fucks with nametables and there's no cannonical way to implement 4-screen mirroring without conflicting with other features, so in those cases it's fine to ignore the bit.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 02:59, 15 January 2019 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:INES&diff=13885Talk:INES2019-01-15T08:21:26Z<p>Bregalad: /* 4-screen mirroring */</p>
<hr />
<div>How does a PlayChoice hint screen work? --[[User:Zzo38|Zzo38]] 19:08, 21 September 2012 (MDT)<br />
<br />
== Last 4 ==<br />
<br />
Should this be "if the last ''5'' bytes are not all zero"? "A general rule of thumb: if the last 4 bytes are not all zero, and the header is not marked for NES 2.0 format, an emulator should either mask off the upper 4 bits of the mapper number or simply refuse to load the ROM." -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 03:45, 14 July 2013 (MDT)<br />
:When I wrote 4 as the rule of thumb, I didn't know how many not-widely-adopted extensions to original iNES were floating around, and I guessed that one or more might have used byte 11 for something, but all of the ROMs I saw with DiskDude and similar tags had at least something in the last four bytes of the header. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 07:48, 14 July 2013 (MDT)<br />
:: Makes sense. Just wanted to check whether it was a typo. -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 09:06, 14 July 2013 (MDT)<br />
:Nestopia checks the last 6, and clears/ignores the last 9. (It also actually does pay attention to bytes 8 and 9)—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 11:21, 14 July 2013 (MDT)<br />
:If the header contains "DiskDude!" or one of those other things (I forget now, but I knew at one time and figured this out), then bit2 of flags 7 will be set; otherwise bit2 and bit3 should both be cleared. This may be another way. --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 19:51, 20 August 2013 (MDT)<br />
<br />
== 4-screen mirroring ==<br />
<br />
Reference needed I'm afraid.<br />
<br />
"Theoretically bit 3 could be used for most mappers that had hard-wired mirroring to transparently provide 4KB of VRAM for 4-screen instead. However, many emulators will ignore this bit except for mappers with prior 4-screen variations."<br />
<br />
I'm fairly confident most emulators will happily gives you 4-screen mirroring when asked for it, even if they are in mappers where such a possibility wasn't used. I remember at some point considering using 4-screen mirroring with CNROM and it worked well.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:55, 13 January 2019 (MST)<br />
<br />
: In my limited experience, most emulators will let you start with 4-screen layout, but if the mapper has a mirroring control register, using it will irrevocably remove the extra nametables. For example, this is what goes wrong when trying to run Vs. Goonies on FCEUX as mapper 75 instead of mapper 151. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 02:13, 13 January 2019 (MST)<br />
<br />
:: Ah ok. This is super weird, such a behaviour would be almost impossible to pull out in real hardware.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 02:20, 13 January 2019 (MST)<br />
<br />
::: As a curious aside, mappers [[NES 2.0 Mapper 356|356]] and [[NES 2.0 Mapper 512|512]] could do that if powered on in 4-screen mode. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:35, 13 January 2019 (MST)<br />
<br />
: How do you think this should be worded? The point I'm trying to be careful about is basically that there are only two ROMs that have ever put this bit to actual meaningful use (4, 206). The rest is "theoretical" because nobody's released a game or test ROMs to verify the hundreds of other mappers that could maybe apply it. Because of that I have very low confidence that "most emulators" will get a completely untested feature correct. Testing this would actually be quite a big research project though. I am trying to keep this describing what exists, and not making it into a rule of "emulator authors should/must do it this way" that might not match reality and give people the expectation that they can safely use such an untested feature. Can you help write an alternative/better way to express this? I'll switch the wording to say "largely untested" for starters, but I'm sure it could be said better. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 12:28, 13 January 2019 (MST)<br />
<br />
:: Well I don't know exactly, but something like that : "The 4-screen mirroring feature is largely untested with mappers wiout prior games using a 4-screen variation". This means that it's supposed to work, however it's untested and that's what makes the most sense in this contex. Saying "most emulators will ignore the bit" seems overreaching to me. [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:21, 15 January 2019 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:INES&diff=13881Talk:INES2019-01-13T09:20:41Z<p>Bregalad: /* 4-screen mirroring */</p>
<hr />
<div>How does a PlayChoice hint screen work? --[[User:Zzo38|Zzo38]] 19:08, 21 September 2012 (MDT)<br />
<br />
== Last 4 ==<br />
<br />
Should this be "if the last ''5'' bytes are not all zero"? "A general rule of thumb: if the last 4 bytes are not all zero, and the header is not marked for NES 2.0 format, an emulator should either mask off the upper 4 bits of the mapper number or simply refuse to load the ROM." -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 03:45, 14 July 2013 (MDT)<br />
:When I wrote 4 as the rule of thumb, I didn't know how many not-widely-adopted extensions to original iNES were floating around, and I guessed that one or more might have used byte 11 for something, but all of the ROMs I saw with DiskDude and similar tags had at least something in the last four bytes of the header. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 07:48, 14 July 2013 (MDT)<br />
:: Makes sense. Just wanted to check whether it was a typo. -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 09:06, 14 July 2013 (MDT)<br />
:Nestopia checks the last 6, and clears/ignores the last 9. (It also actually does pay attention to bytes 8 and 9)—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 11:21, 14 July 2013 (MDT)<br />
:If the header contains "DiskDude!" or one of those other things (I forget now, but I knew at one time and figured this out), then bit2 of flags 7 will be set; otherwise bit2 and bit3 should both be cleared. This may be another way. --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 19:51, 20 August 2013 (MDT)<br />
<br />
== 4-screen mirroring ==<br />
<br />
Reference needed I'm afraid.<br />
<br />
"Theoretically bit 3 could be used for most mappers that had hard-wired mirroring to transparently provide 4KB of VRAM for 4-screen instead. However, many emulators will ignore this bit except for mappers with prior 4-screen variations."<br />
<br />
I'm fairly confident most emulators will happily gives you 4-screen mirroring when asked for it, even if they are in mappers where such a possibility wasn't used. I remember at some point considering using 4-screen mirroring with CNROM and it worked well.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:55, 13 January 2019 (MST)<br />
<br />
: In my limited experience, most emulators will let you start with 4-screen layout, but if the mapper has a mirroring control register, using it will irrevocably remove the extra nametables. For example, this is what goes wrong when trying to run Vs. Goonies on FCEUX as mapper 75 instead of mapper 151. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 02:13, 13 January 2019 (MST)<br />
<br />
:: Ah ok. This is super weird, such a behaviour would be almost impossible to pull out in real hardware.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 02:20, 13 January 2019 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:INES&diff=13879Talk:INES2019-01-13T08:55:55Z<p>Bregalad: /* 4-screen mirroring */ new section</p>
<hr />
<div>How does a PlayChoice hint screen work? --[[User:Zzo38|Zzo38]] 19:08, 21 September 2012 (MDT)<br />
<br />
== Last 4 ==<br />
<br />
Should this be "if the last ''5'' bytes are not all zero"? "A general rule of thumb: if the last 4 bytes are not all zero, and the header is not marked for NES 2.0 format, an emulator should either mask off the upper 4 bits of the mapper number or simply refuse to load the ROM." -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 03:45, 14 July 2013 (MDT)<br />
:When I wrote 4 as the rule of thumb, I didn't know how many not-widely-adopted extensions to original iNES were floating around, and I guessed that one or more might have used byte 11 for something, but all of the ROMs I saw with DiskDude and similar tags had at least something in the last four bytes of the header. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 07:48, 14 July 2013 (MDT)<br />
:: Makes sense. Just wanted to check whether it was a typo. -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 09:06, 14 July 2013 (MDT)<br />
:Nestopia checks the last 6, and clears/ignores the last 9. (It also actually does pay attention to bytes 8 and 9)—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 11:21, 14 July 2013 (MDT)<br />
:If the header contains "DiskDude!" or one of those other things (I forget now, but I knew at one time and figured this out), then bit2 of flags 7 will be set; otherwise bit2 and bit3 should both be cleared. This may be another way. --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 19:51, 20 August 2013 (MDT)<br />
<br />
== 4-screen mirroring ==<br />
<br />
Reference needed I'm afraid.<br />
<br />
"Theoretically bit 3 could be used for most mappers that had hard-wired mirroring to transparently provide 4KB of VRAM for 4-screen instead. However, many emulators will ignore this bit except for mappers with prior 4-screen variations."<br />
<br />
I'm fairly confident most emulators will happily gives you 4-screen mirroring when asked for it, even if they are in mappers where such a possibility wasn't used. I remember at some point considering using 4-screen mirroring with CNROM and it worked well.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:55, 13 January 2019 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=SxROM&diff=11555SxROM2019-01-09T10:32:15Z<p>Bregalad: Sorry to insist, but the boards are made with optional battery backup. Whether games used this option or not is irrelveant here. But you're right it's a good idea to leave redundant info since the way to select banks can be a little confusing.</p>
<hr />
<div>[[Category:Nintendo licensed mappers]]<br />
The generic designation '''SxROM''' refers to cartridge boards made by Nintendo that use the [[MMC1|Nintendo MMC1]] mapper.<br />
<br />
== Board types ==<br />
<br />
The following SxROM boards are known to exist:<br />
{| class="tabular"<br />
! Board || PRG ROM || PRG RAM || CHR || Comments<br />
|-<br />
| {{nesdblink|unif_wild|SAROM|SAROM}} || 64 KB || 8 KB || 16 / 32 / 64 KB ROM || NES only<br />
|-<br />
| {{nesdblink|unif_wild|SBROM|SBROM}} || 64 KB || || 16 / 32 / 64 KB ROM || NES only<br />
|-<br />
| {{nesdblink|unif_wild|SCROM|SCROM}} || 64 KB || || 128 KB ROM || NES only<br />
|-<br />
| {{nesdblink|unif_wild|SC1ROM|SC1ROM}} || 64 KB || || 128 KB ROM || Uses [[7432]] for 28-pin CHR ROM<br />
|-<br />
| {{nesdblink|unif_wild|SEROM|SEROM}} || 32 KB || || 16 / 32 / 64 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SFROM|SFROM}} || 128 / 256 KB || || 16 / 32 / 64 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SF1ROM|SF1ROM}} || 256 KB || || 64 KB ROM || [http://forums.nesdev.org/viewtopic.php?p=139126#p139126 PRG uses standard 32-pin EPROM pinout]<br />
|-<br />
| [http://bootgod.dyndns.org:7777/profile.php?id=745 SFEXPROM] || 256 KB || || 64 KB ROM || [http://forums.nesdev.org/viewtopic.php?t=1371 Patches PRG at runtime] to correct a bad mask ROM run.<br />
|-<br />
| {{nesdblink|unif_wild|SGROM|SGROM}} || 128 / 256 KB || || 8 KB RAM/ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SHROM|SHROM}} || 32 KB || || 128 KB ROM || NES only<br />
|-<br />
| {{nesdblink|unif_wild|SH1ROM|SH1ROM}} || 32 KB || || 128 KB ROM || Uses [[7432]] for 28-pin CHR ROM<br />
|-<br />
| {{nesdblink|unif_wild|SIROM|SIROM}} || 32 KB || 8 KB || 16 / 32 / 64 KB ROM || Japan Only<br />
|-<br />
| {{nesdblink|unif_wild|SJROM|SJROM}} || 128 / 256 KB || 8 KB || 16 / 32 / 64 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SKROM|SKROM}} || 128 / 256 KB || 8 KB || 128 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SLROM|SLROM}} || 128 / 256 KB || || 128 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SL1ROM|SL1ROM}} || 64 / 128 / 256 KB || || 128 KB ROM || Uses [[7432]] for 28-pin CHR ROM<br />
|-<br />
| {{nesdblink|unif_wild|SL2ROM|SL2ROM}} || 128 / 256 KB || || 128 KB ROM || [http://forums.nesdev.org/viewtopic.php?t=12657 CHR uses standard 32-pin EPROM pinout]<br />
|-<br />
| {{nesdblink|unif_wild|SL3ROM|SL3ROM}} || 256 KB || || 128 KB ROM || Uses [[7432]] for 28-pin CHR ROM<br />
|-<br />
| {{nesdblink|unif_wild|SLRROM|SLRROM}} || 128 / 256 KB || || 128 KB ROM || Difference from SLROM unknown<br />
|-<br />
| {{nesdblink|unif_wild|SMROM|SMROM}} || 256 KB || || 8 KB RAM || Japan Only<br />
|-<br />
| {{nesdblink|unif_wild|SNROM|SNROM}} || 128 / 256 KB || 8 KB || 8 KB RAM/ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SOROM|SOROM}} || 128 / 256 KB || 16 KB || 8 KB RAM/ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|STROM|STROM}} || colspan=4|Not MMC1, actually [[NROM]]<br />
|-<br />
| {{nesdblink|unif_wild|SUROM|SUROM}} || 512 KB || 8 KB || 8 KB RAM/ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SXROM|SXROM}} || 128 / 256 / 512 KB || 32 KB || 8 KB RAM/ROM || Japan Only<br />
|-<br />
| [https://www.crazysmart.net.au/phpBB3/viewtopic.php?f=10&t=8&p=9#p9 SZROM] || 128 / 256 KB || 16 KB || 16-64 KB ROM || Japan Only<br />
|}<br />
<br />
== Solder pad config ==<br />
<br />
=== Battery data retention ===<br />
<br />
'''The below pertains to SAROM, SJROM, SKROM, SNROM, SUROM, and SXROM boards only:'''<br />
<br />
* PRG RAM retaining data : 'SL' disconnected, Battery, D1, D2, R1 R2 and R3 present.<br />
* PRG RAM not retaining data : 'SL' connected, leave slots for Battery, D1, D2, R1, R2 and R3 free.<br />
<br />
Even if the SOROM and SZROM boards utilizes a battery, it is connected to only one PRG RAM chip. The first RAM chip will not retain its data, but the second one will. <br />
<br />
== Higher CHR lines ==<br />
<br />
The SUROM, SOROM, and SXROM boards are extensions of SNROM, which has CHR RAM and PRG RAM.<br />
Because CHR RAM doesn't need bankswitching, these boards use the CHR bank select lines to switch different things:<br />
<br />
*SNROM uses the upper CHR bank select line coming out of the mapper (CHR A16; bit 4 of bank number) as an additional chip enable for the PRG RAM.[http://forums.nesdev.org/viewtopic.php?t=7045] All other boards with PRG RAM appear to tie /CE to ground.<br />
*SUROM uses CHR A16 to control the upper address line (PRG A18) of its 512KB PRG ROM.<br />
*SOROM uses a similar method, using the second-highest CHR bank select line to choose between two 8KB PRG RAM chips. Only the RAM chip selected by driving CHR A15 high can be battery backed.<br />
*SXROM is a combination of SOROM and SUROM, addressing both 512KB of PRG ROM and 32KB of PRG RAM.<br />
<br />
*SZROM retains multiple address lines for CHR ROM banking, but also has 16 KiB of PRG RAM. It uses CHR A16, instead of SOROM's CHR A15, to select between two 8 KiB PRG RAM chips. Similar to SOROM, only the RAM chip selected by driving CHR A16 high can be battery backed.<br />
<br />
In these scenarios, however, both CHR bank registers must be set to the same value (or the CHR bank size must be set to 8KB), or the PRG ROM/RAM will be bankswitched as the PPU renders, causing disastrous results.<br />
<br />
== Various notes ==<br />
<br />
* The SEROM, SHROM, and SH1ROM boards, all used for games with 32 KiB PRG such as Dr. Mario, do not connect the PRG ROM's A14 to the MMC1; instead A14 is connected directly to the NES. This means the PRG ROM bank register and the PRG ROM bank mode bits have no effect.[http://forums.nesdev.org/viewtopic.php?p=94803#p94803] SIROM does not seem to share this property, despite having 32 KiB PRG.<br />
* SLxROM boards are functionally identical to SLROM, but with different chip pinouts. Some of them have an additional [[7432|74HC32]] chip to combine PPU /RD and PPU /A13 into a single enable signal for the CHR ROM chip that has only 28 pins.<br />
* SMROM is functionally identical to SGROM, but features two 128 KB PRG ROM chips instead of one 256 KB. Only a very early MMC1 game in Japan is known to have used this board, and one of very few Nintendo-made boards which combine smaller ROM chips to get a bigger ROM.<br />
* One SNROM game for Famicom uses an 8 KiB CHR ROM instead of CHR RAM: ''[http://bootgod.dyndns.org:7777/profile.php?id=3479 Morita Shogi]''. The [[6264 static RAM|6264]] pinout is nearly identical to the pinout of an 8 KiB [[mask ROM pinout|mask ROM]], except for pins 26 and 27. On the 6264, these are a positive chip enable (CS2) and negative write enable (/WE) respectively; on the mask ROM, they may be additional positive chip enables. Either way, they're high during reads.<br />
* Even boards which different usage of upper CHR lines are all assigned to '''NES Mapper 1'''. Emulators can distinguish SOROM and SXROM from SNROM using the new PRG RAM size fields in [[NES 2.0]] or using a PRG hash for legacy iNES ROMs. Therefore, it is recommended that ROM images of SOROM and SXROM games be stored in NES 2.0 format to allow an emulator to distinguish them from SNROM or SUROM.</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:SxROM&diff=15764Talk:SxROM2019-01-09T10:24:19Z<p>Bregalad: Undo revision 16096 by Bregalad (talk) Never mind.</p>
<hr />
<div></div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:SxROM&diff=15763Talk:SxROM2019-01-09T10:22:16Z<p>Bregalad: Why I "threw up" information</p>
<hr />
<div>@lidnariq: I "threw up information" because this page is supposed to be a summary/overview page, and the details are already in the MMC1 main page.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 03:22, 9 January 2019 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=SxROM&diff=11553SxROM2019-01-09T07:49:57Z<p>Bregalad: /* Higher CHR lines */ Better wording for SOROM / SZROM.</p>
<hr />
<div>[[Category:Nintendo licensed mappers]]<br />
The generic designation '''SxROM''' refers to cartridge boards made by Nintendo that use the [[MMC1|Nintendo MMC1]] mapper.<br />
<br />
== Board types ==<br />
<br />
The following SxROM boards are known to exist:<br />
{| class="tabular"<br />
! Board || PRG ROM || PRG RAM || CHR || Comments<br />
|-<br />
| {{nesdblink|unif_wild|SAROM|SAROM}} || 64 KB || 8 KB || 16 / 32 / 64 KB ROM || NES only<br />
|-<br />
| {{nesdblink|unif_wild|SBROM|SBROM}} || 64 KB || || 16 / 32 / 64 KB ROM || NES only<br />
|-<br />
| {{nesdblink|unif_wild|SCROM|SCROM}} || 64 KB || || 128 KB ROM || NES only<br />
|-<br />
| {{nesdblink|unif_wild|SC1ROM|SC1ROM}} || 64 KB || || 128 KB ROM || Uses [[7432]] for 28-pin CHR ROM<br />
|-<br />
| {{nesdblink|unif_wild|SEROM|SEROM}} || 32 KB || || 16 / 32 / 64 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SFROM|SFROM}} || 128 / 256 KB || || 16 / 32 / 64 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SF1ROM|SF1ROM}} || 256 KB || || 64 KB ROM || [http://forums.nesdev.org/viewtopic.php?p=139126#p139126 PRG uses standard 32-pin EPROM pinout]<br />
|-<br />
| [http://bootgod.dyndns.org:7777/profile.php?id=745 SFEXPROM] || 256 KB || || 64 KB ROM || [http://forums.nesdev.org/viewtopic.php?t=1371 Patches PRG at runtime] to correct a bad mask ROM run.<br />
|-<br />
| {{nesdblink|unif_wild|SGROM|SGROM}} || 128 / 256 KB || || 8 KB RAM/ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SHROM|SHROM}} || 32 KB || || 128 KB ROM || NES only<br />
|-<br />
| {{nesdblink|unif_wild|SH1ROM|SH1ROM}} || 32 KB || || 128 KB ROM || Uses [[7432]] for 28-pin CHR ROM<br />
|-<br />
| {{nesdblink|unif_wild|SIROM|SIROM}} || 32 KB || 8 KB || 16 / 32 / 64 KB ROM || Japan Only<br />
|-<br />
| {{nesdblink|unif_wild|SJROM|SJROM}} || 128 / 256 KB || 8 KB || 16 / 32 / 64 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SKROM|SKROM}} || 128 / 256 KB || 8 KB || 128 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SLROM|SLROM}} || 128 / 256 KB || || 128 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SL1ROM|SL1ROM}} || 64 / 128 / 256 KB || || 128 KB ROM || Uses [[7432]] for 28-pin CHR ROM<br />
|-<br />
| {{nesdblink|unif_wild|SL2ROM|SL2ROM}} || 128 / 256 KB || || 128 KB ROM || [http://forums.nesdev.org/viewtopic.php?t=12657 CHR uses standard 32-pin EPROM pinout]<br />
|-<br />
| {{nesdblink|unif_wild|SL3ROM|SL3ROM}} || 256 KB || || 128 KB ROM || Uses [[7432]] for 28-pin CHR ROM<br />
|-<br />
| {{nesdblink|unif_wild|SLRROM|SLRROM}} || 128 / 256 KB || || 128 KB ROM || Difference from SLROM unknown<br />
|-<br />
| {{nesdblink|unif_wild|SMROM|SMROM}} || 256 KB || || 8 KB RAM || Japan Only<br />
|-<br />
| {{nesdblink|unif_wild|SNROM|SNROM}} || 128 / 256 KB || 8 KB || 8 KB RAM/ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SOROM|SOROM}} || 128 / 256 KB || 16 KB || 8 KB RAM/ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|STROM|STROM}} || colspan=4|Not MMC1, actually [[NROM]]<br />
|-<br />
| {{nesdblink|unif_wild|SUROM|SUROM}} || 512 KB || 8 KB || 8 KB RAM/ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SXROM|SXROM}} || 128 / 256 / 512 KB || 32 KB || 8 KB RAM/ROM || Japan Only<br />
|-<br />
| [https://www.crazysmart.net.au/phpBB3/viewtopic.php?f=10&t=8&p=9#p9 SZROM] || 128 / 256 KB || 16 KB || 16-64 KB ROM || Japan Only<br />
|}<br />
<br />
== Solder pad config ==<br />
<br />
=== Battery data retention ===<br />
<br />
'''The below pertains to SAROM, SJROM, SKROM, SNROM, SUROM, and SXROM boards only:'''<br />
<br />
* PRG RAM retaining data : 'SL' disconnected, Battery, D1, D2, R1 R2 and R3 present.<br />
* PRG RAM not retaining data : 'SL' connected, leave slots for Battery, D1, D2, R1, R2 and R3 free.<br />
<br />
Even if the SOROM boards utilizes a battery, it is connected to only one PRG RAM chip. The first RAM chip will not retain its data, but the second one will. <br />
<br />
== Higher CHR lines ==<br />
<br />
The SUROM, SOROM, and SXROM boards are extensions of SNROM, which has CHR RAM and PRG RAM.<br />
Because CHR RAM doesn't need bankswitching, these boards use the CHR bank select lines to switch different things:<br />
<br />
*SNROM uses the upper CHR bank select line coming out of the mapper (CHR A16; bit 4 of bank number) as an additional chip enable for the PRG RAM.[http://forums.nesdev.org/viewtopic.php?t=7045] All other boards with PRG RAM appear to tie /CE to ground.<br />
*SUROM uses CHR A16 to control the upper address line (PRG A18) of its 512KB PRG ROM.<br />
*SOROM uses a similar method, using the second-highest CHR bank select line to choose between two 8KB PRG RAM chips. Only one 8KB RAM chip can be battery backed.<br />
*SXROM is a combination of SOROM and SUROM, addressing both 512KB of PRG ROM and 32KB of PRG RAM.<br />
<br />
*SZROM retains multiple address lines for CHR ROM banking, but also has 16 KiB of PRG RAM. It uses CHR A16, instead of SOROM's CHR A15, to select between two 8 KiB PRG RAM chips. Like SOROM, only one chip can be battery-backed.<br />
<br />
In these scenarios, however, both CHR bank registers must be set to the same value (or the CHR bank size must be set to 8KB), or the PRG ROM/RAM will be bankswitched as the PPU renders, causing disastrous results.<br />
<br />
== Various notes ==<br />
<br />
* The SEROM, SHROM, and SH1ROM boards, all used for games with 32 KiB PRG such as Dr. Mario, do not connect the PRG ROM's A14 to the MMC1; instead A14 is connected directly to the NES. This means the PRG ROM bank register and the PRG ROM bank mode bits have no effect.[http://forums.nesdev.org/viewtopic.php?p=94803#p94803] SIROM does not seem to share this property, despite having 32 KiB PRG.<br />
* SLxROM boards are functionally identical to SLROM, but with different chip pinouts. Some of them have an additional [[7432|74HC32]] chip to combine PPU /RD and PPU /A13 into a single enable signal for the CHR ROM chip that has only 28 pins.<br />
* SMROM is functionally identical to SGROM, but features two 128 KB PRG ROM chips instead of one 256 KB. Only a very early MMC1 game in Japan is known to have used this board, and one of very few Nintendo-made boards which combine smaller ROM chips to get a bigger ROM.<br />
* One SNROM game for Famicom uses an 8 KiB CHR ROM instead of CHR RAM: ''[http://bootgod.dyndns.org:7777/profile.php?id=3479 Morita Shogi]''. The [[6264 static RAM|6264]] pinout is nearly identical to the pinout of an 8 KiB [[mask ROM pinout|mask ROM]], except for pins 26 and 27. On the 6264, these are a positive chip enable (CS2) and negative write enable (/WE) respectively; on the mask ROM, they may be additional positive chip enables. Either way, they're high during reads.<br />
* Even boards which different usage of upper CHR lines are all assigned to '''NES Mapper 1'''. Emulators can distinguish SOROM and SXROM from SNROM using the new PRG RAM size fields in [[NES 2.0]] or using a PRG hash for legacy iNES ROMs. Therefore, it is recommended that ROM images of SOROM and SXROM games be stored in NES 2.0 format to allow an emulator to distinguish them from SNROM or SUROM.</div>Bregaladhttps://www.nesdev.org/w/index.php?title=SxROM&diff=11552SxROM2019-01-09T07:47:42Z<p>Bregalad: /* Board types */ SZROM is japan only</p>
<hr />
<div>[[Category:Nintendo licensed mappers]]<br />
The generic designation '''SxROM''' refers to cartridge boards made by Nintendo that use the [[MMC1|Nintendo MMC1]] mapper.<br />
<br />
== Board types ==<br />
<br />
The following SxROM boards are known to exist:<br />
{| class="tabular"<br />
! Board || PRG ROM || PRG RAM || CHR || Comments<br />
|-<br />
| {{nesdblink|unif_wild|SAROM|SAROM}} || 64 KB || 8 KB || 16 / 32 / 64 KB ROM || NES only<br />
|-<br />
| {{nesdblink|unif_wild|SBROM|SBROM}} || 64 KB || || 16 / 32 / 64 KB ROM || NES only<br />
|-<br />
| {{nesdblink|unif_wild|SCROM|SCROM}} || 64 KB || || 128 KB ROM || NES only<br />
|-<br />
| {{nesdblink|unif_wild|SC1ROM|SC1ROM}} || 64 KB || || 128 KB ROM || Uses [[7432]] for 28-pin CHR ROM<br />
|-<br />
| {{nesdblink|unif_wild|SEROM|SEROM}} || 32 KB || || 16 / 32 / 64 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SFROM|SFROM}} || 128 / 256 KB || || 16 / 32 / 64 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SF1ROM|SF1ROM}} || 256 KB || || 64 KB ROM || [http://forums.nesdev.org/viewtopic.php?p=139126#p139126 PRG uses standard 32-pin EPROM pinout]<br />
|-<br />
| [http://bootgod.dyndns.org:7777/profile.php?id=745 SFEXPROM] || 256 KB || || 64 KB ROM || [http://forums.nesdev.org/viewtopic.php?t=1371 Patches PRG at runtime] to correct a bad mask ROM run.<br />
|-<br />
| {{nesdblink|unif_wild|SGROM|SGROM}} || 128 / 256 KB || || 8 KB RAM/ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SHROM|SHROM}} || 32 KB || || 128 KB ROM || NES only<br />
|-<br />
| {{nesdblink|unif_wild|SH1ROM|SH1ROM}} || 32 KB || || 128 KB ROM || Uses [[7432]] for 28-pin CHR ROM<br />
|-<br />
| {{nesdblink|unif_wild|SIROM|SIROM}} || 32 KB || 8 KB || 16 / 32 / 64 KB ROM || Japan Only<br />
|-<br />
| {{nesdblink|unif_wild|SJROM|SJROM}} || 128 / 256 KB || 8 KB || 16 / 32 / 64 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SKROM|SKROM}} || 128 / 256 KB || 8 KB || 128 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SLROM|SLROM}} || 128 / 256 KB || || 128 KB ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SL1ROM|SL1ROM}} || 64 / 128 / 256 KB || || 128 KB ROM || Uses [[7432]] for 28-pin CHR ROM<br />
|-<br />
| {{nesdblink|unif_wild|SL2ROM|SL2ROM}} || 128 / 256 KB || || 128 KB ROM || [http://forums.nesdev.org/viewtopic.php?t=12657 CHR uses standard 32-pin EPROM pinout]<br />
|-<br />
| {{nesdblink|unif_wild|SL3ROM|SL3ROM}} || 256 KB || || 128 KB ROM || Uses [[7432]] for 28-pin CHR ROM<br />
|-<br />
| {{nesdblink|unif_wild|SLRROM|SLRROM}} || 128 / 256 KB || || 128 KB ROM || Difference from SLROM unknown<br />
|-<br />
| {{nesdblink|unif_wild|SMROM|SMROM}} || 256 KB || || 8 KB RAM || Japan Only<br />
|-<br />
| {{nesdblink|unif_wild|SNROM|SNROM}} || 128 / 256 KB || 8 KB || 8 KB RAM/ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SOROM|SOROM}} || 128 / 256 KB || 16 KB || 8 KB RAM/ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|STROM|STROM}} || colspan=4|Not MMC1, actually [[NROM]]<br />
|-<br />
| {{nesdblink|unif_wild|SUROM|SUROM}} || 512 KB || 8 KB || 8 KB RAM/ROM ||<br />
|-<br />
| {{nesdblink|unif_wild|SXROM|SXROM}} || 128 / 256 / 512 KB || 32 KB || 8 KB RAM/ROM || Japan Only<br />
|-<br />
| [https://www.crazysmart.net.au/phpBB3/viewtopic.php?f=10&t=8&p=9#p9 SZROM] || 128 / 256 KB || 16 KB || 16-64 KB ROM || Japan Only<br />
|}<br />
<br />
== Solder pad config ==<br />
<br />
=== Battery data retention ===<br />
<br />
'''The below pertains to SAROM, SJROM, SKROM, SNROM, SUROM, and SXROM boards only:'''<br />
<br />
* PRG RAM retaining data : 'SL' disconnected, Battery, D1, D2, R1 R2 and R3 present.<br />
* PRG RAM not retaining data : 'SL' connected, leave slots for Battery, D1, D2, R1, R2 and R3 free.<br />
<br />
Even if the SOROM boards utilizes a battery, it is connected to only one PRG RAM chip. The first RAM chip will not retain its data, but the second one will. <br />
<br />
== Higher CHR lines ==<br />
<br />
The SUROM, SOROM, and SXROM boards are extensions of SNROM, which has CHR RAM and PRG RAM.<br />
Because CHR RAM doesn't need bankswitching, these boards use the CHR bank select lines to switch different things:<br />
<br />
*SNROM uses the upper CHR bank select line coming out of the mapper (CHR A16; bit 4 of bank number) as an additional chip enable for the PRG RAM.[http://forums.nesdev.org/viewtopic.php?t=7045] All other boards with PRG RAM appear to tie /CE to ground.<br />
*SUROM uses CHR A16 to control the upper address line (PRG A18) of its 512KB PRG ROM.<br />
*SOROM uses a similar method, using the second-highest CHR bank select line to choose between two 8KB PRG RAM chips. Of chip 0 and chip 1, only chip 1 is battery backed.<br />
*SXROM is a combination of SOROM and SUROM, addressing both 512KB of PRG ROM and 32KB of PRG RAM.<br />
<br />
*SZROM retains multiple address lines for CHR ROM banking, but also has 16 KiB of PRG RAM. It uses CHR A16, instead of SOROM's CHR A15, to select between two 8 KiB PRG RAM chips. Like SOROM, only chip 1 is battery-backed.<br />
<br />
In these scenarios, however, both CHR bank registers must be set to the same value (or the CHR bank size must be set to 8KB), or the PRG ROM/RAM will be bankswitched as the PPU renders, causing disastrous results.<br />
<br />
== Various notes ==<br />
<br />
* The SEROM, SHROM, and SH1ROM boards, all used for games with 32 KiB PRG such as Dr. Mario, do not connect the PRG ROM's A14 to the MMC1; instead A14 is connected directly to the NES. This means the PRG ROM bank register and the PRG ROM bank mode bits have no effect.[http://forums.nesdev.org/viewtopic.php?p=94803#p94803] SIROM does not seem to share this property, despite having 32 KiB PRG.<br />
* SLxROM boards are functionally identical to SLROM, but with different chip pinouts. Some of them have an additional [[7432|74HC32]] chip to combine PPU /RD and PPU /A13 into a single enable signal for the CHR ROM chip that has only 28 pins.<br />
* SMROM is functionally identical to SGROM, but features two 128 KB PRG ROM chips instead of one 256 KB. Only a very early MMC1 game in Japan is known to have used this board, and one of very few Nintendo-made boards which combine smaller ROM chips to get a bigger ROM.<br />
* One SNROM game for Famicom uses an 8 KiB CHR ROM instead of CHR RAM: ''[http://bootgod.dyndns.org:7777/profile.php?id=3479 Morita Shogi]''. The [[6264 static RAM|6264]] pinout is nearly identical to the pinout of an 8 KiB [[mask ROM pinout|mask ROM]], except for pins 26 and 27. On the 6264, these are a positive chip enable (CS2) and negative write enable (/WE) respectively; on the mask ROM, they may be additional positive chip enables. Either way, they're high during reads.<br />
* Even boards which different usage of upper CHR lines are all assigned to '''NES Mapper 1'''. Emulators can distinguish SOROM and SXROM from SNROM using the new PRG RAM size fields in [[NES 2.0]] or using a PRG hash for legacy iNES ROMs. Therefore, it is recommended that ROM images of SOROM and SXROM games be stored in NES 2.0 format to allow an emulator to distinguish them from SNROM or SUROM.</div>Bregaladhttps://www.nesdev.org/w/index.php?title=MMC5&diff=6744MMC52018-12-22T15:22:43Z<p>Bregalad: /* CHR Bankswitching ($5120-$5130) */ Misspelling fixed.</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 />
|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]]<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 />
* A scanline based IRQ counter<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 />
=== 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, recent research found that bits 2-3 control state of two unknown pins which acts like A15-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.<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]<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 />
It is not currently known how the MMC5 detects the sprite size being used by the PPU.<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 most mappers supporting multiple bank sizes, 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'' is the only known game to use split screen mode (during the intro, where it shows ship stats). It is [https://forums.nesdev.org/viewtopic.php?f=2&t=12764| suspected but not confirmed] that ''Bandit Kings of Ancient China'' also uses split screen mode during the ending sequence.<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, however when you scroll to 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 may only use vertical scroll values whose bottom 3 bits match the [[PPU|Nes PPU]]'s fine vertical scroll value. 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 Counter ($5203) ====<br />
All eight bits specify the scanline number to generate IRQ at<br />
<br />
==== IRQ Status ($5204, read/write) ====<br />
===== Write =====<br />
7 bit 0<br />
---- ----<br />
Exxx xxxx<br />
|<br />
+--------- IRQ Enable flag (1=IRQs enabled)<br />
<br />
===== Read =====<br />
7 bit 0<br />
---- ----<br />
SVxx xxxx MMC5A default power-on value = $00<br />
||<br />
|+-------- "In Frame" signal<br />
+--------- IRQ Pending flag<br />
<br />
When set, the "In Frame" signal specifies that the PPU is currently rendering a scanline. It also plays a role in how IRQs are generated.<br />
<br />
The IRQ Pending flag may be raised even if IRQs are disabled.<br />
<br />
Any time this register is read, the 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 ==<br />
[[File:mmc5_in_frame_status_bit.png|thumb|right|MMC5 'in frame' status bit state diagram]]<br />
Scanline detection involves monitoring the addresses read by the PPU. In the state diagram to the right, PPU /RD going low indicates a read by the PPU. M2 rising indicates a clock cycle of the CPU. A PPU address is considered "in range" if the address is in the range $2000 - $2FFF.<br />
<br />
When the MMC5 has detected that a scanline is rendering, the 'in frame' status bit gets set in register $5204 and the internal 8-bit scanline counter is incremented. Software can use this status bit as an indication of whether or not the PPU is currently rendering.<br />
<br />
It appears that all 240 rendered scanlines as well as the pre-render scanline are all detected by the MMC5. It also appears that scanlines are detected near their end (or near the start of the next scanline). See also [http://forums.nesdev.org/viewtopic.php?t=7653].<br />
<br />
The 'in frame' status bit is cleared as soon as the MMC5 no longer detects PPU rendering. This happens at the end of the last rendered scanline, and whenever the PPU is switched off (Sprite and BG rendering disabled).<br />
<br />
Note that there are side-effects to switching off the PPU mid frame. Clearing the In Frame signal effectively resets the IRQ counter as can be seen in the logic given above. Therefore, if the PPU is switched back on in the frame, the IRQ counter will begin counting from $00 again.<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 />
== Scanline-Counting IRQ Operation ==<br />
<br />
The MMC5 has an internal 8-bit incrementing scanline counter that watches the PPU as it renders, and counts each passing scanline. When the counter reaches the scanline specified by register $5203, it generates an IRQ. For example, when register $5203 is set to $04, the IRQ will occur near the start of the 5th rendered scanline.<br />
<br />
When the MMC5 detects a scanline, the following events occur:<br />
* If the 'in frame' status bit is clear, set it, reset the IRQ counter to 0, and clear the IRQ Pending flag<br />
* Otherwise, increment the IRQ counter. If it now equals the IRQ scanline specified by register $5203, raise IRQ Pending flag and generate an IRQ if enabled<br />
<br />
Note the above logic makes it impossible for an IRQ to occur when $5203 is set to $00<br />
<br />
The IRQ Pending flag is raised when the desired scanline is reached ''regardless'' of whether or not IRQs are enabled. $5204.7 can still be read as set even when IRQ Enable flag is clear. However, an actual IRQ is only sent to the CPU if both the IRQ Enable flag and IRQ Pending flag are raised.<br />
<br />
== Hardware ==<br />
<br />
The MMC5 exists in a 100-pin TQFP 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 />
== See also ==<br />
* NES Mapper list by Disch [http://www.romhacking.net/documents/362/]<br />
* Nintendo MMC5 by goroh, translated by Sgt. Bowhack [http://nesdev.org/mmc5-e.txt]<br />
* Nintendo MMC5 Bankswitching by Kevin Horton [http://nesdev.org/mmc5_bank_switch.txt]</div>Bregaladhttps://www.nesdev.org/w/index.php?title=MMC5&diff=6743MMC52018-12-22T14:03:30Z<p>Bregalad: Makes PRG and CHR tables more alike to eachother, add warning about CHR bankswitching being in actual size. Remove note about nonexisting registers.</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 />
|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]]<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 />
* A scanline based IRQ counter<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 />
=== 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, recent research found that bits 2-3 control state of two unknown pins which acts like A15-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.<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]<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 />
It is not currently known how the MMC5 detects the sprite size being used by the PPU.<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 most mappers supporting multiple bank sizes, and unlike how PRG banking wors 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'' is the only known game to use split screen mode (during the intro, where it shows ship stats). It is [https://forums.nesdev.org/viewtopic.php?f=2&t=12764| suspected but not confirmed] that ''Bandit Kings of Ancient China'' also uses split screen mode during the ending sequence.<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, however when you scroll to 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 may only use vertical scroll values whose bottom 3 bits match the [[PPU|Nes PPU]]'s fine vertical scroll value. 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 Counter ($5203) ====<br />
All eight bits specify the scanline number to generate IRQ at<br />
<br />
==== IRQ Status ($5204, read/write) ====<br />
===== Write =====<br />
7 bit 0<br />
---- ----<br />
Exxx xxxx<br />
|<br />
+--------- IRQ Enable flag (1=IRQs enabled)<br />
<br />
===== Read =====<br />
7 bit 0<br />
---- ----<br />
SVxx xxxx MMC5A default power-on value = $00<br />
||<br />
|+-------- "In Frame" signal<br />
+--------- IRQ Pending flag<br />
<br />
When set, the "In Frame" signal specifies that the PPU is currently rendering a scanline. It also plays a role in how IRQs are generated.<br />
<br />
The IRQ Pending flag may be raised even if IRQs are disabled.<br />
<br />
Any time this register is read, the 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 ==<br />
[[File:mmc5_in_frame_status_bit.png|thumb|right|MMC5 'in frame' status bit state diagram]]<br />
Scanline detection involves monitoring the addresses read by the PPU. In the state diagram to the right, PPU /RD going low indicates a read by the PPU. M2 rising indicates a clock cycle of the CPU. A PPU address is considered "in range" if the address is in the range $2000 - $2FFF.<br />
<br />
When the MMC5 has detected that a scanline is rendering, the 'in frame' status bit gets set in register $5204 and the internal 8-bit scanline counter is incremented. Software can use this status bit as an indication of whether or not the PPU is currently rendering.<br />
<br />
It appears that all 240 rendered scanlines as well as the pre-render scanline are all detected by the MMC5. It also appears that scanlines are detected near their end (or near the start of the next scanline). See also [http://forums.nesdev.org/viewtopic.php?t=7653].<br />
<br />
The 'in frame' status bit is cleared as soon as the MMC5 no longer detects PPU rendering. This happens at the end of the last rendered scanline, and whenever the PPU is switched off (Sprite and BG rendering disabled).<br />
<br />
Note that there are side-effects to switching off the PPU mid frame. Clearing the In Frame signal effectively resets the IRQ counter as can be seen in the logic given above. Therefore, if the PPU is switched back on in the frame, the IRQ counter will begin counting from $00 again.<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 />
== Scanline-Counting IRQ Operation ==<br />
<br />
The MMC5 has an internal 8-bit incrementing scanline counter that watches the PPU as it renders, and counts each passing scanline. When the counter reaches the scanline specified by register $5203, it generates an IRQ. For example, when register $5203 is set to $04, the IRQ will occur near the start of the 5th rendered scanline.<br />
<br />
When the MMC5 detects a scanline, the following events occur:<br />
* If the 'in frame' status bit is clear, set it, reset the IRQ counter to 0, and clear the IRQ Pending flag<br />
* Otherwise, increment the IRQ counter. If it now equals the IRQ scanline specified by register $5203, raise IRQ Pending flag and generate an IRQ if enabled<br />
<br />
Note the above logic makes it impossible for an IRQ to occur when $5203 is set to $00<br />
<br />
The IRQ Pending flag is raised when the desired scanline is reached ''regardless'' of whether or not IRQs are enabled. $5204.7 can still be read as set even when IRQ Enable flag is clear. However, an actual IRQ is only sent to the CPU if both the IRQ Enable flag and IRQ Pending flag are raised.<br />
<br />
== Hardware ==<br />
<br />
The MMC5 exists in a 100-pin TQFP 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 />
== See also ==<br />
* NES Mapper list by Disch [http://www.romhacking.net/documents/362/]<br />
* Nintendo MMC5 by goroh, translated by Sgt. Bowhack [http://nesdev.org/mmc5-e.txt]<br />
* Nintendo MMC5 Bankswitching by Kevin Horton [http://nesdev.org/mmc5_bank_switch.txt]</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:MMC5&diff=14389Talk:MMC52018-12-21T22:10:51Z<p>Bregalad: /* PRG Bankswitching */</p>
<hr />
<div>== [[wikipedia:Don't repeat yourself|Don't Repeat Yourself]] failure ==<br />
Ok, it's crazy to have two completely different pages explaining the MMC5 mapper, one on iNES mapper 5 and the other on MMC5. I think the info should be present on a single page (like it is for all other mappers).<br />
<br />
Well in fact it seems it's Zeromus who added Dish's notes on all iNES mapper pages. This would be nice if the info wasn't already present on the wiki - having twice the same info isn't very logical is it ? I don't know what to do but something should probably be changed...Bregalad 00:36, 23 March 2012 (PDT)<br />
<br />
:Disch' format is '''much''' better for reading. Funny, I was really thinking to discuss about such thing. :) --[[User:Zepper|Zepper]] 14:44, 23 March 2012 (PDT)<br />
<br />
:Problem solved. @Zepper : If there is a particular point that should be improved about how the mappers are presented on the wiki, then please change it (or at least say more precisely what is ''much'' better).[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:02, 20 April 2015 (MDT)<br />
<br />
::Rather than just deleting them, I've been trying to review the disch notes and compare them to the existing article, integrating anything that it was adding before removing it. It's more time consuming than just deleting them, but the whole point of zeromus pasting them here was that they might improve the articles. Sometimes they add nothing, for sure, but it's worth reviewing before deleting, I think. In the process you might find other things here and there to improve in the mapper articles too. This review process is healthy for the wiki content. We don't need to be in a hurry to scour the disch notes from the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 20:38, 20 April 2015 (MDT)<br />
<br />
:: They have been here for more than three years, so how much time should have been waited for their removal in your opinion? 10 years? As I said they are still available, so you can just download them, and do the review work using your local copy of Dish notes. No point to have them pasted here, period. I absolutely agree that such a review work is benefical, and if there is a particular part you'd want me to review, just ask.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 03:13, 21 April 2015 (MDT)<br />
<br />
::: If you'd bothered to pay attention to what Rainwarrior's been doing, he's been carefully looking over each page and incorporating Disch's documentation as he goes, not just blindly removing everything.—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 04:53, 21 April 2015 (MDT)<br />
<br />
::: I did not just remove it but link to the original place. That's a different thing. Please explain me why Rainwarrior cannot download dish's document on his hard drive and work with that copy. (answer : he can, and that makes a lot more sense). Anyways I'm sick of editing this wiki for a while. [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:04, 21 April 2015 (MDT)<br />
<br />
:::: There are several reasons why I would not do it that way:<br />
:::: - If I download the document and begin integrating it into the Wiki, it can no longer be a collaborative process. If I do that, I have to do every single one myself (nobody can help, sensibly, without being redundant), and there is really no good way to know which have been done already.<br />
:::: - Several of the Disch notes sections have had edits in the time since being pasted here, and all of these deserve an overview before being removed.<br />
:::: - I believe zeromus' addition of the Disch notes to the Wiki was overall a good thing, filling in content where it was missing at the temporary expense of redundancy.<br />
:::: - Simply reverting someone's changes without reviewing them treats them in bad faith.<br />
:::: "if there is a particular part you'd want me to review, just ask." Please review every deletion you make. That's what I am asking, and that was the project I had begun, myself. If you don't want to do this, please just leave it there. I will get to it eventually! I had started working on this carefully (but slowly). It will probably take me a few months if I do it alone, but I really don't appreciate someone coming in with sweeping deletions and making it difficult for me to try and attempt to finally make good on zeromus' good-faith effort to have the wiki improved by Disch's notes. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 10:48, 21 April 2015 (MDT)<br />
<br />
Oh because those HAVE HAD EDITS ?! :O<br />
<br />
Now everything makes even less sense. I give up! This wiki is a huge mess anyway and will always be. Collaborative work just doesn't work. My only regrets is to have worked so hard for the hardware page and the FDS page, when they are doomed to be in the little of this huge disorganized mess with no head and no tail. Any change I make is systematically criticized, even if I asked in the forums if it was ok to do it, and nobody reacts which I belive is "I'm ok with that", but after the change everytime screams like "Begalad you're doing it all wrong, revert those changes!" It's the fourth time there is an issue like that where changes I made in a lame attempt to make this wiki a slightly better place are refuted only AFTER I made them.<br />
<br />
By the way a great thing would be to report those edits to RHDN, so that at least a clean and up to date version of Dish' doccument lies somewhere (and that is on RHDN, not here).[[Special:Contributions/185.26.182.29|185.26.182.29]] 12:47, 21 April 2015 (MDT)<br />
:If consensus for large scale editing has been established in a topic on the forum, it would be a good idea to include the URL of this topic in the edit summary of each edit so that we know what you're doing. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 12:56, 21 April 2015 (MDT)<br />
<br />
:I can't complain about your changes before you make them, unless you tell us what your intentions are first. If you want to make large scale changes unannounced, yes, people will complain after the fact. When else would they complain? I think we want the same thing in the end (no more redundant Disch notes), but I am unhappy with the way you are doing it. I began several days ago a long term effort to do it carefully to make sure we aren't losing information as the Disch notes are removed, but suddenly you have come in to just bulldoze it to the ground, and this does bother me. This isn't collaboration, this is in effect just you having an edit war with zeromus with a 2 year delay. I don't know what argument you had about the FDS article, or what, but it's not at all relevant to the current discussion. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:13, 21 April 2015 (MDT)<br />
<br />
:Yeah, it really suck because we're making efforts and we get in the way of eachother. That's just how this wiki works and is doomed to work. As for the thread it's [http://forums.nesdev.org/viewtopic.php?f=14&t=12621 here], but it was in an abandoned state after one day. If I say "should we do that" and nobody react I assume nobody cares if I to do it. Well wrong assumption I guess. I was absolutely sure the Dish docs were untouched that is why I acted this way. However the edits from the are not lost because they're in the history logs. I'll track for them, and update new Dish docs to RHDN to apologize for this behaviour (so I don't have to deal with the wiki anymore but still repair what I have broken). I hope this is okay for everyone. It will take a few days, though.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:28, 21 April 2015 (MDT)<br />
<br />
::I reacted, and I started working on the problem. I didn't want to just revert your deletions because it would basically be an edit war if we don't talk about it first. Undoing a single revision I can explain in the comment summary, but doing many is kind of hostile. I know you spent a good amount of time (in good faith) making the edits, though zeromus also spent a good amount of time putting that stuff up in the first place. Both of you wanted to improve the wiki, and I'm trying to mediate this by keeping anything of value that was there. You don't need to revert anything yourself, at this point; I have been reviewing the changes, and keeping a list of deletions at [[User:Rainwarrior]], and I'll eventually get through them one by one as part of the ongoing project I started. I want to keep all the document links you added, for eaxmple, because those are good. As for updating RHDN, you can do that if you like, but I'm only concerned about the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:42, 21 April 2015 (MDT)<br />
<br />
== MMC5-internal RAM ==<br />
What is the logic in the ASIC that causes it to write zero if the PPU is not rendering? --[[User:Zzo38|Zzo38]] 01:51, 22 September 2012 (MDT)<br />
<br />
Another question about the ExRAM is, what happens when you try to read/write ExRAM nametables through the PPU registers, and if extended attribute mode is selected, what happens when reading/writing attribute tables using the PPU registers (when it isn't rendering the picture, and in any potentially random order)? --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 22:23, 24 February 2014 (MST)<br />
<br />
Yet another question : Is the ExRAM battery backed ? It would seem no, but technically the Battery is connected to the MMC5 so who knowns ? [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 04:38, 5 May 2014 (MDT)<br />
<br />
== Even more extended PRG RAM ==<br />
Parsimony of silicon strongly implies that the higher address lines (corresponding to the 0x78 bits of the register) are still driven for the registers from $5114 to $5116 even when RAM is selected, meaning >64KiB PRG-RAM would be usable when mapped to $8000-$DFFF.<br />
It's conceivable that these same bits of the register at $5113 (controlling PRG-RAM bank) are implemented, since they have to feed a multiplexer anyway.<br />
Something to test, maybe. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 23:34, 20 January 2014 (MST)<br />
<br />
== PRG Bankswitching ==<br />
The PRG bankswitching section was much better before the recent edits by Ben Bolt. In particular, I do not see why non-existing registers $5112 etc... are even mentioned at all. The current page is a huge mess and I don't see any new info that wasn't there before, except that it's now much less readable and non understandable.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 00:40, 26 November 2018 (MST)<br />
<br />
Also, this is not related to recent edits, but the info in this wiki clearly contradict Dish notes.<br />
<br />
Wiki says:<br />
<br />
''Mode 1 - Select a 16KB PRG ROM bank at $C000-$FFFF (pass through CPU A13 to PRG A13 instead of using bit 0)''<br />
''Mode 0 - Select a 32KB PRG ROM bank at $8000-$FFFF (pass through CPU A13 and A14 to PRG A13 and A14 instead of using bits 0 and 1)''<br />
<br />
Before the recent edits it said:<br />
<br />
''Mode 0 - Select a 32KB PRG ROM bank at $8000-$FFFF (ignore bottom 2 bits)''<br />
''Mode 1 - Select a 16KB PRG ROM bank at $C000-$FFFF (ignore bottom bit)''<br />
<br />
which is equivalent, but simpler to understand in a sowftware viewpoint.<br />
<br />
Dish however says:<br />
<br />
''Note that unlike most other mappers, these CHR pages are in *actual* sizes. IE: when in 4k mode, registers contain 4k page numbers. But when in 2k mode, register contain 2k page numbers.''<br />
<br />
Which is the oposite ! This was already contradictory before the recent edits but I didn't notice. So who's right, who's wrong ? At least Castlevania III uses 16k banks with MMC5 so this should be easy to figure out.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 08:50, 26 November 2018 (MST)<br />
<br />
: You'll note that the former comment is about PRG bankswitching, and Disch's comment is about CHR bankswitching. Both are true. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 13:29, 26 November 2018 (MST)<br />
<br />
:: Ah Okaaay... so the MMC5 did the shifting trick for it's CHR pages but not PRG pages where bigger sizes are used like usual by ignoring lower bits... that's very tricky indeed. This should probably be mentionned after the PRG bankswitching part is fixed up.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:56, 26 November 2018 (MST)<br />
<br />
OK I hope everything is fixed now, tried to present the information in a way that is simultaneously as concise and complete as possible.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 15:10, 21 December 2018 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=MMC5&diff=6738MMC52018-12-21T21:38:09Z<p>Bregalad: /* PRG Bankswitching */ Removes duplicate information, numbers are in hex ($ sign) and stop talking about nonexisting registers $5110-$5112</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 />
|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]]<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 />
* A scanline based IRQ counter<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 />
=== 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 />
|-<br />
!Bank<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 />
||3||$5113|||$6000-$7FFF (RAM)||$6000-$7FFF (RAM)||$6000-$7FFF (RAM)||$6000-$7FFF (RAM)<br />
|-<br />
||4||$5114|||$8000-$9FFF||style="background: #cccccc;"|v (none) v||style="background: #cccccc;"|v (none) v||style="background: #cccccc;"|v (none) v<br />
|-<br />
||5||$5115|||$A000-$BFFF||$8000-$BFFF||$8000-$BFFF||style="background: #cccccc;"|v (none) v<br />
|-<br />
||6||$5116|||$C000-$DFFF||$C000$-DFFF||style="background: #cccccc;"|v (none) v||style="background: #cccccc;"|v (none) v<br />
|-<br />
||7||$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 whathever PRG range is covered by register $5117, and the bit $5117.7 is ignored. This makes it technically impossible to map RAM at interrupt vectors in all modes.<br />
<br />
Modes 0-2 : The bankswitching registers always hold a value of 8kb bank index numbers. Just like with all other mappers supporting multiple banks sizes, 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 quircks ====<br />
<br />
Until novermber 2018, it was thought that the MMC5 supported up to 2 PRG RAM chips, each up to 32KB in length. However, recent researchs shows that bits 2-3 control state of two unknown pins which acts like A15-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 quicks 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 PRG-RAM banking.<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 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.<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]<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 />
It is not currently known how the MMC5 detects the sprite size being used by the PPU.<br />
<br />
==== CHR selects 0…11====<br />
{| class="wikitable"<br />
! !! colspan=4|PPU memory affected for each mode (see [[#CHR mode ($5101)]])<br />
|-<br />
! Write to CPU address !! 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 />
Note: Registers $512C - $512F ''do not exist''.<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'' is the only known game to use split screen mode (during the intro, where it shows ship stats). It is [https://forums.nesdev.org/viewtopic.php?f=2&t=12764| suspected but not confirmed] that ''Bandit Kings of Ancient China'' also uses split screen mode during the ending sequence.<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, however when you scroll to 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 may only use vertical scroll values whose bottom 3 bits match the [[PPU|Nes PPU]]'s fine vertical scroll value. 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 Counter ($5203) ====<br />
All eight bits specify the scanline number to generate IRQ at<br />
<br />
==== IRQ Status ($5204, read/write) ====<br />
===== Write =====<br />
7 bit 0<br />
---- ----<br />
Exxx xxxx<br />
|<br />
+--------- IRQ Enable flag (1=IRQs enabled)<br />
<br />
===== Read =====<br />
7 bit 0<br />
---- ----<br />
SVxx xxxx MMC5A default power-on value = $00<br />
||<br />
|+-------- "In Frame" signal<br />
+--------- IRQ Pending flag<br />
<br />
When set, the "In Frame" signal specifies that the PPU is currently rendering a scanline. It also plays a role in how IRQs are generated.<br />
<br />
The IRQ Pending flag may be raised even if IRQs are disabled.<br />
<br />
Any time this register is read, the 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 ==<br />
[[File:mmc5_in_frame_status_bit.png|thumb|right|MMC5 'in frame' status bit state diagram]]<br />
Scanline detection involves monitoring the addresses read by the PPU. In the state diagram to the right, PPU /RD going low indicates a read by the PPU. M2 rising indicates a clock cycle of the CPU. A PPU address is considered "in range" if the address is in the range $2000 - $2FFF.<br />
<br />
When the MMC5 has detected that a scanline is rendering, the 'in frame' status bit gets set in register $5204 and the internal 8-bit scanline counter is incremented. Software can use this status bit as an indication of whether or not the PPU is currently rendering.<br />
<br />
It appears that all 240 rendered scanlines as well as the pre-render scanline are all detected by the MMC5. It also appears that scanlines are detected near their end (or near the start of the next scanline). See also [http://forums.nesdev.org/viewtopic.php?t=7653].<br />
<br />
The 'in frame' status bit is cleared as soon as the MMC5 no longer detects PPU rendering. This happens at the end of the last rendered scanline, and whenever the PPU is switched off (Sprite and BG rendering disabled).<br />
<br />
Note that there are side-effects to switching off the PPU mid frame. Clearing the In Frame signal effectively resets the IRQ counter as can be seen in the logic given above. Therefore, if the PPU is switched back on in the frame, the IRQ counter will begin counting from $00 again.<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 />
== Scanline-Counting IRQ Operation ==<br />
<br />
The MMC5 has an internal 8-bit incrementing scanline counter that watches the PPU as it renders, and counts each passing scanline. When the counter reaches the scanline specified by register $5203, it generates an IRQ. For example, when register $5203 is set to $04, the IRQ will occur near the start of the 5th rendered scanline.<br />
<br />
When the MMC5 detects a scanline, the following events occur:<br />
* If the 'in frame' status bit is clear, set it, reset the IRQ counter to 0, and clear the IRQ Pending flag<br />
* Otherwise, increment the IRQ counter. If it now equals the IRQ scanline specified by register $5203, raise IRQ Pending flag and generate an IRQ if enabled<br />
<br />
Note the above logic makes it impossible for an IRQ to occur when $5203 is set to $00<br />
<br />
The IRQ Pending flag is raised when the desired scanline is reached ''regardless'' of whether or not IRQs are enabled. $5204.7 can still be read as set even when IRQ Enable flag is clear. However, an actual IRQ is only sent to the CPU if both the IRQ Enable flag and IRQ Pending flag are raised.<br />
<br />
== Hardware ==<br />
<br />
The MMC5 exists in a 100-pin TQFP 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 />
== See also ==<br />
* NES Mapper list by Disch [http://www.romhacking.net/documents/362/]<br />
* Nintendo MMC5 by goroh, translated by Sgt. Bowhack [http://nesdev.org/mmc5-e.txt]<br />
* Nintendo MMC5 Bankswitching by Kevin Horton [http://nesdev.org/mmc5_bank_switch.txt]</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:MMC5&diff=14388Talk:MMC52018-11-26T20:56:57Z<p>Bregalad: /* PRG Bankswitching */</p>
<hr />
<div>== [[wikipedia:Don't repeat yourself|Don't Repeat Yourself]] failure ==<br />
Ok, it's crazy to have two completely different pages explaining the MMC5 mapper, one on iNES mapper 5 and the other on MMC5. I think the info should be present on a single page (like it is for all other mappers).<br />
<br />
Well in fact it seems it's Zeromus who added Dish's notes on all iNES mapper pages. This would be nice if the info wasn't already present on the wiki - having twice the same info isn't very logical is it ? I don't know what to do but something should probably be changed...Bregalad 00:36, 23 March 2012 (PDT)<br />
<br />
:Disch' format is '''much''' better for reading. Funny, I was really thinking to discuss about such thing. :) --[[User:Zepper|Zepper]] 14:44, 23 March 2012 (PDT)<br />
<br />
:Problem solved. @Zepper : If there is a particular point that should be improved about how the mappers are presented on the wiki, then please change it (or at least say more precisely what is ''much'' better).[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:02, 20 April 2015 (MDT)<br />
<br />
::Rather than just deleting them, I've been trying to review the disch notes and compare them to the existing article, integrating anything that it was adding before removing it. It's more time consuming than just deleting them, but the whole point of zeromus pasting them here was that they might improve the articles. Sometimes they add nothing, for sure, but it's worth reviewing before deleting, I think. In the process you might find other things here and there to improve in the mapper articles too. This review process is healthy for the wiki content. We don't need to be in a hurry to scour the disch notes from the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 20:38, 20 April 2015 (MDT)<br />
<br />
:: They have been here for more than three years, so how much time should have been waited for their removal in your opinion? 10 years? As I said they are still available, so you can just download them, and do the review work using your local copy of Dish notes. No point to have them pasted here, period. I absolutely agree that such a review work is benefical, and if there is a particular part you'd want me to review, just ask.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 03:13, 21 April 2015 (MDT)<br />
<br />
::: If you'd bothered to pay attention to what Rainwarrior's been doing, he's been carefully looking over each page and incorporating Disch's documentation as he goes, not just blindly removing everything.—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 04:53, 21 April 2015 (MDT)<br />
<br />
::: I did not just remove it but link to the original place. That's a different thing. Please explain me why Rainwarrior cannot download dish's document on his hard drive and work with that copy. (answer : he can, and that makes a lot more sense). Anyways I'm sick of editing this wiki for a while. [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:04, 21 April 2015 (MDT)<br />
<br />
:::: There are several reasons why I would not do it that way:<br />
:::: - If I download the document and begin integrating it into the Wiki, it can no longer be a collaborative process. If I do that, I have to do every single one myself (nobody can help, sensibly, without being redundant), and there is really no good way to know which have been done already.<br />
:::: - Several of the Disch notes sections have had edits in the time since being pasted here, and all of these deserve an overview before being removed.<br />
:::: - I believe zeromus' addition of the Disch notes to the Wiki was overall a good thing, filling in content where it was missing at the temporary expense of redundancy.<br />
:::: - Simply reverting someone's changes without reviewing them treats them in bad faith.<br />
:::: "if there is a particular part you'd want me to review, just ask." Please review every deletion you make. That's what I am asking, and that was the project I had begun, myself. If you don't want to do this, please just leave it there. I will get to it eventually! I had started working on this carefully (but slowly). It will probably take me a few months if I do it alone, but I really don't appreciate someone coming in with sweeping deletions and making it difficult for me to try and attempt to finally make good on zeromus' good-faith effort to have the wiki improved by Disch's notes. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 10:48, 21 April 2015 (MDT)<br />
<br />
Oh because those HAVE HAD EDITS ?! :O<br />
<br />
Now everything makes even less sense. I give up! This wiki is a huge mess anyway and will always be. Collaborative work just doesn't work. My only regrets is to have worked so hard for the hardware page and the FDS page, when they are doomed to be in the little of this huge disorganized mess with no head and no tail. Any change I make is systematically criticized, even if I asked in the forums if it was ok to do it, and nobody reacts which I belive is "I'm ok with that", but after the change everytime screams like "Begalad you're doing it all wrong, revert those changes!" It's the fourth time there is an issue like that where changes I made in a lame attempt to make this wiki a slightly better place are refuted only AFTER I made them.<br />
<br />
By the way a great thing would be to report those edits to RHDN, so that at least a clean and up to date version of Dish' doccument lies somewhere (and that is on RHDN, not here).[[Special:Contributions/185.26.182.29|185.26.182.29]] 12:47, 21 April 2015 (MDT)<br />
:If consensus for large scale editing has been established in a topic on the forum, it would be a good idea to include the URL of this topic in the edit summary of each edit so that we know what you're doing. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 12:56, 21 April 2015 (MDT)<br />
<br />
:I can't complain about your changes before you make them, unless you tell us what your intentions are first. If you want to make large scale changes unannounced, yes, people will complain after the fact. When else would they complain? I think we want the same thing in the end (no more redundant Disch notes), but I am unhappy with the way you are doing it. I began several days ago a long term effort to do it carefully to make sure we aren't losing information as the Disch notes are removed, but suddenly you have come in to just bulldoze it to the ground, and this does bother me. This isn't collaboration, this is in effect just you having an edit war with zeromus with a 2 year delay. I don't know what argument you had about the FDS article, or what, but it's not at all relevant to the current discussion. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:13, 21 April 2015 (MDT)<br />
<br />
:Yeah, it really suck because we're making efforts and we get in the way of eachother. That's just how this wiki works and is doomed to work. As for the thread it's [http://forums.nesdev.org/viewtopic.php?f=14&t=12621 here], but it was in an abandoned state after one day. If I say "should we do that" and nobody react I assume nobody cares if I to do it. Well wrong assumption I guess. I was absolutely sure the Dish docs were untouched that is why I acted this way. However the edits from the are not lost because they're in the history logs. I'll track for them, and update new Dish docs to RHDN to apologize for this behaviour (so I don't have to deal with the wiki anymore but still repair what I have broken). I hope this is okay for everyone. It will take a few days, though.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:28, 21 April 2015 (MDT)<br />
<br />
::I reacted, and I started working on the problem. I didn't want to just revert your deletions because it would basically be an edit war if we don't talk about it first. Undoing a single revision I can explain in the comment summary, but doing many is kind of hostile. I know you spent a good amount of time (in good faith) making the edits, though zeromus also spent a good amount of time putting that stuff up in the first place. Both of you wanted to improve the wiki, and I'm trying to mediate this by keeping anything of value that was there. You don't need to revert anything yourself, at this point; I have been reviewing the changes, and keeping a list of deletions at [[User:Rainwarrior]], and I'll eventually get through them one by one as part of the ongoing project I started. I want to keep all the document links you added, for eaxmple, because those are good. As for updating RHDN, you can do that if you like, but I'm only concerned about the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:42, 21 April 2015 (MDT)<br />
<br />
== MMC5-internal RAM ==<br />
What is the logic in the ASIC that causes it to write zero if the PPU is not rendering? --[[User:Zzo38|Zzo38]] 01:51, 22 September 2012 (MDT)<br />
<br />
Another question about the ExRAM is, what happens when you try to read/write ExRAM nametables through the PPU registers, and if extended attribute mode is selected, what happens when reading/writing attribute tables using the PPU registers (when it isn't rendering the picture, and in any potentially random order)? --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 22:23, 24 February 2014 (MST)<br />
<br />
Yet another question : Is the ExRAM battery backed ? It would seem no, but technically the Battery is connected to the MMC5 so who knowns ? [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 04:38, 5 May 2014 (MDT)<br />
<br />
== Even more extended PRG RAM ==<br />
Parsimony of silicon strongly implies that the higher address lines (corresponding to the 0x78 bits of the register) are still driven for the registers from $5114 to $5116 even when RAM is selected, meaning >64KiB PRG-RAM would be usable when mapped to $8000-$DFFF.<br />
It's conceivable that these same bits of the register at $5113 (controlling PRG-RAM bank) are implemented, since they have to feed a multiplexer anyway.<br />
Something to test, maybe. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 23:34, 20 January 2014 (MST)<br />
<br />
== PRG Bankswitching ==<br />
The PRG bankswitching section was much better before the recent edits by Ben Bolt. In particular, I do not see why non-existing registers $5112 etc... are even mentioned at all. The current page is a huge mess and I don't see any new info that wasn't there before, except that it's now much less readable and non understandable.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 00:40, 26 November 2018 (MST)<br />
<br />
Also, this is not related to recent edits, but the info in this wiki clearly contradict Dish notes.<br />
<br />
Wiki says:<br />
<br />
''Mode 1 - Select a 16KB PRG ROM bank at $C000-$FFFF (pass through CPU A13 to PRG A13 instead of using bit 0)''<br />
''Mode 0 - Select a 32KB PRG ROM bank at $8000-$FFFF (pass through CPU A13 and A14 to PRG A13 and A14 instead of using bits 0 and 1)''<br />
<br />
Before the recent edits it said:<br />
<br />
''Mode 0 - Select a 32KB PRG ROM bank at $8000-$FFFF (ignore bottom 2 bits)''<br />
''Mode 1 - Select a 16KB PRG ROM bank at $C000-$FFFF (ignore bottom bit)''<br />
<br />
which is equivalent, but simpler to understand in a sowftware viewpoint.<br />
<br />
Dish however says:<br />
<br />
''Note that unlike most other mappers, these CHR pages are in *actual* sizes. IE: when in 4k mode, registers contain 4k page numbers. But when in 2k mode, register contain 2k page numbers.''<br />
<br />
Which is the oposite ! This was already contradictory before the recent edits but I didn't notice. So who's right, who's wrong ? At least Castlevania III uses 16k banks with MMC5 so this should be easy to figure out.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 08:50, 26 November 2018 (MST)<br />
<br />
: You'll note that the former comment is about PRG bankswitching, and Disch's comment is about CHR bankswitching. Both are true. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 13:29, 26 November 2018 (MST)<br />
<br />
:: Ah Okaaay... so the MMC5 did the shifting trick for it's CHR pages but not PRG pages where bigger sizes are used like usual by ignoring lower bits... that's very tricky indeed. This should probably be mentionned after the PRG bankswitching part is fixed up.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:56, 26 November 2018 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:MMC5&diff=14386Talk:MMC52018-11-26T18:35:27Z<p>Bregalad: /* PRG Bankswitching */</p>
<hr />
<div>== [[wikipedia:Don't repeat yourself|Don't Repeat Yourself]] failure ==<br />
Ok, it's crazy to have two completely different pages explaining the MMC5 mapper, one on iNES mapper 5 and the other on MMC5. I think the info should be present on a single page (like it is for all other mappers).<br />
<br />
Well in fact it seems it's Zeromus who added Dish's notes on all iNES mapper pages. This would be nice if the info wasn't already present on the wiki - having twice the same info isn't very logical is it ? I don't know what to do but something should probably be changed...Bregalad 00:36, 23 March 2012 (PDT)<br />
<br />
:Disch' format is '''much''' better for reading. Funny, I was really thinking to discuss about such thing. :) --[[User:Zepper|Zepper]] 14:44, 23 March 2012 (PDT)<br />
<br />
:Problem solved. @Zepper : If there is a particular point that should be improved about how the mappers are presented on the wiki, then please change it (or at least say more precisely what is ''much'' better).[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:02, 20 April 2015 (MDT)<br />
<br />
::Rather than just deleting them, I've been trying to review the disch notes and compare them to the existing article, integrating anything that it was adding before removing it. It's more time consuming than just deleting them, but the whole point of zeromus pasting them here was that they might improve the articles. Sometimes they add nothing, for sure, but it's worth reviewing before deleting, I think. In the process you might find other things here and there to improve in the mapper articles too. This review process is healthy for the wiki content. We don't need to be in a hurry to scour the disch notes from the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 20:38, 20 April 2015 (MDT)<br />
<br />
:: They have been here for more than three years, so how much time should have been waited for their removal in your opinion? 10 years? As I said they are still available, so you can just download them, and do the review work using your local copy of Dish notes. No point to have them pasted here, period. I absolutely agree that such a review work is benefical, and if there is a particular part you'd want me to review, just ask.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 03:13, 21 April 2015 (MDT)<br />
<br />
::: If you'd bothered to pay attention to what Rainwarrior's been doing, he's been carefully looking over each page and incorporating Disch's documentation as he goes, not just blindly removing everything.—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 04:53, 21 April 2015 (MDT)<br />
<br />
::: I did not just remove it but link to the original place. That's a different thing. Please explain me why Rainwarrior cannot download dish's document on his hard drive and work with that copy. (answer : he can, and that makes a lot more sense). Anyways I'm sick of editing this wiki for a while. [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:04, 21 April 2015 (MDT)<br />
<br />
:::: There are several reasons why I would not do it that way:<br />
:::: - If I download the document and begin integrating it into the Wiki, it can no longer be a collaborative process. If I do that, I have to do every single one myself (nobody can help, sensibly, without being redundant), and there is really no good way to know which have been done already.<br />
:::: - Several of the Disch notes sections have had edits in the time since being pasted here, and all of these deserve an overview before being removed.<br />
:::: - I believe zeromus' addition of the Disch notes to the Wiki was overall a good thing, filling in content where it was missing at the temporary expense of redundancy.<br />
:::: - Simply reverting someone's changes without reviewing them treats them in bad faith.<br />
:::: "if there is a particular part you'd want me to review, just ask." Please review every deletion you make. That's what I am asking, and that was the project I had begun, myself. If you don't want to do this, please just leave it there. I will get to it eventually! I had started working on this carefully (but slowly). It will probably take me a few months if I do it alone, but I really don't appreciate someone coming in with sweeping deletions and making it difficult for me to try and attempt to finally make good on zeromus' good-faith effort to have the wiki improved by Disch's notes. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 10:48, 21 April 2015 (MDT)<br />
<br />
Oh because those HAVE HAD EDITS ?! :O<br />
<br />
Now everything makes even less sense. I give up! This wiki is a huge mess anyway and will always be. Collaborative work just doesn't work. My only regrets is to have worked so hard for the hardware page and the FDS page, when they are doomed to be in the little of this huge disorganized mess with no head and no tail. Any change I make is systematically criticized, even if I asked in the forums if it was ok to do it, and nobody reacts which I belive is "I'm ok with that", but after the change everytime screams like "Begalad you're doing it all wrong, revert those changes!" It's the fourth time there is an issue like that where changes I made in a lame attempt to make this wiki a slightly better place are refuted only AFTER I made them.<br />
<br />
By the way a great thing would be to report those edits to RHDN, so that at least a clean and up to date version of Dish' doccument lies somewhere (and that is on RHDN, not here).[[Special:Contributions/185.26.182.29|185.26.182.29]] 12:47, 21 April 2015 (MDT)<br />
:If consensus for large scale editing has been established in a topic on the forum, it would be a good idea to include the URL of this topic in the edit summary of each edit so that we know what you're doing. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 12:56, 21 April 2015 (MDT)<br />
<br />
:I can't complain about your changes before you make them, unless you tell us what your intentions are first. If you want to make large scale changes unannounced, yes, people will complain after the fact. When else would they complain? I think we want the same thing in the end (no more redundant Disch notes), but I am unhappy with the way you are doing it. I began several days ago a long term effort to do it carefully to make sure we aren't losing information as the Disch notes are removed, but suddenly you have come in to just bulldoze it to the ground, and this does bother me. This isn't collaboration, this is in effect just you having an edit war with zeromus with a 2 year delay. I don't know what argument you had about the FDS article, or what, but it's not at all relevant to the current discussion. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:13, 21 April 2015 (MDT)<br />
<br />
:Yeah, it really suck because we're making efforts and we get in the way of eachother. That's just how this wiki works and is doomed to work. As for the thread it's [http://forums.nesdev.org/viewtopic.php?f=14&t=12621 here], but it was in an abandoned state after one day. If I say "should we do that" and nobody react I assume nobody cares if I to do it. Well wrong assumption I guess. I was absolutely sure the Dish docs were untouched that is why I acted this way. However the edits from the are not lost because they're in the history logs. I'll track for them, and update new Dish docs to RHDN to apologize for this behaviour (so I don't have to deal with the wiki anymore but still repair what I have broken). I hope this is okay for everyone. It will take a few days, though.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:28, 21 April 2015 (MDT)<br />
<br />
::I reacted, and I started working on the problem. I didn't want to just revert your deletions because it would basically be an edit war if we don't talk about it first. Undoing a single revision I can explain in the comment summary, but doing many is kind of hostile. I know you spent a good amount of time (in good faith) making the edits, though zeromus also spent a good amount of time putting that stuff up in the first place. Both of you wanted to improve the wiki, and I'm trying to mediate this by keeping anything of value that was there. You don't need to revert anything yourself, at this point; I have been reviewing the changes, and keeping a list of deletions at [[User:Rainwarrior]], and I'll eventually get through them one by one as part of the ongoing project I started. I want to keep all the document links you added, for eaxmple, because those are good. As for updating RHDN, you can do that if you like, but I'm only concerned about the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:42, 21 April 2015 (MDT)<br />
<br />
== MMC5-internal RAM ==<br />
What is the logic in the ASIC that causes it to write zero if the PPU is not rendering? --[[User:Zzo38|Zzo38]] 01:51, 22 September 2012 (MDT)<br />
<br />
Another question about the ExRAM is, what happens when you try to read/write ExRAM nametables through the PPU registers, and if extended attribute mode is selected, what happens when reading/writing attribute tables using the PPU registers (when it isn't rendering the picture, and in any potentially random order)? --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 22:23, 24 February 2014 (MST)<br />
<br />
Yet another question : Is the ExRAM battery backed ? It would seem no, but technically the Battery is connected to the MMC5 so who knowns ? [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 04:38, 5 May 2014 (MDT)<br />
<br />
== Even more extended PRG RAM ==<br />
Parsimony of silicon strongly implies that the higher address lines (corresponding to the 0x78 bits of the register) are still driven for the registers from $5114 to $5116 even when RAM is selected, meaning >64KiB PRG-RAM would be usable when mapped to $8000-$DFFF.<br />
It's conceivable that these same bits of the register at $5113 (controlling PRG-RAM bank) are implemented, since they have to feed a multiplexer anyway.<br />
Something to test, maybe. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 23:34, 20 January 2014 (MST)<br />
<br />
== PRG Bankswitching ==<br />
The PRG bankswitching section was much better before the recent edits by Ben Bolt. In particular, I do not see why non-existing registers $5112 etc... are even mentioned at all. The current page is a huge mess and I don't see any new info that wasn't there before, except that it's now much less readable and non understandable.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 00:40, 26 November 2018 (MST)<br />
<br />
Also, this is not related to recent edits, but the info in this wiki clearly contradict Dish notes.<br />
<br />
Wiki says:<br />
<br />
''Mode 1 - Select a 16KB PRG ROM bank at $C000-$FFFF (pass through CPU A13 to PRG A13 instead of using bit 0)''<br />
''Mode 0 - Select a 32KB PRG ROM bank at $8000-$FFFF (pass through CPU A13 and A14 to PRG A13 and A14 instead of using bits 0 and 1)''<br />
<br />
Before the recent edits it said:<br />
<br />
''Mode 0 - Select a 32KB PRG ROM bank at $8000-$FFFF (ignore bottom 2 bits)''<br />
''Mode 1 - Select a 16KB PRG ROM bank at $C000-$FFFF (ignore bottom bit)''<br />
<br />
which is equivalent, but simpler to understand in a sowftware viewpoint.<br />
<br />
Dish however says:<br />
<br />
''Note that unlike most other mappers, these CHR pages are in *actual* sizes. IE: when in 4k mode, registers contain 4k page numbers. But when in 2k mode, register contain 2k page numbers.''<br />
<br />
Which is the oposite ! This was already contradictory before the recent edits but I didn't notice. So who's right, who's wrong ? At least Castlevania III uses 16k banks with MMC5 so this should be easy to figure out.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 08:50, 26 November 2018 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:MMC5&diff=14385Talk:MMC52018-11-26T18:35:00Z<p>Bregalad: /* PRG Bankswitching */</p>
<hr />
<div>== [[wikipedia:Don't repeat yourself|Don't Repeat Yourself]] failure ==<br />
Ok, it's crazy to have two completely different pages explaining the MMC5 mapper, one on iNES mapper 5 and the other on MMC5. I think the info should be present on a single page (like it is for all other mappers).<br />
<br />
Well in fact it seems it's Zeromus who added Dish's notes on all iNES mapper pages. This would be nice if the info wasn't already present on the wiki - having twice the same info isn't very logical is it ? I don't know what to do but something should probably be changed...Bregalad 00:36, 23 March 2012 (PDT)<br />
<br />
:Disch' format is '''much''' better for reading. Funny, I was really thinking to discuss about such thing. :) --[[User:Zepper|Zepper]] 14:44, 23 March 2012 (PDT)<br />
<br />
:Problem solved. @Zepper : If there is a particular point that should be improved about how the mappers are presented on the wiki, then please change it (or at least say more precisely what is ''much'' better).[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:02, 20 April 2015 (MDT)<br />
<br />
::Rather than just deleting them, I've been trying to review the disch notes and compare them to the existing article, integrating anything that it was adding before removing it. It's more time consuming than just deleting them, but the whole point of zeromus pasting them here was that they might improve the articles. Sometimes they add nothing, for sure, but it's worth reviewing before deleting, I think. In the process you might find other things here and there to improve in the mapper articles too. This review process is healthy for the wiki content. We don't need to be in a hurry to scour the disch notes from the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 20:38, 20 April 2015 (MDT)<br />
<br />
:: They have been here for more than three years, so how much time should have been waited for their removal in your opinion? 10 years? As I said they are still available, so you can just download them, and do the review work using your local copy of Dish notes. No point to have them pasted here, period. I absolutely agree that such a review work is benefical, and if there is a particular part you'd want me to review, just ask.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 03:13, 21 April 2015 (MDT)<br />
<br />
::: If you'd bothered to pay attention to what Rainwarrior's been doing, he's been carefully looking over each page and incorporating Disch's documentation as he goes, not just blindly removing everything.—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 04:53, 21 April 2015 (MDT)<br />
<br />
::: I did not just remove it but link to the original place. That's a different thing. Please explain me why Rainwarrior cannot download dish's document on his hard drive and work with that copy. (answer : he can, and that makes a lot more sense). Anyways I'm sick of editing this wiki for a while. [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:04, 21 April 2015 (MDT)<br />
<br />
:::: There are several reasons why I would not do it that way:<br />
:::: - If I download the document and begin integrating it into the Wiki, it can no longer be a collaborative process. If I do that, I have to do every single one myself (nobody can help, sensibly, without being redundant), and there is really no good way to know which have been done already.<br />
:::: - Several of the Disch notes sections have had edits in the time since being pasted here, and all of these deserve an overview before being removed.<br />
:::: - I believe zeromus' addition of the Disch notes to the Wiki was overall a good thing, filling in content where it was missing at the temporary expense of redundancy.<br />
:::: - Simply reverting someone's changes without reviewing them treats them in bad faith.<br />
:::: "if there is a particular part you'd want me to review, just ask." Please review every deletion you make. That's what I am asking, and that was the project I had begun, myself. If you don't want to do this, please just leave it there. I will get to it eventually! I had started working on this carefully (but slowly). It will probably take me a few months if I do it alone, but I really don't appreciate someone coming in with sweeping deletions and making it difficult for me to try and attempt to finally make good on zeromus' good-faith effort to have the wiki improved by Disch's notes. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 10:48, 21 April 2015 (MDT)<br />
<br />
Oh because those HAVE HAD EDITS ?! :O<br />
<br />
Now everything makes even less sense. I give up! This wiki is a huge mess anyway and will always be. Collaborative work just doesn't work. My only regrets is to have worked so hard for the hardware page and the FDS page, when they are doomed to be in the little of this huge disorganized mess with no head and no tail. Any change I make is systematically criticized, even if I asked in the forums if it was ok to do it, and nobody reacts which I belive is "I'm ok with that", but after the change everytime screams like "Begalad you're doing it all wrong, revert those changes!" It's the fourth time there is an issue like that where changes I made in a lame attempt to make this wiki a slightly better place are refuted only AFTER I made them.<br />
<br />
By the way a great thing would be to report those edits to RHDN, so that at least a clean and up to date version of Dish' doccument lies somewhere (and that is on RHDN, not here).[[Special:Contributions/185.26.182.29|185.26.182.29]] 12:47, 21 April 2015 (MDT)<br />
:If consensus for large scale editing has been established in a topic on the forum, it would be a good idea to include the URL of this topic in the edit summary of each edit so that we know what you're doing. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 12:56, 21 April 2015 (MDT)<br />
<br />
:I can't complain about your changes before you make them, unless you tell us what your intentions are first. If you want to make large scale changes unannounced, yes, people will complain after the fact. When else would they complain? I think we want the same thing in the end (no more redundant Disch notes), but I am unhappy with the way you are doing it. I began several days ago a long term effort to do it carefully to make sure we aren't losing information as the Disch notes are removed, but suddenly you have come in to just bulldoze it to the ground, and this does bother me. This isn't collaboration, this is in effect just you having an edit war with zeromus with a 2 year delay. I don't know what argument you had about the FDS article, or what, but it's not at all relevant to the current discussion. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:13, 21 April 2015 (MDT)<br />
<br />
:Yeah, it really suck because we're making efforts and we get in the way of eachother. That's just how this wiki works and is doomed to work. As for the thread it's [http://forums.nesdev.org/viewtopic.php?f=14&t=12621 here], but it was in an abandoned state after one day. If I say "should we do that" and nobody react I assume nobody cares if I to do it. Well wrong assumption I guess. I was absolutely sure the Dish docs were untouched that is why I acted this way. However the edits from the are not lost because they're in the history logs. I'll track for them, and update new Dish docs to RHDN to apologize for this behaviour (so I don't have to deal with the wiki anymore but still repair what I have broken). I hope this is okay for everyone. It will take a few days, though.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:28, 21 April 2015 (MDT)<br />
<br />
::I reacted, and I started working on the problem. I didn't want to just revert your deletions because it would basically be an edit war if we don't talk about it first. Undoing a single revision I can explain in the comment summary, but doing many is kind of hostile. I know you spent a good amount of time (in good faith) making the edits, though zeromus also spent a good amount of time putting that stuff up in the first place. Both of you wanted to improve the wiki, and I'm trying to mediate this by keeping anything of value that was there. You don't need to revert anything yourself, at this point; I have been reviewing the changes, and keeping a list of deletions at [[User:Rainwarrior]], and I'll eventually get through them one by one as part of the ongoing project I started. I want to keep all the document links you added, for eaxmple, because those are good. As for updating RHDN, you can do that if you like, but I'm only concerned about the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:42, 21 April 2015 (MDT)<br />
<br />
== MMC5-internal RAM ==<br />
What is the logic in the ASIC that causes it to write zero if the PPU is not rendering? --[[User:Zzo38|Zzo38]] 01:51, 22 September 2012 (MDT)<br />
<br />
Another question about the ExRAM is, what happens when you try to read/write ExRAM nametables through the PPU registers, and if extended attribute mode is selected, what happens when reading/writing attribute tables using the PPU registers (when it isn't rendering the picture, and in any potentially random order)? --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 22:23, 24 February 2014 (MST)<br />
<br />
Yet another question : Is the ExRAM battery backed ? It would seem no, but technically the Battery is connected to the MMC5 so who knowns ? [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 04:38, 5 May 2014 (MDT)<br />
<br />
== Even more extended PRG RAM ==<br />
Parsimony of silicon strongly implies that the higher address lines (corresponding to the 0x78 bits of the register) are still driven for the registers from $5114 to $5116 even when RAM is selected, meaning >64KiB PRG-RAM would be usable when mapped to $8000-$DFFF.<br />
It's conceivable that these same bits of the register at $5113 (controlling PRG-RAM bank) are implemented, since they have to feed a multiplexer anyway.<br />
Something to test, maybe. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 23:34, 20 January 2014 (MST)<br />
<br />
== PRG Bankswitching ==<br />
The PRG bankswitching section was much better before the recent edits by Ben Bolt. In particular, I do not see why non-existing registers $5112 etc... are even mentioned at all. The current page is a huge mess and I don't see any new info that wasn't there before, except that it's now much less readable and non understandable.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 00:40, 26 November 2018 (MST)<br />
<br />
Also, this is not related to recent edits, but the info in this wiki clearly contradict Dish notes.<br />
<br />
Wiki says:<br />
<br />
''Mode 1 - Select a 16KB PRG ROM bank at $C000-$FFFF (pass through CPU A13 to PRG A13 instead of using bit 0)<br />
Mode 0 - Select a 32KB PRG ROM bank at $8000-$FFFF (pass through CPU A13 and A14 to PRG A13 and A14 instead of using bits 0 and 1)''<br />
<br />
Before the recent edits it said:<br />
<br />
''Mode 0 - Select a 32KB PRG ROM bank at $8000-$FFFF (ignore bottom 2 bits)<br />
Mode 1 - Select a 16KB PRG ROM bank at $C000-$FFFF (ignore bottom bit)''<br />
<br />
which is equivalent, but simpler to understand in a sowftware viewpoint.<br />
<br />
Dish however says:<br />
<br />
''Note that unlike most other mappers, these CHR pages are in *actual* sizes. IE: when in 4k mode, registers<br />
contain 4k page numbers. But when in 2k mode, register contain 2k page numbers.<br />
''<br />
<br />
Which is the oposite ! This was already contradictory before the recent edits but I didn't notice. So who's right, who's wrong ? At least Castlevania III uses 16k banks with MMC5 so this should be easy to figure out.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 08:50, 26 November 2018 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:MMC5&diff=14384Talk:MMC52018-11-26T15:50:37Z<p>Bregalad: /* PRG Bankswitching */</p>
<hr />
<div>== [[wikipedia:Don't repeat yourself|Don't Repeat Yourself]] failure ==<br />
Ok, it's crazy to have two completely different pages explaining the MMC5 mapper, one on iNES mapper 5 and the other on MMC5. I think the info should be present on a single page (like it is for all other mappers).<br />
<br />
Well in fact it seems it's Zeromus who added Dish's notes on all iNES mapper pages. This would be nice if the info wasn't already present on the wiki - having twice the same info isn't very logical is it ? I don't know what to do but something should probably be changed...Bregalad 00:36, 23 March 2012 (PDT)<br />
<br />
:Disch' format is '''much''' better for reading. Funny, I was really thinking to discuss about such thing. :) --[[User:Zepper|Zepper]] 14:44, 23 March 2012 (PDT)<br />
<br />
:Problem solved. @Zepper : If there is a particular point that should be improved about how the mappers are presented on the wiki, then please change it (or at least say more precisely what is ''much'' better).[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:02, 20 April 2015 (MDT)<br />
<br />
::Rather than just deleting them, I've been trying to review the disch notes and compare them to the existing article, integrating anything that it was adding before removing it. It's more time consuming than just deleting them, but the whole point of zeromus pasting them here was that they might improve the articles. Sometimes they add nothing, for sure, but it's worth reviewing before deleting, I think. In the process you might find other things here and there to improve in the mapper articles too. This review process is healthy for the wiki content. We don't need to be in a hurry to scour the disch notes from the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 20:38, 20 April 2015 (MDT)<br />
<br />
:: They have been here for more than three years, so how much time should have been waited for their removal in your opinion? 10 years? As I said they are still available, so you can just download them, and do the review work using your local copy of Dish notes. No point to have them pasted here, period. I absolutely agree that such a review work is benefical, and if there is a particular part you'd want me to review, just ask.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 03:13, 21 April 2015 (MDT)<br />
<br />
::: If you'd bothered to pay attention to what Rainwarrior's been doing, he's been carefully looking over each page and incorporating Disch's documentation as he goes, not just blindly removing everything.—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 04:53, 21 April 2015 (MDT)<br />
<br />
::: I did not just remove it but link to the original place. That's a different thing. Please explain me why Rainwarrior cannot download dish's document on his hard drive and work with that copy. (answer : he can, and that makes a lot more sense). Anyways I'm sick of editing this wiki for a while. [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:04, 21 April 2015 (MDT)<br />
<br />
:::: There are several reasons why I would not do it that way:<br />
:::: - If I download the document and begin integrating it into the Wiki, it can no longer be a collaborative process. If I do that, I have to do every single one myself (nobody can help, sensibly, without being redundant), and there is really no good way to know which have been done already.<br />
:::: - Several of the Disch notes sections have had edits in the time since being pasted here, and all of these deserve an overview before being removed.<br />
:::: - I believe zeromus' addition of the Disch notes to the Wiki was overall a good thing, filling in content where it was missing at the temporary expense of redundancy.<br />
:::: - Simply reverting someone's changes without reviewing them treats them in bad faith.<br />
:::: "if there is a particular part you'd want me to review, just ask." Please review every deletion you make. That's what I am asking, and that was the project I had begun, myself. If you don't want to do this, please just leave it there. I will get to it eventually! I had started working on this carefully (but slowly). It will probably take me a few months if I do it alone, but I really don't appreciate someone coming in with sweeping deletions and making it difficult for me to try and attempt to finally make good on zeromus' good-faith effort to have the wiki improved by Disch's notes. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 10:48, 21 April 2015 (MDT)<br />
<br />
Oh because those HAVE HAD EDITS ?! :O<br />
<br />
Now everything makes even less sense. I give up! This wiki is a huge mess anyway and will always be. Collaborative work just doesn't work. My only regrets is to have worked so hard for the hardware page and the FDS page, when they are doomed to be in the little of this huge disorganized mess with no head and no tail. Any change I make is systematically criticized, even if I asked in the forums if it was ok to do it, and nobody reacts which I belive is "I'm ok with that", but after the change everytime screams like "Begalad you're doing it all wrong, revert those changes!" It's the fourth time there is an issue like that where changes I made in a lame attempt to make this wiki a slightly better place are refuted only AFTER I made them.<br />
<br />
By the way a great thing would be to report those edits to RHDN, so that at least a clean and up to date version of Dish' doccument lies somewhere (and that is on RHDN, not here).[[Special:Contributions/185.26.182.29|185.26.182.29]] 12:47, 21 April 2015 (MDT)<br />
:If consensus for large scale editing has been established in a topic on the forum, it would be a good idea to include the URL of this topic in the edit summary of each edit so that we know what you're doing. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 12:56, 21 April 2015 (MDT)<br />
<br />
:I can't complain about your changes before you make them, unless you tell us what your intentions are first. If you want to make large scale changes unannounced, yes, people will complain after the fact. When else would they complain? I think we want the same thing in the end (no more redundant Disch notes), but I am unhappy with the way you are doing it. I began several days ago a long term effort to do it carefully to make sure we aren't losing information as the Disch notes are removed, but suddenly you have come in to just bulldoze it to the ground, and this does bother me. This isn't collaboration, this is in effect just you having an edit war with zeromus with a 2 year delay. I don't know what argument you had about the FDS article, or what, but it's not at all relevant to the current discussion. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:13, 21 April 2015 (MDT)<br />
<br />
:Yeah, it really suck because we're making efforts and we get in the way of eachother. That's just how this wiki works and is doomed to work. As for the thread it's [http://forums.nesdev.org/viewtopic.php?f=14&t=12621 here], but it was in an abandoned state after one day. If I say "should we do that" and nobody react I assume nobody cares if I to do it. Well wrong assumption I guess. I was absolutely sure the Dish docs were untouched that is why I acted this way. However the edits from the are not lost because they're in the history logs. I'll track for them, and update new Dish docs to RHDN to apologize for this behaviour (so I don't have to deal with the wiki anymore but still repair what I have broken). I hope this is okay for everyone. It will take a few days, though.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:28, 21 April 2015 (MDT)<br />
<br />
::I reacted, and I started working on the problem. I didn't want to just revert your deletions because it would basically be an edit war if we don't talk about it first. Undoing a single revision I can explain in the comment summary, but doing many is kind of hostile. I know you spent a good amount of time (in good faith) making the edits, though zeromus also spent a good amount of time putting that stuff up in the first place. Both of you wanted to improve the wiki, and I'm trying to mediate this by keeping anything of value that was there. You don't need to revert anything yourself, at this point; I have been reviewing the changes, and keeping a list of deletions at [[User:Rainwarrior]], and I'll eventually get through them one by one as part of the ongoing project I started. I want to keep all the document links you added, for eaxmple, because those are good. As for updating RHDN, you can do that if you like, but I'm only concerned about the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:42, 21 April 2015 (MDT)<br />
<br />
== MMC5-internal RAM ==<br />
What is the logic in the ASIC that causes it to write zero if the PPU is not rendering? --[[User:Zzo38|Zzo38]] 01:51, 22 September 2012 (MDT)<br />
<br />
Another question about the ExRAM is, what happens when you try to read/write ExRAM nametables through the PPU registers, and if extended attribute mode is selected, what happens when reading/writing attribute tables using the PPU registers (when it isn't rendering the picture, and in any potentially random order)? --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 22:23, 24 February 2014 (MST)<br />
<br />
Yet another question : Is the ExRAM battery backed ? It would seem no, but technically the Battery is connected to the MMC5 so who knowns ? [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 04:38, 5 May 2014 (MDT)<br />
<br />
== Even more extended PRG RAM ==<br />
Parsimony of silicon strongly implies that the higher address lines (corresponding to the 0x78 bits of the register) are still driven for the registers from $5114 to $5116 even when RAM is selected, meaning >64KiB PRG-RAM would be usable when mapped to $8000-$DFFF.<br />
It's conceivable that these same bits of the register at $5113 (controlling PRG-RAM bank) are implemented, since they have to feed a multiplexer anyway.<br />
Something to test, maybe. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 23:34, 20 January 2014 (MST)<br />
<br />
== PRG Bankswitching ==<br />
The PRG bankswitching section was much better before the recent edits by Ben Bolt. In particular, I do not see why non-existing registers $5112 etc... are even mentioned at all. The current page is a huge mess and I don't see any new info that wasn't there before, except that it's now much less readable and non understandable.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 00:40, 26 November 2018 (MST)<br />
<br />
Also, this is not related to recent edits, but the info in this wiki clearly contradict Dish notes.<br />
<br />
Wiki says<br />
''Mode 1 - Select a 16KB PRG ROM bank at $C000-$FFFF (pass through CPU A13 to PRG A13 instead of using bit 0)<br />
Mode 0 - Select a 32KB PRG ROM bank at $8000-$FFFF (pass through CPU A13 and A14 to PRG A13 and A14 instead of using bits 0 and 1)''<br />
<br />
Dish says<br />
<br />
''Note that unlike most other mappers, these CHR pages are in *actual* sizes. IE: when in 4k mode, registers<br />
contain 4k page numbers. But when in 2k mode, register contain 2k page numbers.<br />
''<br />
<br />
This was already contradictory before the recent edits but I didn't notice. So who's right, who's wrong ? At least Castlevania III uses 16k banks with MMC5 so this should be easy to figure out.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 08:50, 26 November 2018 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:MMC5&diff=14383Talk:MMC52018-11-26T15:40:17Z<p>Bregalad: /* PRG Bankswitching */ Some precision (I wasn't talking about the whole article)</p>
<hr />
<div>== [[wikipedia:Don't repeat yourself|Don't Repeat Yourself]] failure ==<br />
Ok, it's crazy to have two completely different pages explaining the MMC5 mapper, one on iNES mapper 5 and the other on MMC5. I think the info should be present on a single page (like it is for all other mappers).<br />
<br />
Well in fact it seems it's Zeromus who added Dish's notes on all iNES mapper pages. This would be nice if the info wasn't already present on the wiki - having twice the same info isn't very logical is it ? I don't know what to do but something should probably be changed...Bregalad 00:36, 23 March 2012 (PDT)<br />
<br />
:Disch' format is '''much''' better for reading. Funny, I was really thinking to discuss about such thing. :) --[[User:Zepper|Zepper]] 14:44, 23 March 2012 (PDT)<br />
<br />
:Problem solved. @Zepper : If there is a particular point that should be improved about how the mappers are presented on the wiki, then please change it (or at least say more precisely what is ''much'' better).[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:02, 20 April 2015 (MDT)<br />
<br />
::Rather than just deleting them, I've been trying to review the disch notes and compare them to the existing article, integrating anything that it was adding before removing it. It's more time consuming than just deleting them, but the whole point of zeromus pasting them here was that they might improve the articles. Sometimes they add nothing, for sure, but it's worth reviewing before deleting, I think. In the process you might find other things here and there to improve in the mapper articles too. This review process is healthy for the wiki content. We don't need to be in a hurry to scour the disch notes from the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 20:38, 20 April 2015 (MDT)<br />
<br />
:: They have been here for more than three years, so how much time should have been waited for their removal in your opinion? 10 years? As I said they are still available, so you can just download them, and do the review work using your local copy of Dish notes. No point to have them pasted here, period. I absolutely agree that such a review work is benefical, and if there is a particular part you'd want me to review, just ask.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 03:13, 21 April 2015 (MDT)<br />
<br />
::: If you'd bothered to pay attention to what Rainwarrior's been doing, he's been carefully looking over each page and incorporating Disch's documentation as he goes, not just blindly removing everything.—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 04:53, 21 April 2015 (MDT)<br />
<br />
::: I did not just remove it but link to the original place. That's a different thing. Please explain me why Rainwarrior cannot download dish's document on his hard drive and work with that copy. (answer : he can, and that makes a lot more sense). Anyways I'm sick of editing this wiki for a while. [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:04, 21 April 2015 (MDT)<br />
<br />
:::: There are several reasons why I would not do it that way:<br />
:::: - If I download the document and begin integrating it into the Wiki, it can no longer be a collaborative process. If I do that, I have to do every single one myself (nobody can help, sensibly, without being redundant), and there is really no good way to know which have been done already.<br />
:::: - Several of the Disch notes sections have had edits in the time since being pasted here, and all of these deserve an overview before being removed.<br />
:::: - I believe zeromus' addition of the Disch notes to the Wiki was overall a good thing, filling in content where it was missing at the temporary expense of redundancy.<br />
:::: - Simply reverting someone's changes without reviewing them treats them in bad faith.<br />
:::: "if there is a particular part you'd want me to review, just ask." Please review every deletion you make. That's what I am asking, and that was the project I had begun, myself. If you don't want to do this, please just leave it there. I will get to it eventually! I had started working on this carefully (but slowly). It will probably take me a few months if I do it alone, but I really don't appreciate someone coming in with sweeping deletions and making it difficult for me to try and attempt to finally make good on zeromus' good-faith effort to have the wiki improved by Disch's notes. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 10:48, 21 April 2015 (MDT)<br />
<br />
Oh because those HAVE HAD EDITS ?! :O<br />
<br />
Now everything makes even less sense. I give up! This wiki is a huge mess anyway and will always be. Collaborative work just doesn't work. My only regrets is to have worked so hard for the hardware page and the FDS page, when they are doomed to be in the little of this huge disorganized mess with no head and no tail. Any change I make is systematically criticized, even if I asked in the forums if it was ok to do it, and nobody reacts which I belive is "I'm ok with that", but after the change everytime screams like "Begalad you're doing it all wrong, revert those changes!" It's the fourth time there is an issue like that where changes I made in a lame attempt to make this wiki a slightly better place are refuted only AFTER I made them.<br />
<br />
By the way a great thing would be to report those edits to RHDN, so that at least a clean and up to date version of Dish' doccument lies somewhere (and that is on RHDN, not here).[[Special:Contributions/185.26.182.29|185.26.182.29]] 12:47, 21 April 2015 (MDT)<br />
:If consensus for large scale editing has been established in a topic on the forum, it would be a good idea to include the URL of this topic in the edit summary of each edit so that we know what you're doing. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 12:56, 21 April 2015 (MDT)<br />
<br />
:I can't complain about your changes before you make them, unless you tell us what your intentions are first. If you want to make large scale changes unannounced, yes, people will complain after the fact. When else would they complain? I think we want the same thing in the end (no more redundant Disch notes), but I am unhappy with the way you are doing it. I began several days ago a long term effort to do it carefully to make sure we aren't losing information as the Disch notes are removed, but suddenly you have come in to just bulldoze it to the ground, and this does bother me. This isn't collaboration, this is in effect just you having an edit war with zeromus with a 2 year delay. I don't know what argument you had about the FDS article, or what, but it's not at all relevant to the current discussion. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:13, 21 April 2015 (MDT)<br />
<br />
:Yeah, it really suck because we're making efforts and we get in the way of eachother. That's just how this wiki works and is doomed to work. As for the thread it's [http://forums.nesdev.org/viewtopic.php?f=14&t=12621 here], but it was in an abandoned state after one day. If I say "should we do that" and nobody react I assume nobody cares if I to do it. Well wrong assumption I guess. I was absolutely sure the Dish docs were untouched that is why I acted this way. However the edits from the are not lost because they're in the history logs. I'll track for them, and update new Dish docs to RHDN to apologize for this behaviour (so I don't have to deal with the wiki anymore but still repair what I have broken). I hope this is okay for everyone. It will take a few days, though.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:28, 21 April 2015 (MDT)<br />
<br />
::I reacted, and I started working on the problem. I didn't want to just revert your deletions because it would basically be an edit war if we don't talk about it first. Undoing a single revision I can explain in the comment summary, but doing many is kind of hostile. I know you spent a good amount of time (in good faith) making the edits, though zeromus also spent a good amount of time putting that stuff up in the first place. Both of you wanted to improve the wiki, and I'm trying to mediate this by keeping anything of value that was there. You don't need to revert anything yourself, at this point; I have been reviewing the changes, and keeping a list of deletions at [[User:Rainwarrior]], and I'll eventually get through them one by one as part of the ongoing project I started. I want to keep all the document links you added, for eaxmple, because those are good. As for updating RHDN, you can do that if you like, but I'm only concerned about the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:42, 21 April 2015 (MDT)<br />
<br />
== MMC5-internal RAM ==<br />
What is the logic in the ASIC that causes it to write zero if the PPU is not rendering? --[[User:Zzo38|Zzo38]] 01:51, 22 September 2012 (MDT)<br />
<br />
Another question about the ExRAM is, what happens when you try to read/write ExRAM nametables through the PPU registers, and if extended attribute mode is selected, what happens when reading/writing attribute tables using the PPU registers (when it isn't rendering the picture, and in any potentially random order)? --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 22:23, 24 February 2014 (MST)<br />
<br />
Yet another question : Is the ExRAM battery backed ? It would seem no, but technically the Battery is connected to the MMC5 so who knowns ? [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 04:38, 5 May 2014 (MDT)<br />
<br />
== Even more extended PRG RAM ==<br />
Parsimony of silicon strongly implies that the higher address lines (corresponding to the 0x78 bits of the register) are still driven for the registers from $5114 to $5116 even when RAM is selected, meaning >64KiB PRG-RAM would be usable when mapped to $8000-$DFFF.<br />
It's conceivable that these same bits of the register at $5113 (controlling PRG-RAM bank) are implemented, since they have to feed a multiplexer anyway.<br />
Something to test, maybe. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 23:34, 20 January 2014 (MST)<br />
<br />
== PRG Bankswitching ==<br />
The PRG bankswitching section was much better before the recent edits by Ben Bolt. In particular, I do not see why non-existing registers $5112 etc... are even mentioned at all. The current page is a huge mess and I don't see any new info that wasn't there before, except that it's now much less readable and non understandable.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 00:40, 26 November 2018 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:MMC5&diff=14382Talk:MMC52018-11-26T07:48:01Z<p>Bregalad: Add title</p>
<hr />
<div>== [[wikipedia:Don't repeat yourself|Don't Repeat Yourself]] failure ==<br />
Ok, it's crazy to have two completely different pages explaining the MMC5 mapper, one on iNES mapper 5 and the other on MMC5. I think the info should be present on a single page (like it is for all other mappers).<br />
<br />
Well in fact it seems it's Zeromus who added Dish's notes on all iNES mapper pages. This would be nice if the info wasn't already present on the wiki - having twice the same info isn't very logical is it ? I don't know what to do but something should probably be changed...Bregalad 00:36, 23 March 2012 (PDT)<br />
<br />
:Disch' format is '''much''' better for reading. Funny, I was really thinking to discuss about such thing. :) --[[User:Zepper|Zepper]] 14:44, 23 March 2012 (PDT)<br />
<br />
:Problem solved. @Zepper : If there is a particular point that should be improved about how the mappers are presented on the wiki, then please change it (or at least say more precisely what is ''much'' better).[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:02, 20 April 2015 (MDT)<br />
<br />
::Rather than just deleting them, I've been trying to review the disch notes and compare them to the existing article, integrating anything that it was adding before removing it. It's more time consuming than just deleting them, but the whole point of zeromus pasting them here was that they might improve the articles. Sometimes they add nothing, for sure, but it's worth reviewing before deleting, I think. In the process you might find other things here and there to improve in the mapper articles too. This review process is healthy for the wiki content. We don't need to be in a hurry to scour the disch notes from the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 20:38, 20 April 2015 (MDT)<br />
<br />
:: They have been here for more than three years, so how much time should have been waited for their removal in your opinion? 10 years? As I said they are still available, so you can just download them, and do the review work using your local copy of Dish notes. No point to have them pasted here, period. I absolutely agree that such a review work is benefical, and if there is a particular part you'd want me to review, just ask.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 03:13, 21 April 2015 (MDT)<br />
<br />
::: If you'd bothered to pay attention to what Rainwarrior's been doing, he's been carefully looking over each page and incorporating Disch's documentation as he goes, not just blindly removing everything.—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 04:53, 21 April 2015 (MDT)<br />
<br />
::: I did not just remove it but link to the original place. That's a different thing. Please explain me why Rainwarrior cannot download dish's document on his hard drive and work with that copy. (answer : he can, and that makes a lot more sense). Anyways I'm sick of editing this wiki for a while. [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:04, 21 April 2015 (MDT)<br />
<br />
:::: There are several reasons why I would not do it that way:<br />
:::: - If I download the document and begin integrating it into the Wiki, it can no longer be a collaborative process. If I do that, I have to do every single one myself (nobody can help, sensibly, without being redundant), and there is really no good way to know which have been done already.<br />
:::: - Several of the Disch notes sections have had edits in the time since being pasted here, and all of these deserve an overview before being removed.<br />
:::: - I believe zeromus' addition of the Disch notes to the Wiki was overall a good thing, filling in content where it was missing at the temporary expense of redundancy.<br />
:::: - Simply reverting someone's changes without reviewing them treats them in bad faith.<br />
:::: "if there is a particular part you'd want me to review, just ask." Please review every deletion you make. That's what I am asking, and that was the project I had begun, myself. If you don't want to do this, please just leave it there. I will get to it eventually! I had started working on this carefully (but slowly). It will probably take me a few months if I do it alone, but I really don't appreciate someone coming in with sweeping deletions and making it difficult for me to try and attempt to finally make good on zeromus' good-faith effort to have the wiki improved by Disch's notes. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 10:48, 21 April 2015 (MDT)<br />
<br />
Oh because those HAVE HAD EDITS ?! :O<br />
<br />
Now everything makes even less sense. I give up! This wiki is a huge mess anyway and will always be. Collaborative work just doesn't work. My only regrets is to have worked so hard for the hardware page and the FDS page, when they are doomed to be in the little of this huge disorganized mess with no head and no tail. Any change I make is systematically criticized, even if I asked in the forums if it was ok to do it, and nobody reacts which I belive is "I'm ok with that", but after the change everytime screams like "Begalad you're doing it all wrong, revert those changes!" It's the fourth time there is an issue like that where changes I made in a lame attempt to make this wiki a slightly better place are refuted only AFTER I made them.<br />
<br />
By the way a great thing would be to report those edits to RHDN, so that at least a clean and up to date version of Dish' doccument lies somewhere (and that is on RHDN, not here).[[Special:Contributions/185.26.182.29|185.26.182.29]] 12:47, 21 April 2015 (MDT)<br />
:If consensus for large scale editing has been established in a topic on the forum, it would be a good idea to include the URL of this topic in the edit summary of each edit so that we know what you're doing. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 12:56, 21 April 2015 (MDT)<br />
<br />
:I can't complain about your changes before you make them, unless you tell us what your intentions are first. If you want to make large scale changes unannounced, yes, people will complain after the fact. When else would they complain? I think we want the same thing in the end (no more redundant Disch notes), but I am unhappy with the way you are doing it. I began several days ago a long term effort to do it carefully to make sure we aren't losing information as the Disch notes are removed, but suddenly you have come in to just bulldoze it to the ground, and this does bother me. This isn't collaboration, this is in effect just you having an edit war with zeromus with a 2 year delay. I don't know what argument you had about the FDS article, or what, but it's not at all relevant to the current discussion. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:13, 21 April 2015 (MDT)<br />
<br />
:Yeah, it really suck because we're making efforts and we get in the way of eachother. That's just how this wiki works and is doomed to work. As for the thread it's [http://forums.nesdev.org/viewtopic.php?f=14&t=12621 here], but it was in an abandoned state after one day. If I say "should we do that" and nobody react I assume nobody cares if I to do it. Well wrong assumption I guess. I was absolutely sure the Dish docs were untouched that is why I acted this way. However the edits from the are not lost because they're in the history logs. I'll track for them, and update new Dish docs to RHDN to apologize for this behaviour (so I don't have to deal with the wiki anymore but still repair what I have broken). I hope this is okay for everyone. It will take a few days, though.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:28, 21 April 2015 (MDT)<br />
<br />
::I reacted, and I started working on the problem. I didn't want to just revert your deletions because it would basically be an edit war if we don't talk about it first. Undoing a single revision I can explain in the comment summary, but doing many is kind of hostile. I know you spent a good amount of time (in good faith) making the edits, though zeromus also spent a good amount of time putting that stuff up in the first place. Both of you wanted to improve the wiki, and I'm trying to mediate this by keeping anything of value that was there. You don't need to revert anything yourself, at this point; I have been reviewing the changes, and keeping a list of deletions at [[User:Rainwarrior]], and I'll eventually get through them one by one as part of the ongoing project I started. I want to keep all the document links you added, for eaxmple, because those are good. As for updating RHDN, you can do that if you like, but I'm only concerned about the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:42, 21 April 2015 (MDT)<br />
<br />
== MMC5-internal RAM ==<br />
What is the logic in the ASIC that causes it to write zero if the PPU is not rendering? --[[User:Zzo38|Zzo38]] 01:51, 22 September 2012 (MDT)<br />
<br />
Another question about the ExRAM is, what happens when you try to read/write ExRAM nametables through the PPU registers, and if extended attribute mode is selected, what happens when reading/writing attribute tables using the PPU registers (when it isn't rendering the picture, and in any potentially random order)? --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 22:23, 24 February 2014 (MST)<br />
<br />
Yet another question : Is the ExRAM battery backed ? It would seem no, but technically the Battery is connected to the MMC5 so who knowns ? [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 04:38, 5 May 2014 (MDT)<br />
<br />
== Even more extended PRG RAM ==<br />
Parsimony of silicon strongly implies that the higher address lines (corresponding to the 0x78 bits of the register) are still driven for the registers from $5114 to $5116 even when RAM is selected, meaning >64KiB PRG-RAM would be usable when mapped to $8000-$DFFF.<br />
It's conceivable that these same bits of the register at $5113 (controlling PRG-RAM bank) are implemented, since they have to feed a multiplexer anyway.<br />
Something to test, maybe. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 23:34, 20 January 2014 (MST)<br />
<br />
== PRG Bankswitching ==<br />
The article was much better before the recent edits by Ben Bolt. In particular, I do not see why non-existing registers $5112 etc... are even mentioned at all. The current page is a huge mess and I don't see any new info that wasn't there before, except that it's now much less readable and non understandable.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 00:40, 26 November 2018 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:MMC5&diff=14381Talk:MMC52018-11-26T07:40:53Z<p>Bregalad: </p>
<hr />
<div>== [[wikipedia:Don't repeat yourself|Don't Repeat Yourself]] failure ==<br />
Ok, it's crazy to have two completely different pages explaining the MMC5 mapper, one on iNES mapper 5 and the other on MMC5. I think the info should be present on a single page (like it is for all other mappers).<br />
<br />
Well in fact it seems it's Zeromus who added Dish's notes on all iNES mapper pages. This would be nice if the info wasn't already present on the wiki - having twice the same info isn't very logical is it ? I don't know what to do but something should probably be changed...Bregalad 00:36, 23 March 2012 (PDT)<br />
<br />
:Disch' format is '''much''' better for reading. Funny, I was really thinking to discuss about such thing. :) --[[User:Zepper|Zepper]] 14:44, 23 March 2012 (PDT)<br />
<br />
:Problem solved. @Zepper : If there is a particular point that should be improved about how the mappers are presented on the wiki, then please change it (or at least say more precisely what is ''much'' better).[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:02, 20 April 2015 (MDT)<br />
<br />
::Rather than just deleting them, I've been trying to review the disch notes and compare them to the existing article, integrating anything that it was adding before removing it. It's more time consuming than just deleting them, but the whole point of zeromus pasting them here was that they might improve the articles. Sometimes they add nothing, for sure, but it's worth reviewing before deleting, I think. In the process you might find other things here and there to improve in the mapper articles too. This review process is healthy for the wiki content. We don't need to be in a hurry to scour the disch notes from the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 20:38, 20 April 2015 (MDT)<br />
<br />
:: They have been here for more than three years, so how much time should have been waited for their removal in your opinion? 10 years? As I said they are still available, so you can just download them, and do the review work using your local copy of Dish notes. No point to have them pasted here, period. I absolutely agree that such a review work is benefical, and if there is a particular part you'd want me to review, just ask.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 03:13, 21 April 2015 (MDT)<br />
<br />
::: If you'd bothered to pay attention to what Rainwarrior's been doing, he's been carefully looking over each page and incorporating Disch's documentation as he goes, not just blindly removing everything.—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 04:53, 21 April 2015 (MDT)<br />
<br />
::: I did not just remove it but link to the original place. That's a different thing. Please explain me why Rainwarrior cannot download dish's document on his hard drive and work with that copy. (answer : he can, and that makes a lot more sense). Anyways I'm sick of editing this wiki for a while. [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 06:04, 21 April 2015 (MDT)<br />
<br />
:::: There are several reasons why I would not do it that way:<br />
:::: - If I download the document and begin integrating it into the Wiki, it can no longer be a collaborative process. If I do that, I have to do every single one myself (nobody can help, sensibly, without being redundant), and there is really no good way to know which have been done already.<br />
:::: - Several of the Disch notes sections have had edits in the time since being pasted here, and all of these deserve an overview before being removed.<br />
:::: - I believe zeromus' addition of the Disch notes to the Wiki was overall a good thing, filling in content where it was missing at the temporary expense of redundancy.<br />
:::: - Simply reverting someone's changes without reviewing them treats them in bad faith.<br />
:::: "if there is a particular part you'd want me to review, just ask." Please review every deletion you make. That's what I am asking, and that was the project I had begun, myself. If you don't want to do this, please just leave it there. I will get to it eventually! I had started working on this carefully (but slowly). It will probably take me a few months if I do it alone, but I really don't appreciate someone coming in with sweeping deletions and making it difficult for me to try and attempt to finally make good on zeromus' good-faith effort to have the wiki improved by Disch's notes. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 10:48, 21 April 2015 (MDT)<br />
<br />
Oh because those HAVE HAD EDITS ?! :O<br />
<br />
Now everything makes even less sense. I give up! This wiki is a huge mess anyway and will always be. Collaborative work just doesn't work. My only regrets is to have worked so hard for the hardware page and the FDS page, when they are doomed to be in the little of this huge disorganized mess with no head and no tail. Any change I make is systematically criticized, even if I asked in the forums if it was ok to do it, and nobody reacts which I belive is "I'm ok with that", but after the change everytime screams like "Begalad you're doing it all wrong, revert those changes!" It's the fourth time there is an issue like that where changes I made in a lame attempt to make this wiki a slightly better place are refuted only AFTER I made them.<br />
<br />
By the way a great thing would be to report those edits to RHDN, so that at least a clean and up to date version of Dish' doccument lies somewhere (and that is on RHDN, not here).[[Special:Contributions/185.26.182.29|185.26.182.29]] 12:47, 21 April 2015 (MDT)<br />
:If consensus for large scale editing has been established in a topic on the forum, it would be a good idea to include the URL of this topic in the edit summary of each edit so that we know what you're doing. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 12:56, 21 April 2015 (MDT)<br />
<br />
:I can't complain about your changes before you make them, unless you tell us what your intentions are first. If you want to make large scale changes unannounced, yes, people will complain after the fact. When else would they complain? I think we want the same thing in the end (no more redundant Disch notes), but I am unhappy with the way you are doing it. I began several days ago a long term effort to do it carefully to make sure we aren't losing information as the Disch notes are removed, but suddenly you have come in to just bulldoze it to the ground, and this does bother me. This isn't collaboration, this is in effect just you having an edit war with zeromus with a 2 year delay. I don't know what argument you had about the FDS article, or what, but it's not at all relevant to the current discussion. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:13, 21 April 2015 (MDT)<br />
<br />
:Yeah, it really suck because we're making efforts and we get in the way of eachother. That's just how this wiki works and is doomed to work. As for the thread it's [http://forums.nesdev.org/viewtopic.php?f=14&t=12621 here], but it was in an abandoned state after one day. If I say "should we do that" and nobody react I assume nobody cares if I to do it. Well wrong assumption I guess. I was absolutely sure the Dish docs were untouched that is why I acted this way. However the edits from the are not lost because they're in the history logs. I'll track for them, and update new Dish docs to RHDN to apologize for this behaviour (so I don't have to deal with the wiki anymore but still repair what I have broken). I hope this is okay for everyone. It will take a few days, though.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 13:28, 21 April 2015 (MDT)<br />
<br />
::I reacted, and I started working on the problem. I didn't want to just revert your deletions because it would basically be an edit war if we don't talk about it first. Undoing a single revision I can explain in the comment summary, but doing many is kind of hostile. I know you spent a good amount of time (in good faith) making the edits, though zeromus also spent a good amount of time putting that stuff up in the first place. Both of you wanted to improve the wiki, and I'm trying to mediate this by keeping anything of value that was there. You don't need to revert anything yourself, at this point; I have been reviewing the changes, and keeping a list of deletions at [[User:Rainwarrior]], and I'll eventually get through them one by one as part of the ongoing project I started. I want to keep all the document links you added, for eaxmple, because those are good. As for updating RHDN, you can do that if you like, but I'm only concerned about the wiki. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:42, 21 April 2015 (MDT)<br />
<br />
== MMC5-internal RAM ==<br />
What is the logic in the ASIC that causes it to write zero if the PPU is not rendering? --[[User:Zzo38|Zzo38]] 01:51, 22 September 2012 (MDT)<br />
<br />
Another question about the ExRAM is, what happens when you try to read/write ExRAM nametables through the PPU registers, and if extended attribute mode is selected, what happens when reading/writing attribute tables using the PPU registers (when it isn't rendering the picture, and in any potentially random order)? --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 22:23, 24 February 2014 (MST)<br />
<br />
Yet another question : Is the ExRAM battery backed ? It would seem no, but technically the Battery is connected to the MMC5 so who knowns ? [[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 04:38, 5 May 2014 (MDT)<br />
<br />
== Even more extended PRG RAM ==<br />
Parsimony of silicon strongly implies that the higher address lines (corresponding to the 0x78 bits of the register) are still driven for the registers from $5114 to $5116 even when RAM is selected, meaning >64KiB PRG-RAM would be usable when mapped to $8000-$DFFF.<br />
It's conceivable that these same bits of the register at $5113 (controlling PRG-RAM bank) are implemented, since they have to feed a multiplexer anyway.<br />
Something to test, maybe. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 23:34, 20 January 2014 (MST)<br />
<br />
The article was much better before the recent edits by Ben Bolt. In particular, I do not see why non-existing registers $5112 etc... are even mentioned at all. The current page is a huge mess and I don't see any new info that wasn't there before, except that it's now much less readable and non understandable.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 00:40, 26 November 2018 (MST)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=MMC2&diff=6431MMC22018-11-20T13:13:06Z<p>Bregalad: /* CHR banking */ Spelling/clarification</p>
<hr />
<div>{{Infobox iNES mapper<br />
|name=MMC2<br />
|name2=PxROM<br />
|company=Nintendo<br />
|mapper=9<br />
|nescartdbgames=1<br />
|complexity=ASIC<br />
|boards=PNROM, PEEOROM<br />
|prgmax=128K<br />
|prgpage=8K + 24K fixed<br />
|wrammax=8K (PC10 ver.)<br />
|wrampage=Fixed<br />
|chrmax=128K<br />
|chrpage=4K + 4K (triggered)<br />
|mirroring=H or V, switchable<br />
|busconflicts=No<br />
}}[[Category:Nintendo licensed mappers]]<br />
The '''Nintendo MMC2''' is an [[:Category:ASIC mappers|ASIC]] [[MMC|mapper]], used on the '''PNROM''' and '''PEEOROM''' Nintendo Game Pak boards for ''Mike Tyson's Punch Out!!''.<br />
The [[iNES]] format assigns '''Mapper 009''' to '''PxROM'''.<br />
This chip appeared in November 1987.<br />
<br />
== Banks ==<br />
* CPU $6000-$7FFF: 8 KB PRG RAM bank (PlayChoice version only; [[PRG RAM circuit|contains a 6264 and 74139]])<br />
* CPU $8000-$9FFF: 8 KB switchable PRG ROM bank<br />
* CPU $A000-$FFFF: Three 8 KB PRG ROM banks, fixed to the last three banks<br />
* PPU $0000-$0FFF: Two 4 KB switchable CHR ROM banks<br />
* PPU $1000-$1FFF: Two 4 KB switchable CHR ROM banks<br />
<br />
The two 4 KB PPU banks each have two 4 KB banks, which can be switched during rendering by using the special tiles $FD or $FE in either a sprite or the background. See [[#CHR banking|CHR banking]] below.<br />
<br />
== Registers ==<br />
=== PRG ROM bank select ($A000-$AFFF) ===<br />
7 bit 0<br />
---- ----<br />
xxxx PPPP<br />
||||<br />
++++- Select 8 KB PRG ROM bank for CPU $8000-$9FFF<br />
<br />
=== CHR ROM $FD/0000 bank select ($B000-$BFFF) ===<br />
7 bit 0<br />
---- ----<br />
xxxC CCCC<br />
| ||||<br />
+-++++- Select 4 KB CHR ROM bank for PPU $0000-$0FFF<br />
used when latch 0 = $FD<br />
<br />
=== CHR ROM $FE/0000 bank select ($C000-$CFFF) ===<br />
7 bit 0<br />
---- ----<br />
xxxC CCCC<br />
| ||||<br />
+-++++- Select 4 KB CHR ROM bank for PPU $0000-$0FFF<br />
used when latch 0 = $FE<br />
<br />
=== CHR ROM $FD/1000 bank select ($D000-$DFFF) ===<br />
7 bit 0<br />
---- ----<br />
xxxC CCCC<br />
| ||||<br />
+-++++- Select 4 KB CHR ROM bank for PPU $1000-$1FFF<br />
used when latch 1 = $FD<br />
<br />
=== CHR ROM $FE/1000 bank select ($E000-$EFFF) ===<br />
7 bit 0<br />
---- ----<br />
xxxC CCCC<br />
| ||||<br />
+-++++- Select 4 KB CHR ROM bank for PPU $1000-$1FFF<br />
used when latch 1 = $FE<br />
<br />
=== Mirroring ($F000-$FFFF) ===<br />
7 bit 0<br />
---- ----<br />
xxxx xxxM<br />
|<br />
+- Select nametable mirroring (0: vertical; 1: horizontal)<br />
<br />
== CHR banking ==<br />
<br />
The main interest of the MMC2 and MMC4 mappers is that they allow switching two pairs of 4 KB CHR-ROM banks at the same time, automatically alternating between banks within one pair during rendering. When the PPU reads from specific tiles ($FD or $FE) in the pattern tables, the MMC2/4 sets a latch that switches between two different 4 KB banks. This allows the tile limit to increase from 256 to 512 with bank splits, without involving the CPU or an IRQ.<br />
<br />
*PPU reads $0FD8: latch 0 is set to $FD for subsequent reads<br />
*PPU reads $0FE8: latch 0 is set to $FE for subsequent reads<br />
*PPU reads $1FD8 through $1FDF: latch 1 is set to $FD for subsequent reads<br />
*PPU reads $1FE8 through $1FEF: latch 1 is set to $FE for subsequent reads<br />
<br />
Notice that latch 0 only responds to one address, but latch 1 responds to a range of addresses. This means that:<br />
* The left ($0000-0FFF) pattern table only switches on the ''top row'' of the 8x8 tile<br />
* The right ($1000-1FFF) pattern table switches on ''every row'' of the 8x8 tile<br />
<br />
With this mapper, the left pattern table ($0000) is intended for use with sprites, and the right pattern ($1000) table for background. Backgrounds require a switch on every row. Because sprites aren't constrained to an 8x8 grid, triggering on only the first row allows switching sprites to be placed closer together if needed. This nuance is absent in the [[MMC4]], where both pattern table switches from the entire tiles in a symmetrical fashion.<br />
<br />
Note that the latch is updated ''after'' either pattern table byte is fetched, so the switching tiles $FD or $FE themselves are drawn using the old CHR-bank before the latch value is changed. As the PPU fetches 34 background tiles per scanline (and at most 33 are drawn), if vertical [[mirroring]] is used, background switching tiles can be placed past the edge of the screen where they will be unseen.<br />
<br />
== Hardware ==<br />
The MMC2 is implemented in a [[MMC2 pinout|40-pin shrink-DIP package]].<br />
At least two revisions are known to exist, the MMC2 and the MMC2-L.<br />
<br />
The PEEOROM board is used in the re-issue of ''Mike Tyson's Punch-Out!!''. Unlike PNROM, and unlike most other boards used in NES Game Paks sold to the public, it can be configured to support EPROM memory through jumpers on the board.<br />
<br />
A pirate clone that exclusively uses discrete logic has been found and reverse-engineered. [http://forums.nesdev.org/viewtopic.php?f=9&t=10652]<br />
<br />
== Variants ==<br />
Nintendo's [[MMC4]], used in the [[FxROM]] board set, is a similar mapper with PRG RAM support and PRG bank sizes of 16kb instead of 8kb. It also suppresses the different banking behavior of the left pattern table.<br />
<br />
Because of the extreme similarity between the MMC2 and MMC4, it is possible to make a circuit that simulates an MMC4 from an MMC2 with the help of a [[7402]] quad-NOR gate and a [[7420]] 4-input NAND gate to [[PRG RAM circuit|decode PRG RAM]].<br />
The following circuit "tricks" the MMC2 into thinking the program is still in the $8000-$9fff range when reading from $A000-$BFFF, but doesn't affect mapper writes.<br />
It also shifts all addresses left one bit so that it switches 16kB instead of 8kB banks, and it shortcuts around the different behavior for pattern tables at $0000 and $1000.<br />
<br />
<pre><br />
MMC2 A16 ---------------------------------- PRG A17<br />
<br />
MMC2 A15 ---------------------------------- PRG A16<br />
<br />
MMC2 A14 ---------------------------------- PRG A15<br />
____ ___<br />
MMC2 A13 -----\ `. ,---\ `.<br />
) )o-----+ ) )o--- PRG A14<br />
CPU A14 -----/____,' `---/___,' <br />
<br />
CPU A13 ---+------------------------------ PRG A13<br />
| ___<br />
+---\ `. ___<br />
| ) )o------\ `.<br />
`---/___,' ) )o----- MMC2 A13<br />
,----/___,'<br />
R/W ----------------'<br />
<br />
GND --------------------+------------- MMC2 PA2<br />
|<br />
+------------- MMC2 PA1<br />
|<br />
`------------- MMC2 PA0<br />
</pre><br />
<br />
== See also ==<br />
* [http://nesdev.org/mmc2.txt Nintendo MMC2] 01/29/98 by Jim Geffre.<br />
* [http://nesdev.org/mappers.zip Comprehensive NES Mapper Document] by \Firebug\, information about mapper's initial state and lates are inaccurate.<br />
* [http://www.romhacking.net/documents/362/ NES Mapper list] by Disch.</div>Bregaladhttps://www.nesdev.org/w/index.php?title=MMC2&diff=6430MMC22018-11-20T09:39:16Z<p>Bregalad: /* CHR banking */ Add some details.</p>
<hr />
<div>{{Infobox iNES mapper<br />
|name=MMC2<br />
|name2=PxROM<br />
|company=Nintendo<br />
|mapper=9<br />
|nescartdbgames=1<br />
|complexity=ASIC<br />
|boards=PNROM, PEEOROM<br />
|prgmax=128K<br />
|prgpage=8K + 24K fixed<br />
|wrammax=8K (PC10 ver.)<br />
|wrampage=Fixed<br />
|chrmax=128K<br />
|chrpage=4K + 4K (triggered)<br />
|mirroring=H or V, switchable<br />
|busconflicts=No<br />
}}[[Category:Nintendo licensed mappers]]<br />
The '''Nintendo MMC2''' is an [[:Category:ASIC mappers|ASIC]] [[MMC|mapper]], used on the '''PNROM''' and '''PEEOROM''' Nintendo Game Pak boards for ''Mike Tyson's Punch Out!!''.<br />
The [[iNES]] format assigns '''Mapper 009''' to '''PxROM'''.<br />
This chip appeared in November 1987.<br />
<br />
== Banks ==<br />
* CPU $6000-$7FFF: 8 KB PRG RAM bank (PlayChoice version only; [[PRG RAM circuit|contains a 6264 and 74139]])<br />
* CPU $8000-$9FFF: 8 KB switchable PRG ROM bank<br />
* CPU $A000-$FFFF: Three 8 KB PRG ROM banks, fixed to the last three banks<br />
* PPU $0000-$0FFF: Two 4 KB switchable CHR ROM banks<br />
* PPU $1000-$1FFF: Two 4 KB switchable CHR ROM banks<br />
<br />
The two 4 KB PPU banks each have two 4 KB banks, which can be switched during rendering by using the special tiles $FD or $FE in either a sprite or the background. See [[#CHR banking|CHR banking]] below.<br />
<br />
== Registers ==<br />
=== PRG ROM bank select ($A000-$AFFF) ===<br />
7 bit 0<br />
---- ----<br />
xxxx PPPP<br />
||||<br />
++++- Select 8 KB PRG ROM bank for CPU $8000-$9FFF<br />
<br />
=== CHR ROM $FD/0000 bank select ($B000-$BFFF) ===<br />
7 bit 0<br />
---- ----<br />
xxxC CCCC<br />
| ||||<br />
+-++++- Select 4 KB CHR ROM bank for PPU $0000-$0FFF<br />
used when latch 0 = $FD<br />
<br />
=== CHR ROM $FE/0000 bank select ($C000-$CFFF) ===<br />
7 bit 0<br />
---- ----<br />
xxxC CCCC<br />
| ||||<br />
+-++++- Select 4 KB CHR ROM bank for PPU $0000-$0FFF<br />
used when latch 0 = $FE<br />
<br />
=== CHR ROM $FD/1000 bank select ($D000-$DFFF) ===<br />
7 bit 0<br />
---- ----<br />
xxxC CCCC<br />
| ||||<br />
+-++++- Select 4 KB CHR ROM bank for PPU $1000-$1FFF<br />
used when latch 1 = $FD<br />
<br />
=== CHR ROM $FE/1000 bank select ($E000-$EFFF) ===<br />
7 bit 0<br />
---- ----<br />
xxxC CCCC<br />
| ||||<br />
+-++++- Select 4 KB CHR ROM bank for PPU $1000-$1FFF<br />
used when latch 1 = $FE<br />
<br />
=== Mirroring ($F000-$FFFF) ===<br />
7 bit 0<br />
---- ----<br />
xxxx xxxM<br />
|<br />
+- Select nametable mirroring (0: vertical; 1: horizontal)<br />
<br />
== CHR banking ==<br />
<br />
The main interest of the MMC2 and MMC4 mappers is that they allow switching two pairs of 4 KB CHR-ROM banks at the same time, automatically alternating between banks within one pair during rendering. When the PPU reads from specific tiles ($FD or $FE) in the pattern tables, the MMC2/4 sets a latch that switches between two different 4 KB banks. This allows the tile limit to increase from 256 to 512 with bank splits, without involving the CPU or an IRQ.<br />
<br />
*PPU reads $0FD8: latch 0 is set to $FD for subsequent reads<br />
*PPU reads $0FE8: latch 0 is set to $FE for subsequent reads<br />
*PPU reads $1FD8 through $1FDF: latch 1 is set to $FD for subsequent reads<br />
*PPU reads $1FE8 through $1FEF: latch 1 is set to $FE for subsequent reads<br />
<br />
Notice that latch 0 only responds to one address, but latch 1 responds to a range of addresses. This means that:<br />
* The left ($0000-0FFF) pattern table only switches on the ''top row'' of the 8x8 tile<br />
* The right ($1000-1FFF) pattern table switches on ''every row'' of the 8x8 tile<br />
<br />
With this mapper, the left pattern table ($0000) is intended for use with sprites, and the right pattern ($1000) table for background. Backgrounds require a switch on every row. Because sprites aren't constrained to an 8x8 grid, triggering on only the first row allows switching sprites to be placed closer together if needed.<br />
<br />
This nuance is absent in the [[MMC4]], where both pattern table switches from the entire tiles in an symmetrical fashion.<br />
<br />
Note that the latch is updated ''after'' either pattern table byte is fetched, so the switching tiles $FD or $FE are drawn using the old CHR-bank before the new latch value is set. As the PPU fetches 34 background tiles per scanline (and at most 33 are drawn), if vertical [[mirroring]] is used, background switching tiles can be placed past the edge of the screen where they will be unseen.<br />
<br />
== Hardware ==<br />
The MMC2 is implemented in a [[MMC2 pinout|40-pin shrink-DIP package]].<br />
At least two revisions are known to exist, the MMC2 and the MMC2-L.<br />
<br />
The PEEOROM board is used in the re-issue of ''Mike Tyson's Punch-Out!!''. Unlike PNROM, and unlike most other boards used in NES Game Paks sold to the public, it can be configured to support EPROM memory through jumpers on the board.<br />
<br />
A pirate clone that exclusively uses discrete logic has been found and reverse-engineered. [http://forums.nesdev.org/viewtopic.php?f=9&t=10652]<br />
<br />
== Variants ==<br />
Nintendo's [[MMC4]], used in the [[FxROM]] board set, is a similar mapper with PRG RAM support and PRG bank sizes of 16kb instead of 8kb. It also suppresses the different banking behavior of the left pattern table.<br />
<br />
Because of the extreme similarity between the MMC2 and MMC4, it is possible to make a circuit that simulates an MMC4 from an MMC2 with the help of a [[7402]] quad-NOR gate and a [[7420]] 4-input NAND gate to [[PRG RAM circuit|decode PRG RAM]].<br />
The following circuit "tricks" the MMC2 into thinking the program is still in the $8000-$9fff range when reading from $A000-$BFFF, but doesn't affect mapper writes.<br />
It also shifts all addresses left one bit so that it switches 16kB instead of 8kB banks, and it shortcuts around the different behavior for pattern tables at $0000 and $1000.<br />
<br />
<pre><br />
MMC2 A16 ---------------------------------- PRG A17<br />
<br />
MMC2 A15 ---------------------------------- PRG A16<br />
<br />
MMC2 A14 ---------------------------------- PRG A15<br />
____ ___<br />
MMC2 A13 -----\ `. ,---\ `.<br />
) )o-----+ ) )o--- PRG A14<br />
CPU A14 -----/____,' `---/___,' <br />
<br />
CPU A13 ---+------------------------------ PRG A13<br />
| ___<br />
+---\ `. ___<br />
| ) )o------\ `.<br />
`---/___,' ) )o----- MMC2 A13<br />
,----/___,'<br />
R/W ----------------'<br />
<br />
GND --------------------+------------- MMC2 PA2<br />
|<br />
+------------- MMC2 PA1<br />
|<br />
`------------- MMC2 PA0<br />
</pre><br />
<br />
== See also ==<br />
* [http://nesdev.org/mmc2.txt Nintendo MMC2] 01/29/98 by Jim Geffre.<br />
* [http://nesdev.org/mappers.zip Comprehensive NES Mapper Document] by \Firebug\, information about mapper's initial state and lates are inaccurate.<br />
* [http://www.romhacking.net/documents/362/ NES Mapper list] by Disch.</div>Bregaladhttps://www.nesdev.org/w/index.php?title=MMC4&diff=6618MMC42018-11-20T09:24:35Z<p>Bregalad: In order to avoid having the same information twice in the wiki, make this page in the style of the MMC6 redirecting to MMC3 for common information; here we redirect to MMC2.</p>
<hr />
<div>{{Infobox iNES mapper<br />
|name=MMC4<br />
|name2=FxROM<br />
|company=Nintendo<br />
|mapper=10<br />
|nescartdbgames=3<br />
|complexity=ASIC<br />
|boards=FJROM, FKROM<br />
|prgmax=256K<br />
|prgpage=16K + 16K fixed<br />
|wrammax=8K<br />
|wrampage=8K<br />
|chrmax=128K<br />
|chrpage=4K + 4K (triggered)<br />
|mirroring=H or V, switchable<br />
|busconflicts=No<br />
}}<br />
[[Category:Nintendo licensed mappers]]<br />
The '''Nintendo MMC4''' is an [[:Category:ASIC mappers|ASIC]] [[MMC|mapper]], used on the [[FxROM]] board set. The [[iNES]] format assigns '''mapper 10''' to these boards. The chip first appeared in August 1988.<br />
<br />
Nintendo's MMC2, used in PxROM boards, is a similar mapper with 8 KB switchable PRG ROM banks, a 24 KB fixed PRG ROM bank, no PRG RAM, and a slightly different behaviour in auto-switching on the left (low) pattern table. This page only explains the differences, see [[MMC2]] for full details on the rest of the mapper.<br />
<br />
== Banks ==<br />
* CPU $6000-$7FFF: 8 KB fixed PRG RAM bank<br />
* CPU $8000-$BFFF: 16 KB switchable PRG ROM bank<br />
* CPU $C000-$FFFF: 16 KB PRG ROM bank, fixed to the last bank<br />
* PPU $0000-$0FFF: Two 4 KB switchable CHR ROM banks<br />
* PPU $1000-$1FFF: Two 4 KB switchable CHR ROM banks<br />
<br />
When the PPU reads from specific tiles in the pattern table during rendering, the MMC4 sets a latch that tells it to use a different 4 KB bank number. On the background layer, this has the effect of setting a different bank for all tiles to the right of a given tile, virtually increasing the tile count limit from 256 to 512 without monopolising the CPU.<br />
<br />
*PPU reads $0FD8 through $0FDF: latch 0 is set to $FD<br />
*PPU reads $0FE8 through $0FEF: latch 0 is set to $FE<br />
*PPU reads $1FD8 through $1FDF: latch 1 is set to $FD<br />
*PPU reads $1FE8 through $1FEF: latch 1 is set to $FE<br />
<br />
== Registers ==<br />
The MMC4 has 6 registers at $A000-$AFFF, $B000-$BFFF, $C000-$CFFF, $D000-$DFFF, $E000-$EFFF and $F000-$FFFF. Only $A000-$AFFF is covered here. For the rest of the registers, see [[MMC2]].<br />
<br />
=== PRG ROM bank select ($A000-$AFFF) ===<br />
7 bit 0<br />
---- ----<br />
xxxx PPPP<br />
||||<br />
++++- Select 16 KB PRG ROM bank for CPU $8000-$BFFF<br />
<br />
== Hardware ==<br />
The MMC4 is implemented in a 44-pin TQFP package: [[MMC4 pinout]]<br />
<br />
Only one revision is known to exist.<br />
<br />
== See also ==<br />
* [http://www.romhacking.net/documents/362/ NES Mapper List] by Disch<br />
* [http://nesdev.org/mmc4.txt Nintendo MMC4] (author unknown)<br />
*[http://nesdev.org/mappers.zip Comprehensive NES Mapper Document] by \Firebug\, information about mapper's initial state is inaccurate.</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:SxROM&diff=15762Talk:SxROM2018-11-09T07:50:44Z<p>Bregalad: Undo revision 15814 by 208.71.141.54 (talk)</p>
<hr />
<div></div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:NESdev_IRC_channel&diff=14922Talk:NESdev IRC channel2018-11-02T07:48:20Z<p>Bregalad: Undo revision 15796 by 208.71.141.54 (talk)</p>
<hr />
<div>Really enjoyed this article post.Really looking forward to read more. Will read on... Blaze<br />
<br />
== Chciałem się tylko przywitać ==<br />
<br />
Witam wszystkich jestem tu nowy ;) <small><span class="autosigned">—&nbsp;Preceding unsigned comment added by [[User:46.175.234.116|46.175.234.116]] ([[User talk:46.175.234.116|talk]] • [[Special:Contributions/46.175.234.116|contribs]]) 09:31, 24 August 2016</span></small><!-- Template:Unsigned --><br />
<br />
:I do not understand Polish, but hello to you too. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 02:42, 25 August 2016 (MDT)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:List_of_games_with_significant_regional_differences&diff=14258Talk:List of games with significant regional differences2018-11-01T10:26:33Z<p>Bregalad: /* If Rainbow Islands, why not Maniac Mansion? */</p>
<hr />
<div>Are we also going to put here games like:<br />
* Doki Doki Yuuenchi (J) / Trolls In Crazyland (E)<br />
* Hebereke (J) / Ufouria (E)<br />
* Wanpaku Kokkun no Gourmet World (J) / Panic Restaurant (E)<br />
<br />
and many more, which differ with changed sprites of main character and also many more?<br />
<br />
== So guys... ==<br />
<br />
This list is a complete mess. It should list individually games that adjusted the gameplay speed and music from those where there is ACTUAL significant regional differences, such as Castlevania games where the japanese version is COMPLETELY different from the western versions.<br />
<br />
Then the differences should be listed such as: Adjusted difficulty, fixed bugs, etc, etc... Actually I think the NES/FC games where there's no noticeable differences between regions are in minority. ESPECIALLY if adjusting the music or gameplay speed for PAL counts as a "difference".<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:49, 31 October 2018 (MDT)<br />
<br />
== If Rainbow Islands, why not Maniac Mansion? ==<br />
<br />
''Rainbow Islands'' is a different port between (U) and (E) versions. Isn't ''Maniac Mansion'' the same situation between (J) and (U) versions? Or is only (E) worth mentioning because of TV system differences? --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 07:21, 31 October 2018 (MDT)<br />
:The list had just been created by Krzysobial and it is far from being complete right now.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 04:26, 1 November 2018 (MDT)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=TxROM&diff=12105TxROM2018-11-01T10:17:44Z<p>Bregalad: /* Solder pad config */ Factorize out redundant information</p>
<hr />
<div>{{nesdbbox<br />
|unif_wild|-T%ROM|TxROM<br />
|unif_wild|TBROM|TBROM<br />
|unif_wild|TEROM|TEROM<br />
|unif_wild|TFROM|TFROM<br />
|unif_wild|TGROM|TGROM<br />
|unif_wild|TKROM|TKROM<br />
|unif_wild|TK1ROM|TK1ROM<br />
|unif_wild|TKSROM|TKSROM<br />
|unif_wild|TLROM|TLROM<br />
|unif_wild|TL1ROM|TL1ROM<br />
|unif_wild|TL2ROM|TL2ROM<br />
|unif_wild|TLSROM|TLSROM<br />
|unif_wild|TNROM|TNROM<br />
|unif_wild|TQROM|TQROM<br />
|unif_wild|TR1ROM|TR1ROM<br />
|unif_wild|TSROM|TSROM<br />
|unif_wild|TVROM|TVROM<br />
}}<br />
[[Category:MMC3-like mappers]][[Category:Nintendo licensed mappers]]<br />
The generic designation '''TxROM''' refers to cartridge boards made by Nintendo that use the [[MMC3|Nintendo MMC3]] mapper.<br />
<br />
== Board Types ==<br />
The following TxROM boards are known to exist:<br />
{| class="tabular"<br />
! Board || PRG ROM || PRG RAM || CHR || Comments<br />
|-<br />
| TBROM || 64 KB || || 16 / 32 / 64 KB ROM ||<br />
|-<br />
| TEROM || 32 KB || || 16 / 32 / 64 KB ROM || Supports fixed mirroring<br />
|-<br />
| TFROM || 128 / 256 / 512 KB || || 16 / 32 / 64 KB ROM || Supports fixed mirroring<br />
|-<br />
| TGROM || 128 / 256 / 512 KB || || 8 KB RAM/ROM || <br />
|-<br />
| TKROM || 128 / 256 / 512 KB || 8 KB || 128 / 256 KB ROM || <br />
|-<br />
| [http://forums.nesdev.org/viewtopic.php?f=9&t=9891 TK1ROM] || 128 KB || 8KB || 128KB ROM || Uses [[7432]] for 28-pin CHR ROM<br />
|-<br />
| [[TKSROM]] || 128 / 256 / 512 KB || 8 KB || 128 KB ROM || Alternate mirroring control, Famicom only<br />
|-<br />
| TLROM || 128 / 256 / 512 KB || || 128 / 256 KB ROM || <br />
|-<br />
| TL1ROM || 128 KB || || 128 KB || Uses [[7432]] for 28-pin CHR ROM<br />
|-<br />
| TL2ROM || || || || Nonstandard pinout<br />
|-<br />
| [https://forums.nesdev.org/viewtopic.php?p=228322#p228322 TLBROM] || 128 KB || || 128 KB ROM || Uses 74541 to compensate for too-slow CHR ROM<br />
|-<br />
| [[TLSROM]] || 128 / 256 / 512 KB || || 128 KB ROM || Alternate mirroring control<br />
|-<br />
| TNROM || 128 / 256, 512 KB || 8 KB || 8 KB RAM/ROM || Famicom only<br />
|-<br />
| [[TQROM]] || 128 KB || || 16 / 32 / 64 KB ROM + 8 KB RAM || <br />
|-<br />
| [http://bootgod.dyndns.org:7777/profile.php?id=2890 TR1ROM] || 128 / 256 / 512 KB || || 64 KB ROM + 4 KB VRAM (4-screen [[Mirroring]]) || NES only<br />
|-<br />
| TSROM || 128 / 256 / 512 KB || 8 KB (no battery) || 128 / 256 KB ROM || <br />
|-<br />
| [http://bootgod.dyndns.org:7777/profile.php?id=137 TVROM] || 64 KB || || 16 / 32 / 64 KB ROM + 4 KB VRAM (4-screen [[Mirroring]]) || NES only<br />
|}<br />
<br />
== Solder pad config ==<br />
=== [[iNES Mapper 206|Namco 108]] backwards compatibility (TEROM and TFROM)===<br />
* Normal mode: 'CL1' connected, 'CL2' connected, 'H' disconnected, 'V' disconnected.<br />
* Backwards compatible with horizontal [[mirroring]]: 'CL1' disconnected, 'CL2' disconnected, 'H' disconnected, 'V' connected<br />
* Backwards compatible with vertical mirroring: 'CL1' disconnected, 'CL2' disconnected, 'H' connected, 'V' disconnected<br />
<br />
Connecting 'CL1' enables MMC3-controlled mirroring, while connecting 'CL2' enables IRQs.<br />
However, the additional bankswitching modes available by the MMC3 that weren't available with the Namco chip used on DEROM boards are still present and activated by bits 7-6 of port $8000.<br />
<br />
=== Battery retention (TNROM, TKROM and TKSROM) ===<br />
<br />
* PRG RAM retaining data: 'SL' disconnected, Battery, D1, D2, R1 R2 and R3 present.<br />
* PRG RAM not retaining data: 'SL' connected, leave slots for Battery, D1, D2, R1, R2 and R3 free.<br />
<br />
== Various notes ==<br />
<br />
Boards with 4-screen mirroring uses a 8 KB SRAM chip, but only 4 KB is actually used. The 2 KB VRAM inside of the console is always disabled, and the CIRAM A10 pin of the MMC3 doesn't go to anything.<br />
<br />
TLSROM and TKSROM boards have different mirroring control than other MMC3 boards. The mirroring is controlled directly by MMC3's CHR A17 line, and MMC3's CIRAM A10 pin doesn't go to anything. Due to their incompatibility with other MMC3 boards on a software viewpoint, they are assigned to [[INES Mapper 118]] instead of mapper 4.<br />
<br />
TQROM board has both CHR ROM and RAM. Bit 6 of the bank number, which appears on MMC3's CHR A16 line, controls whenever CHR RAM or CHR-ROM is enabled. A [[74HC32]] chip is used to combine this with other chip enable signals for the CHR-ROM and the CHR-RAM chips. Due to this incompatibility with the other MMC3 boards on a software viewpoint, this board is assigned to [[INES Mapper 119]] instead of mapper 4.</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:List_of_games_with_significant_regional_differences&diff=14256Talk:List of games with significant regional differences2018-10-31T07:49:57Z<p>Bregalad: /* So guys... */ new section</p>
<hr />
<div>Are we also going to put here games like:<br />
* Doki Doki Yuuenchi (J) / Trolls In Crazyland (E)<br />
* Hebereke (J) / Ufouria (E)<br />
* Wanpaku Kokkun no Gourmet World (J) / Panic Restaurant (E)<br />
<br />
and many more, which differ with changed sprites of main character and also many more?<br />
<br />
== So guys... ==<br />
<br />
This list is a complete mess. It should list individually games that adjusted the gameplay speed and music from those where there is ACTUAL significant regional differences, such as Castlevania games where the japanese version is COMPLETELY different from the western versions.<br />
<br />
Then the differences should be listed such as: Adjusted difficulty, fixed bugs, etc, etc... Actually I think the NES/FC games where there's no noticeable differences between regions are in minority. ESPECIALLY if adjusting the music or gameplay speed for PAL counts as a "difference".<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:49, 31 October 2018 (MDT)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=MMC5&diff=6709MMC52018-10-19T09:25:57Z<p>Bregalad: /* Nametable mapping ($5105) */ Remove less relevant examples, also use the term "single-screen" instead of "1-screen" in order to be coherent with the mirroring page.</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 />
|prgmax=1024K<br />
|prgpage=8K, 16K, or 32K<br />
|wrammax=64K<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]]<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 64KB of WRAM, mappable not only at $6000-$7FFF but also within $8000-$DFFF<br />
* An 8 bit by 8 bit multiplier with a 16 bit result for performing quick calculations<br />
* A scanline based IRQ counter<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 />
<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 />
=== 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 ===<br />
<br />
==== PRG RAM bank ($5113) ====<br />
7 bit 0<br />
---- ----<br />
xxxx xCBB<br />
|||<br />
|++- Select 8KB PRG RAM bank at $6000-$7FFF<br />
+--- Select PRG RAM chip<br />
<br />
The MMC5 supports 2 PRG RAM chips, each up to 32KB in length. Either or both 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 WRAM are known to exist in ExROM games:<br />
* 0KB: No chips<br />
* 8KB: 1x 8KB chip<br />
* 16KB: 2x 8KB chip<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 />
No ExROM game is known to write PRG RAM with one bank value and then attempt to read back the same data with a 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.<br />
<br />
''Uncharted Waters'' requires PRG-RAM banking.<br />
<br />
==== PRG bank 0 ($5114) ====<br />
7 bit 0<br />
---- ----<br />
RBBB BBBB<br />
|||| ||||<br />
|+++-++++- Bank number<br />
+--------- RAM/ROM toggle (0: RAM; 1: ROM)<br />
<br />
* Mode 0 - Ignored<br />
* Mode 1 - Ignored<br />
* Mode 2 - Ignored<br />
* Mode 3 - Select an 8KB PRG bank at $8000-$9FFF<br />
<br />
When selecting a RAM bank, treat bank bits as indicated for the PRG RAM bank register at $5113.<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 />
<br />
==== PRG bank 1 ($5115) ====<br />
7 bit 0<br />
---- ----<br />
RBBB BBBB<br />
|||| ||||<br />
|+++-++++- Bank number<br />
+--------- RAM/ROM toggle (0: RAM; 1: ROM)<br />
<br />
* Mode 0 - Ignored<br />
* Mode 1 - Select a 16KB PRG bank at $8000-$BFFF (ignore bottom bit)<br />
* Mode 2 - Select a 16KB PRG bank at $8000-$BFFF (ignore bottom bit)<br />
* Mode 3 - Select an 8KB PRG bank at $A000-$BFFF<br />
<br />
When selecting a RAM bank, treat bank bits as indicated for the PRG RAM bank register at $5113.<br />
<br />
==== PRG bank 2 ($5116) ====<br />
7 bit 0<br />
---- ----<br />
RBBB BBBB<br />
|||| ||||<br />
|+++-++++- Bank number<br />
+--------- RAM/ROM toggle (0: RAM; 1: ROM)<br />
<br />
* Mode 0 - Ignored<br />
* Mode 1 - Ignored<br />
* Mode 2 - Select an 8KB PRG bank at $C000-$DFFF<br />
* Mode 3 - Select an 8KB PRG bank at $C000-$DFFF<br />
<br />
When selecting a RAM bank, treat bank bits as indicated for the PRG RAM bank register at $5113.<br />
<br />
==== PRG ROM bank 3 ($5117) ====<br />
7 bit 0<br />
---- ----<br />
xBBB BBBB<br />
||| ||||<br />
+++-++++- PRG ROM bank number<br />
<br />
* Mode 0 - Select a 32KB PRG ROM bank at $8000-$FFFF (ignore bottom 2 bits)<br />
* Mode 1 - Select a 16KB PRG ROM bank at $C000-$FFFF (ignore bottom bit)<br />
* Mode 2 - Select an 8KB PRG ROM bank at $E000-$FFFF<br />
* Mode 3 - Select an 8KB PRG ROM bank at $E000-$FFFF<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 />
=== 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]<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 />
It is not currently known how the MMC5 detects the sprite size being used by the PPU.<br />
<br />
==== CHR selects 0…11====<br />
{| class="wikitable"<br />
! !! colspan=4|PPU memory affected for each mode (see [[#CHR mode ($5101)]])<br />
|-<br />
! Write to CPU address !! 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 />
==== 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'' is the only known game to use split screen mode (during the intro, where it shows ship stats).<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, however when you scroll to 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 may only use vertical scroll values whose bottom 3 bits match the [[PPU|Nes PPU]]'s fine vertical scroll value. 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 Counter ($5203) ====<br />
All eight bits specify the scanline number to generate IRQ at<br />
<br />
==== IRQ Status ($5204, read/write) ====<br />
===== Write =====<br />
7 bit 0<br />
---- ----<br />
Exxx xxxx<br />
|<br />
+--------- IRQ Enable flag (1=IRQs enabled)<br />
<br />
===== Read =====<br />
7 bit 0<br />
---- ----<br />
SVxx xxxx MMC5A default power-on value = $00<br />
||<br />
|+-------- "In Frame" signal<br />
+--------- IRQ Pending flag<br />
<br />
When set, the "In Frame" signal specifies that the PPU is currently rendering a scanline. It also plays a role in how IRQs are generated.<br />
<br />
The IRQ Pending flag may be raised even if IRQs are disabled.<br />
<br />
Any time this register is read, the 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 />
==== CL3 / SL3 Status ($5208 read) ====<br />
7 bit 0<br />
---- ----<br />
AB00 0000<br />
||<br />
|+-------- Value of MMC5.97 pin (CL3)<br />
+--------- Value of MMC5.98 pin (SL3)<br />
<br />
This register returns the values of CL3 and SL3 from the MMC5A. There is no known effect from writing to this register. This register's read value has been shown to be unaffected by all possible input combinations of the multiplier and all possible combinations of values written to $5207 and $5208.<br />
<br />
==== 16-bit Hardware Timer with IRQ ($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 />
=== 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 ==<br />
[[File:mmc5_in_frame_status_bit.png|thumb|right|MMC5 'in frame' status bit state diagram]]<br />
Scanline detection involves monitoring the addresses read by the PPU. In the state diagram to the right, PPU /RD going low indicates a read by the PPU. M2 rising indicates a clock cycle of the CPU. A PPU address is considered "in range" if the address is in the range $2000 - $2FFF.<br />
<br />
When the MMC5 has detected that a scanline is rendering, the 'in frame' status bit gets set in register $5204 and the internal 8-bit scanline counter is incremented. Software can use this status bit as an indication of whether or not the PPU is currently rendering.<br />
<br />
It appears that all 240 rendered scanlines as well as the pre-render scanline are all detected by the MMC5. It also appears that scanlines are detected near their end (or near the start of the next scanline). See also [http://forums.nesdev.org/viewtopic.php?t=7653].<br />
<br />
The 'in frame' status bit is cleared as soon as the MMC5 no longer detects PPU rendering. This happens at the end of the last rendered scanline, and whenever the PPU is switched off (Sprite and BG rendering disabled).<br />
<br />
Note that there are side-effects to switching off the PPU mid frame. Clearing the In Frame signal effectively resets the IRQ counter as can be seen in the logic given above. Therefore, if the PPU is switched back on in the frame, the IRQ counter will begin counting from $00 again.<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 />
== Scanline-Counting IRQ Operation ==<br />
<br />
The MMC5 has an internal 8-bit incrementing scanline counter that watches the PPU as it renders, and counts each passing scanline. When the counter reaches the scanline specified by register $5203, it generates an IRQ. For example, when register $5203 is set to $04, the IRQ will occur near the start of the 5th rendered scanline.<br />
<br />
When the MMC5 detects a scanline, the following events occur:<br />
* If the 'in frame' status bit is clear, set it, reset the IRQ counter to 0, and clear the IRQ Pending flag<br />
* Otherwise, increment the IRQ counter. If it now equals the IRQ scanline specified by register $5203, raise IRQ Pending flag and generate an IRQ if enabled<br />
<br />
Note the above logic makes it impossible for an IRQ to occur when $5203 is set to $00<br />
<br />
The IRQ Pending flag is raised when the desired scanline is reached ''regardless'' of whether or not IRQs are enabled. $5204.7 can still be read as set even when IRQ Enable flag is clear. However, an actual IRQ is only sent to the CPU if both the IRQ Enable flag and IRQ Pending flag are raised.<br />
<br />
== Hardware ==<br />
<br />
The MMC5 exists in a 100-pin TQFP 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. Their differences are unknown.<br />
<br />
== See also ==<br />
* NES Mapper list by Disch [http://www.romhacking.net/documents/362/]<br />
* Nintendo MMC5 by goroh, translated by Sgt. Bowhack [http://nesdev.org/mmc5-e.txt]<br />
* Nintendo MMC5 Bankswitching by Kevin Horton [http://nesdev.org/mmc5_bank_switch.txt]</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Game_bugs&diff=3332Game bugs2018-10-19T08:42:06Z<p>Bregalad: /* "Impossible" controller input */ Remove annoying 2nd person wording.</p>
<hr />
<div>__TOC__<br />
<br />
Listed are games that have been tested on NES or Famicom hardware and verified to look wrong or odd, due to things like NES hardware limitations or programming errors. Refer to this if you're developing an emulator and find a game that looks wrong, before you look for a problem in your emulator. If you are attempting to give your emulator [[accuracy|"bug for bug" compatibility]], you'll want to make sure that these glitches (or unusual behaviors) appear the same in your emulator as they do on the NES.<br />
<br />
This is an incomplete list that concentrates on commercial games. For an overview of common compatibility problems in homebrew games, see [[Program Compatibility]].<br />
Sometimes, a bug slips into a game to make it rely on less-than-intentional features of the hardware; for those, see [[Tricky-to-emulate games]].<br />
<br />
== General bugs ==<br />
<br />
{| class="wikitable sortable"<br />
! style="width: 18%" | Game<br />
! class="unsortable" | Problem<br />
|- <br />
|''Akumajou Densetsu''|| When a door is opened/shut when the player goes through them, the screen shakes by one pixel.<br />
|- <br />
|''Akumajou Special''|| After losing at the bidirectional scroll stages, sometimes the game over screen is glitched. (Validated in the Game Center CX)<br />
|- <br />
|''Armadillo''|| The in-game status bar occasionally bumps vertically by 1 pixel. This game also often suffers from slowdown.<br />
|- <br />
|''Castlevania''|| The PRG 0 version sometimes freezes right before the Grim Reaper. (Fixed in PRG 1 and PAL)<br />
|- <br />
|''Castlevania II - Simon's Quest''|| Sometimes incorrect tiles are shown on the playfield.<br />
|- <br />
| ''Castlevania III - Dracula's Curse''||<br />
* The [[APU DMC|DMC channel]] in music sometimes mutes.<br />
* When pressing the 'B' button at the exact time that Trevor falls off a block, you hear the whip sound, but Trevor doesn't attack.<br />
|- <br />
|''Chip 'n Dale Rescue Rangers''|| After reading the intro to the last, garbage sprites will appear in the upper left (right) corner of the screen.<br />
|- <br />
|''Commando''|| There are many bugs that may look like emulator glitches but aren't.<br />
|- <br />
|''Crystalis''|| The scanline above the status bar and above text boxes looks wrong.<br />
|- <br />
|''Dizzy The Adventurer''|| Resets the sound phase every frame, causing a nasty 60hz buzz.<br />
|- <br />
|''Donald Land''|| When the player progresses too quickly by boosting off of apples, the background loads fall behind and the scroll seam becomes visible.<br />
|- <br />
|''Double Dragon''||<br />
* "Garbage sprites" (sprite 0 (for [[sprite-0 hit]]) and sprite 1) can be seen in the lower right of the game screen.<br />
** Sprite 0 consists of tile $FF (a black tile with 2x2 non-background pixels (i.e. a tile with a 2x2 "dot" in it, visually similar to &#x25A3; or &#9856;)), and the priority bit set.<br />
** Sprite 1 consists of tile $FE (a tile consisting entirely of a single non-transparent colour, often palette entry $0F but varies per stage).<br />
* The screen will sometimes shake vertically on heavy sprite usage.<br />
|- <br />
|''Double Dragon II''|| The status bar may suddenly change colors: sometimes when scrolling vertically it shows incorrectly for a couple of frames.<br />
|- <br />
|''Double Dragon III''|| Same status bar issue as ''Double Dragon II''.<br />
|- <br />
|''Exed Exes''|| When pausing, the immediate next note of the music will play after the pause jingle completes.<br />
|- <br />
|''Ghostbusters (J)''|| The Japanese version of Ghostbusters loads the ending text from the wrong CHR bank, causing it to display a blank screen that eventually scrolls the hiragana 'riri' on the screen.<br />
|- <br />
|''Ghosts 'n Goblins''||<br />
* Sometimes appear garbage sprites of 8x8 pixel on the in-game screen.<br />
* Sometimes it will hit the pixels that are invisible.<br />
|- <br />
|''Hebereke''||<br />
* After switching to the password screen from the title screen, and then returning to the title screen to exit from the password screen, the triangle channel is glitched.<br />
* When a player touches the HUD, it may make the HUD disappear.<br />
|- <br />
|''Hottarman no Chitei Tanken''|| If gameplay slows down due to excessive on-screen objects, scrolling may glitch and display garbage values.<br />
|- <br />
|''Ironsword: Wizards and Warriors II'' || Noise channel doesn't work properly, sometimes plays longer notes and sometimes mutes.<br />
|- <br />
|''Kirby's Adventure''|| When Kirby copies a new ability, the status bar icon may flicker or display incorrect attributes (?).<br />
|- <br />
|''Legend of Zelda''|| The screen "jumps" off 2 pixels at the start and end of vertical fast scrolling.<br />
|- <br />
|''Mega Man 3''||<br />
* On the boss select screen, the scanline above Shadow Man looks wrong.<br />
* The first scanline of the menu is glitched.<br />
|- <br />
|''Mega Man 5''|| In Gyro Man's stage, inside the two elevators, the floor moves up by a few pixels when the elevator goes up, and move back down when the screen is fast-scrolled.<br />
|-<br />
|''Micro Machines''|| Graphical problems on PPU revisions prior to 2C02G due to $2004 unreadability. Resetting on Famicom and NES-101 doesn't always work because the game fails to clear $2000 and $2001 on reset.<br />
|-<br />
|''Mitsume ga Tooru''|| Garbage data is visible in the upper side of the status bar by mistake when shaken by an earthquake, due to the status bar and playfield both sharing the nametables.<br />
|- <br />
|''Panic Restaurant''|| The in-game status bar, always bumps up by 1 pixel.<br />
|- <br />
|''Rad Racer''|| Steer to the far left, and a background scanline will be seen on the road.<br />
|-<br />
|''Rambo''||One scanline is occasionally glitched, for the same reason as in ''Super Mario Bros.''[http://forums.nesdev.org/viewtopic.php?p=154894#p154894]<br />
|-<br />
|''Rampart'' (Jaleco) || During build phase, the drums (on the noise channel) drop out fairly early.<br />
|- <br />
|''Snow Bros.''|| When you clear the stage and rise to the next floor, incorrect CHR bank switching results in glitches in the new floor's graphics.<br />
|- <br />
|''Solar Jetman'' (NTSC version) || Some songs use the sweep registers heavily, which are not restored after a sound effect plays that uses the sweep registers as well. The PAL version seems to have corrected this error.<br />
|- <br />
|''StarTropics''|| The island map music (NSF track 1) has a problem with the second square channel: it is intermittently silent or playing the wrong notes after the first minute or two, because the music data was not made to fit/repeat properly.<br />
|- <br />
|''Super Mario Bros.''||<br />
* The status bar shakes horizontally on heavy sprite usage and the music slows down. This can be seen especially in worlds 6-4, 7-4 and 8-4, where the large number of hammer objects created by Bowser's code causes the processing time to overshoot a frame. NMIs are disabled on entry to the NMI code and only reenabled when the CPU is "idle", thus when the overshoot occurs, the CPU "misses" a frame, causing general slowdown and status bar shakiness.<br />
* At various parts of 1-2, in certain CPU/PPU alignments, a single scanline gets glitched. This is caused by [http://forums.nesdev.org/viewtopic.php?p=112424#p112424 writing $2000 to reenable NMI at the exact end of the previous scanline], causing the PPU to begin that scanline from the first nametable instead of the second.<br />
|- <br />
|''Super Mario Bros. 3'' (U)||<br />
* The first scanline after a scroll split is glitched. This shows up as garbage above the left side of the status bar and as incorrectly scrolled lines in the "spade" (not N-spade) bonus game.<br />
* Note blocks containing items become squarer for a second while the item is popping out. (This is an artifact of the [[sprite priority]] exploit that it uses.)<br />
* If a Hammer Bros. battle ends precisely when a note is starting, the note will freeze on an incorrect duty cycle.<br />
* Big fat attribute glitch on the right side of most levels, because this game uses horizontal scrolling with horizontal [[mirroring]]. Discussed heavily.[http://forums.nesdev.org/viewtopic.php?f=10&t=7844]<br />
|- <br />
|''Teenage Mutant Ninja Turtles''|| Sprite overflow (due to large numbers of enemies) causes the status bar to flicker.<br />
|-<br />
|''The Addams Family''|| The in-game status bar occasionally bumps vertically by 1 pixel, caused by non-solid background pixels overlapping the sprite zero that is used for the status bar split.<br />
|- <br />
|''Zelda II: The Adventure of Link'' (U)||<br />
Reads from $2007 during the title screen twice, moving the background upward by 2 scanlines after the split point.<br />
|}<br />
<br />
== Reliance on power-on mapper register values ==<br />
* When powered-on with uninitialized SRAM, ''Digital Devil Story -- Megami Tensei II'' briefly flashes a "DDS II" logo from left to right before proceeding with the normal introduction. The logo's background looks garbled on real hardware as well as with most emulators because the game has not fully initialized the CHR bank select registers at that point.<br />
<br />
== Reliance on RAM values ==<br />
<br />
Several games erroneously rely on RAM areas being pre-populated with certain values at power-on, despite RAM contents not being in a consistent state on power-on. Other games rely on similar values, but in PRG-RAM (WRAM), or CHR-RAM.<br />
<br />
{| class="wikitable sortable"<br />
! style="width: 18%" | Game<br />
! class="unsortable" | Problem<br />
|-<br />
| ''Apple Town Story'' (FDS) || Uses RAM to determine what character name to default to when starting a new game; when RAM is pre-initialised to $00, the name キャシー (Cathy) will be used.<ref>http://forums.nesdev.org/viewtopic.php?p=183064#p183064</ref><br />
|-<br />
| ''Cheetahmen II'' || Suspected that certain RAM values may affect being able to reach the final two levels of the game (levels 5 and 6).<ref>http://forums.nesdev.org/viewtopic.php?p=178154#p178154</ref><br />
|-<br />
| ''Cybernoid'' || On the title screen, the default selection for the difficulty level changes based on the contents of RAM at power on. Also, the music may not start when starting a game (depending on uninitialized RAM values).<ref>http://tasvideos.org/forum/viewtopic.php?p=463659&sid=7cfe55942ee3420275d8f16b2a59770a#463659</ref><br />
|-<br />
| ''Dancing Blocks'' (Sachen) || Game will not boot when addresses $EC and $ED are both set to $FF.<ref>http://tasvideos.org/forum/viewtopic.php?p=463659&sid=7cfe55942ee3420275d8f16b2a59770a#463659</ref><br />
|-<br />
| ''F-1 Race'' (Beta Version only) || Title screen will be skipped if $6B and $70 contain non-zero values.<ref>http://forums.nesdev.org/viewtopic.php?p=178168#p178168</ref> Game blindly reads and uses values from $51, $55, $70, $A4, and $0200-02FF (via sprite DMA).<ref>http://forums.nesdev.org/viewtopic.php?p=178015#p178015</ref><br />
|-<br />
| ''Gun.Smoke'' (FDS version only)|| The music player's RAM is not cleared before starting the title screen song, resulting in a garbage first noise channel note, with random properties, if that RAM is not zero.<br />
|-<br />
| ''Huge Insect'' || Artifacts show up on the screen when nametable RAM is initialized with random values (the game only appears to initialize one of the 2 nametables).<br />
|-<br />
| ''Layla'' || The music player's RAM is not cleared before starting the title screen song, resulting in a flubbed first note, sometimes with a frequency sweep, depending on power-on RAM content.<br />
|-<br />
| ''Minna no Taabou no Nakayoshi Daisakusen'' || Requires that address $11 be initialized to the value $FF, otherwise the game will not start.<ref>http://forums.nesdev.org/viewtopic.php?p=185663#p185663</ref><br />
|-<br />
| ''Silva Saga'' || When save RAM is initialized with all 0s, the game incorrectly creates 3 blank saved games which do not work properly.<ref>https://forums.nesdev.org/viewtopic.php?f=11&t=11045</ref><br />
|-<br />
| ''Super Mario Bros'' (bootleg versions) || Relies on portions of RAM containing $00, otherwise player starts at world 0-1.<ref>http://forums.nesdev.org/viewtopic.php?p=178163#p178163</ref><br />
|-<br />
| ''Terminator 2: Judgment Day'' || The copyright screen is skipped if RAM is filled with $00 (more generally, if a high score table checksum happens to be valid).<ref>http://forums.nesdev.org/viewtopic.php?p=180752#p180752</ref><br />
|-<br />
| ''Ultima: Exodus'' || Relies on PRG-RAM contents before they're initialised; a fresh/new game may see artifacts such as shaking/wobbly text during the initial text intro screens, corruption of text intro screen fonts, and possibly audio anomalies.<ref>http://forums.nesdev.org/viewtopic.php?p=185163#p185163</ref><br />
|}<br />
<br />
== "Impossible" controller input ==<br />
<br />
Many games do weird and buggy things when button combinations that would be impossible (or at least very hard) to input on a real controller are pressed. This comprises pressing left+right and up+down simultaneously.<br />
Such impossible controller input should probably be prevented by default in an emulator, but they can be optionally allowed for those feeling experimental.<br />
* In ''Zelda II: The Adventure of Link'', Link can gain tremendous speed when pressing left+right.<br />
* In ''Tiny Toon Adventures'', the player can gain unusual speed when pressing left+right.<br />
* In ''Spy vs. Spy'', the character turns into an airplane when pressing left+right.<br />
* In ''Battletoads'', pressing up+down in the vertical tunnel level kills the player instantly. Additionally, pressing left+right causes the player to walk up/back even when in pure 2D stages, which can result in certain areas becoming impossible to complete.<br />
* In ''Mega Man 1'', ''2'', by pressing up+down at the top of a ladder, one may enter the "climbing ladder" state briefly above the top of the ladder. This allows "zipping" through walls.<br />
* In ''Panic Restaurant'', pressing up while crouching (by pressing down, thus pressing up+down simultaneously) the player character's sprite uses garbage data including the damage sprite. This does not occur if up is pressed before down; the player chef merely stands still.<br />
* In ''Teenage Mutant Ninja Turtles'', If you press the attack button while you jump while pressing up+down, the player character uses a garbage sprite, and attacks will use unusual (i.e. garbage data) hitboxes.<br />
* In ''Teenage Mutant Ninja Turtles II: The Arcade Game'', when you jump with a left or right move while pressing up+down, the player character will move in unusual directions and speeds, possibly screen-wrapping.<br />
<br />
== Overscan ugliness ==<br />
<br />
Some games display junk tiles in the [[Overscan|overscan]] area, which is usually not seen (or is at least partially obstructed) on real TV sets. Examples include the NTSC versions of ''Metal Gear'' (e.g. in the jungle area when gameplay starts) and ''Solstice'' (on the title screen).<br />
<br />
<gallery mode=packed><br />
File:metal-gear-junk-tiles.png|''Metal Gear''<br />
File:solstice-junk-tiles.png|''Solstice &ndash; The Quest for the Staff of Demnos''<br />
</gallery><br />
<br />
== References ==<br />
<references /></div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:MMC5_pinout&diff=14417Talk:MMC5 pinout2018-10-08T07:22:10Z<p>Bregalad: /* Chip pinout rotated by 45° */</p>
<hr />
<div>Will the colors still scroll in CL mode even if the pattern isn't? --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 12:52, 28 April 2013 (MDT)<br />
<br />
CL mode => PPU controls CHR A0, CHR A1, CHR A2.<br />
SL mode => MMC5 controls those lines instead (passing the signal through when vertical split is not used, with a delay).<br />
<br />
In both cases (scrolling or not), the vertical split section have the MMC5 trick the PPU by feeding name and attributes fetches with tiles from EXRAM instead of VRAM (while disabling the real VRAM). When scrolling is used as well, it just fetch from a different address for the coarse scrolling (adding a row to the fetched tile every 8 pixels), and shift the address of the CHR-ROM for fine scrolling.<br />
<br />
So, in CL mode, the MMC5 decides which tile to display while the PPU choose which line of the tile is displaying, while in SL mode the MMC5 decides everything. If ones tries to use a different fine scroll for the main area and the vertical split (EXRAM) area, then the tile themselves will scroll smoothly, but their content won't, and will stick to the main background. This will lead to a quite interesting effect !<br />
<br />
As for attributes, the MMC5 has to "guess" which attribute byte is fetched basing on the fine scrolling. If it scrolls fine in SL mode (let's assume it does) then it means the colour data is fetched form the correct place within EXRAM, so it will scroll the same way in CL mode, because the CHR-ROM is not involved in any way.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 15:35, 8 February 2014 (MST)<br />
<br />
:Yes, this is exactly what I expected it would do. Is the delay ever significant? What exactly do pins 97 and 98 do, then? Are they used for saving power or something like that? --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 01:07, 9 February 2014 (MST)<br />
<br />
== CHR enable lines...where? ==<br />
<br />
It seems like pins 29-30 would be the logical place to put them, but is that right? Where are those? Surely they're signals that the MMC5 generates? Is a /WE implemented so as to make CHR-RAM easy?[[User:Myask|Myask]] ([[User talk:Myask|talk]]) 18:52, 12 July 2016 (MDT)<br />
:I think Rockman 4 Minus Infinity, which uses MMC5 with CHR RAM, just runs /WE from the cart edge directly to the CHR RAM chip. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 20:42, 12 July 2016 (MDT)<br />
<br />
:Because the MMC5 can't do anything peculiar with its pattern table (e.g. no ROM nametables), the carts just normally connect PPU A13 to ROM /CE and PPU /RD to ROM /OE. I wouldn't be surprised if one of pin 29 or pin 30 were (PPU A13 OR PPU /RD), though, to accommodate a never-released board with a 28-pin 128 KiB mask ROM. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 22:58, 12 July 2016 (MDT)<br />
<br />
<br />
==Pin 77==<br />
Pin 77 is CPU-R/!W, no idea why somebody ommited this. --[[User:Krzysiobal|Krzysiobal]] ([[User talk:Krzysiobal|talk]]) 20:16, 4 November 2017 (MDT)<br />
<br />
== Chip pinout rotated by 45° ==<br />
<br />
No offense, but this way of representing pinout looks awful in my personal opinion.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 05:52, 5 October 2018 (MDT)<br />
: I disagree. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 10:39, 5 October 2018 (MDT)<br />
<br />
: I don't really understand the alternative you're comparing it to. Every pin needs a line to describe it. The diagonal arrangement makes it practical to give each one a horizontal line of text attached. That's impossible if two of the sides are vertical. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 00:52, 6 October 2018 (MDT)<br />
<br />
: I don't have any particular alternative in mind, but before the edit everything seemed fine to me, perhaps I'm missing something.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:22, 8 October 2018 (MDT)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:TxROM&diff=15839Talk:TxROM2018-10-08T06:31:47Z<p>Bregalad: /* TGROM / TNROM with CHR ROM? */</p>
<hr />
<div>On all the board variants tables why do we say things like:<br />
{| class="tabular"<br />
| TFROM || 128, 256, 512 KiB || || 16, 32, 64 KiB ROM || Supports fixed mirroring<br />
|}<br />
<br />
AFAIK, TFROM existed only with 128 KiB PRG and 32 or 64 KiB CHR. If the table is for reproductions, why not use a denser format? If it's to document reality, why does it say things that are untrue? Regardless, a legend at the top would be nice. Also, when I made [[JxROM]], I assumed this was documentation, not interchangeability guidelines.—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 16:06, 26 March 2013 (MDT)<br />
<br />
== TGROM / TNROM with CHR ROM? ==<br />
<br />
Is there actually a game with TGROM/TNROM and CHR-ROM? There aren't any listed in bootgod's database that I could find. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:30, 4 October 2018 (MDT)<br />
<br />
No, but there's one SNROM game with CHR-ROM, so this shows that Nintendo boards with CHR-RAM can also support CHR-ROM, even though this is rarely used because being limited to only 8k of CHR-ROM is a very strong limitation.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 00:31, 8 October 2018 (MDT)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:MMC3_pinout&diff=14344Talk:MMC3 pinout2018-10-05T11:55:13Z<p>Bregalad: /* Pinout with chip rotated 45° */ new section</p>
<hr />
<div>== Pinout with chip rotated 45° ==<br />
<br />
No offense but the pinout with the chip rotated 45° by Lidnariq in july 2002 looks awful in my personal opinion. (How could it go unnoticed by me for 6 years ?!)<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 05:55, 5 October 2018 (MDT)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:MMC5_pinout&diff=14413Talk:MMC5 pinout2018-10-05T11:52:30Z<p>Bregalad: /* Chip pinout rotated by 45° */ new section</p>
<hr />
<div>Will the colors still scroll in CL mode even if the pattern isn't? --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 12:52, 28 April 2013 (MDT)<br />
<br />
CL mode => PPU controls CHR A0, CHR A1, CHR A2.<br />
SL mode => MMC5 controls those lines instead (passing the signal through when vertical split is not used, with a delay).<br />
<br />
In both cases (scrolling or not), the vertical split section have the MMC5 trick the PPU by feeding name and attributes fetches with tiles from EXRAM instead of VRAM (while disabling the real VRAM). When scrolling is used as well, it just fetch from a different address for the coarse scrolling (adding a row to the fetched tile every 8 pixels), and shift the address of the CHR-ROM for fine scrolling.<br />
<br />
So, in CL mode, the MMC5 decides which tile to display while the PPU choose which line of the tile is displaying, while in SL mode the MMC5 decides everything. If ones tries to use a different fine scroll for the main area and the vertical split (EXRAM) area, then the tile themselves will scroll smoothly, but their content won't, and will stick to the main background. This will lead to a quite interesting effect !<br />
<br />
As for attributes, the MMC5 has to "guess" which attribute byte is fetched basing on the fine scrolling. If it scrolls fine in SL mode (let's assume it does) then it means the colour data is fetched form the correct place within EXRAM, so it will scroll the same way in CL mode, because the CHR-ROM is not involved in any way.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 15:35, 8 February 2014 (MST)<br />
<br />
:Yes, this is exactly what I expected it would do. Is the delay ever significant? What exactly do pins 97 and 98 do, then? Are they used for saving power or something like that? --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 01:07, 9 February 2014 (MST)<br />
<br />
== CHR enable lines...where? ==<br />
<br />
It seems like pins 29-30 would be the logical place to put them, but is that right? Where are those? Surely they're signals that the MMC5 generates? Is a /WE implemented so as to make CHR-RAM easy?[[User:Myask|Myask]] ([[User talk:Myask|talk]]) 18:52, 12 July 2016 (MDT)<br />
:I think Rockman 4 Minus Infinity, which uses MMC5 with CHR RAM, just runs /WE from the cart edge directly to the CHR RAM chip. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 20:42, 12 July 2016 (MDT)<br />
<br />
:Because the MMC5 can't do anything peculiar with its pattern table (e.g. no ROM nametables), the carts just normally connect PPU A13 to ROM /CE and PPU /RD to ROM /OE. I wouldn't be surprised if one of pin 29 or pin 30 were (PPU A13 OR PPU /RD), though, to accommodate a never-released board with a 28-pin 128 KiB mask ROM. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 22:58, 12 July 2016 (MDT)<br />
<br />
<br />
==Pin 77==<br />
Pin 77 is CPU-R/!W, no idea why somebody ommited this. --[[User:Krzysiobal|Krzysiobal]] ([[User talk:Krzysiobal|talk]]) 20:16, 4 November 2017 (MDT)<br />
<br />
== Chip pinout rotated by 45° ==<br />
<br />
No offense, but this way of representing pinout looks awful in my personal opinion.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 05:52, 5 October 2018 (MDT)</div>Bregaladhttps://www.nesdev.org/w/index.php?title=Talk:MMC1&diff=14285Talk:MMC12018-10-03T13:03:15Z<p>Bregalad: /* SXROM Heuristics */</p>
<hr />
<div>== SOROM, SUROM, and SXROM ==<br />
<br />
I'm a little fuzzy about why these are considered different [[NES 2.0 submappers]]. The functionality of all three of these looks the same to me if the extra banking bits become useless/mirror when the ROM/RAM addressed is a smaller size (just like in any other mapper supporting various sizes).<br />
<br />
43210<br />
+---+<br />
PSSxC<br />
<br />
4:P - A18 of 512k PRG ROM, disconnected if smaller<br />
3:S - A13 of 16k PRG RAM, disconnected if smaller<br />
2:S - A14 of 32k PRG RAM, disconnected if smaller<br />
1:x - unused<br />
0:C - 4k CHR banking control<br />
<br />
What am I missing? I can't spot the incompatibility that necessitated three submappers. Isn't this just one mapper together? - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 00:58, 8 August 2015 (MDT)<br />
<br />
Just my $2, but I fully agree with Rainwarrior.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 02:28, 9 August 2015 (MDT)<br />
<br />
:Yeah, tepples confirmed it in a discussion elsewhere (and lidnariq seemed to confirm it in an oblique way?). I've already put this information to use in the description at [[NES 2.0 submappers#001: MMC1]] anyway. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 11:58, 9 August 2015 (MDT)<br />
<br />
: The only issue I see is that people seem to like thinking of the two PRG-RAM banking bits in order, which would pose a problem if exchanging SXROM save RAM images is desired. On the other hand, this is a much more elegant way to handle it, so it sgtm. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 00:09, 10 August 2015 (MDT)<br />
<br />
:: Actually, thinking about this for a moment, this is a far better explanation of why I think we don't need a submapper for SUROM/SXROM/SOROM, by parsing the bits as follows:<br />
43210<br />
+---+<br />
EDCBA<br />
<br />
4:E - CHR A16, if extant; PRG ROM A18, if extant<br />
3:D - CHR A15, if extant; PRG RAM A13, if extant<br />
2:C - CHR A14, if extant; PRG RAM A14, if extant<br />
1:B - CHR A13, if extant<br />
0:A - CHR A12<br />
—[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 12:39, 11 August 2015 (MDT)<br />
<br />
== SXROM Heuristics ==<br />
<br />
Should the section on SOROM/SUROM/SXROM be modified because the amount of PRG-ROM in SXROM need not be "large", as shown with Dezaemon (128K)? [[User:Great Hierophant|Great Hierophant]] ([[User talk:Great Hierophant|talk]]) 19:41, 1 Oct 2018 (MDT)<br />
<br />
: Yes, it should. Actually this entire paragraph is wrong, because determining SUROM from other MMC1-based configuration is not problematic; just using the good old iNES header marked with 32 "16kb PRG-ROM banks" is enough to detect SUROM; there is nothing problematic. The only problematic thing is accounting for larger RAM (16k or 32k; SOROM or SXROM) because in the original iNES header there's no way to indicate a larger RAM. NES 2.0 header solves this, therefore submapper is unnecessary but a NES 2.0 header is necessary. For games using the old iNES header, the only choice is to either detect games based on CRC (bad approach) or to assume there's always 32kb if no save file is already present; and write only the banks that were actually used to the save file.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 00:42, 2 October 2018 (MDT)<br />
<br />
: The only place the distinction matters is the recommendation of emulating SNROM-style PRG RAM protection with small PRG and CHR. The only other place large PRG matters is for allowing the same bit to control selecting between 256 KiB outer banks, which is a no-op if there aren't multiple 256 KiB outer banks. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 00:54, 2 October 2018 (MDT)<br />
<br />
: I completely forgot about SNROM-style PRG RAM protection. I still think it should be handled individually, i.e. if PRG-ROM < 256k and CHR-RAM is used then this protection is activated, this does not require heuristics nor a NES 2.0 header.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 01:20, 2 October 2018 (MDT)<br />
<br />
:: I think that whole "heuristic" segment should be axed. The only iNES 2 thing is PRG-RAM size, and even that's not much of an issue. The organization got muddled, ending up in an iNES 2 category because the succinct combined implementation was a reaction to Kevtris' redundant submapper allocations. All this stuff about "8k of hard drive space" etc. seems like extra confusion of the issue, TBH. -[[User:Rainwarrior|Rainwarrior]] 14:18, 2 October 2018 (MDT)<br />
<br />
:: I more or less just removed that whole section, and removed the reference to iNES 2 except for PRG-RAM size. I tried to look over the heuristic formula to see if anything was worth keeping in it, but I didn't find anything in there that didn't seem redundant or unimportant to the more succinct combined register description. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 15:00, 2 October 2018 (MDT)<br />
<br />
:: You did exactly the right thing IMO.[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 07:03, 3 October 2018 (MDT)</div>Bregalad