VRC6: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
(merging mapper 24/26 reduntant material here for redirect)
(A #053330 VRC6 (harvested from a Madara cartridge) has been decapped and revealed to be an SLA7340 CMOS gate array, very similar to the NEC MMC3B/MMC3C)
 
(56 intermediate revisions by 9 users not shown)
Line 1: Line 1:
[[Category:ASIC mappers]][[Category:Mappers with ROM nametables]]
{{Infobox_iNES_mapper
|name=VRC6
|company=Konami
|mapper=24
|nescartdbgames=3
|othermappers=[[iNES Mapper 026|026]]
|complexity=ASIC
|boards=351951, 351949A
|pinout=VRC6 pinout
|prgmax=256K
|prgpage=16K + 8K
|wrammax=8K
|wrampage=8K
|chrmax=256K
|chrpage=1K
|mirroring=H, V, or 1, switchable
|busconflicts=No
|irq=Yes
|audio=[[VRC6_audio|Yes]]
}}
[[Category:ASIC mappers]][[Category:Mappers with ROM nametables]][[Category:Mappers with cycle IRQs]][[Category:Mappers with single-screen mirroring]]
The Konami's '''VRC6''' [[:Category:ASIC mappers|ASIC]] [[MMC|mapper]] comes in two variants:
The Konami's '''VRC6''' [[:Category:ASIC mappers|ASIC]] [[MMC|mapper]] comes in two variants:
# '''iNES Mapper 024''' used for ''Akumajou Densetsu'' (Konami PCB '''351951''').
* '''VRC6a''' - '''iNES Mapper 024''' used for ''Akumajou Densetsu'' (Konami PCB 351951).
# '''iNES Mapper 026''' used for ''Madara'' and ''Esper Dream 2'' (Konami PCB '''351949A''').
* '''VRC6b''' - '''iNES Mapper 026''' used for ''Madara'' and ''Esper Dream 2'' (Konami PCB 351949A).


The difference between the two variants switches the A0 and A1 lines. The registers described on this page are for mapper 24, but for mapper 26 the register addresses must be adjusted ($x001 becomes $x002 and vice versa).
The difference between the two variants switches the A0 and A1 lines. The registers described on this page are for mapper 24, but for mapper 26 the register addresses must be adjusted ($x001 becomes $x002 and vice versa).
See [[VRC6 pinout]] for chip pinout.




__TOC__
__TOC__


== Banks ==
=== CPU ===
* $6000-$7FFF: 8 KB PRG-RAM bank, fixed
* $8000-$BFFF: 16 KB switchable PRG ROM bank
* $C000-$DFFF: 8 KB switchable PRG ROM bank
* $E000-$FFFF: 8 KB PRG ROM bank, fixed to the last bank


== Overview ==
=== PPU ===
* PRG ROM size: Up to 256 KB
* $0000-$03FF: 1 KB switchable CHR ROM bank
* PRG ROM bank size: 16 KB at $8000, 8 KB at $C000
* $0400-$07FF: 1 KB switchable CHR ROM bank
* PRG RAM: Up to 8 KB
* $0800-$0BFF: 1 KB switchable CHR ROM bank
* CHR capacity: Up to 256 KB ROM
* $0C00-$0FFF: 1 KB switchable CHR ROM bank
* CHR bank size: 1 KB
* $1000-$13FF: 1 KB switchable CHR ROM bank
* Nametable [[mirroring]]: Controlled by mapper
* $1400-$17FF: 1 KB switchable CHR ROM bank
* Subject to [[bus conflict]]s: No
* $1800-$1BFF: 1 KB switchable CHR ROM bank
 
* $1C00-$1FFF: 1 KB switchable CHR ROM bank
See [[VRC6 pinout]] for chip pinout.


== Registers ==
== Registers ==


Only address lines 0, 1, and 12-15 are used for registers, therefore mirrors can be found by ANDing the address with $F003 ($DE6A mirrors $D002)
Only address lines 0, 1, and 12-15 are used for registers, therefore mirrors can be found by ANDing the address with $F003 ($DE6A mirrors $D002)
The addresses described here are for mapper 24. The registers for mapper 26 can be found by swapping bits 0 and 1 of the address.
    variant  lines    registers                      Mapper Number
    =================================================================
    VRC6a:    A0, A1    $x000, $x001, $x002, $x003      024
    VRC6b:    A1, A0    $x000, $x002, $x001, $x003      026


=== 16k PRG Select ($8000-$8003) ===
=== 16k PRG Select ($8000-$8003) ===
Line 31: Line 65:
  .... PPPP
  .... PPPP
       ||||
       ||||
       ++++- Select 16 KB PRG ROM at $8000
       ++++- Select 16 KB PRG ROM bank at $8000-$BFFF


=== 8k PRG Select ($C000-$C003) ===
=== 8k PRG Select ($C000-$C003) ===
Line 39: Line 73:
  ...P PPPP
  ...P PPPP
     | ||||
     | ||||
     +-++++- Select 8 KB PRG ROM at $C000
     +-++++- Select 8 KB PRG ROM bank at $C000-$DFFF


=== PPU Banking Style ($B003) ===
=== PPU Banking Style ($B003) ===
Line 53: Line 87:
  +--------- PRG RAM enable
  +--------- PRG RAM enable


The VRC6 supports the use of a larger RAM to provide more nametables. However, no games used any more than the two from the Famicom's built-in CIRAM, nor ever use ROM nametables. As a result, the commercial games seen only ever write the values $20, $24, $28, $2C, $A0, $A4, $A8, and $AC to this register.
The VRC6 supports the use of a larger RAM to provide more nametables. However, the three commercial VRC6 games neither provided extra nametable RAM, nor used ROM nametables. As a result these games only ever write the values $20, $24, $28, $2C, $A0, $A4, $A8, and $AC to this register.
 
CIRAM A10 is always connected to CHR A10, and bit 5 affects the behaviour of this signal (see below for details). The commercial games always left this bit set.


=== CHR Select 0…7 ($Dxxx, $Exxx) ===
=== CHR Select 0…7 ($Dxxx, $Exxx) ===
Line 61: Line 97:
The lower 3 bits of the $B003 register affect where the registers are used:
The lower 3 bits of the $B003 register affect where the registers are used:
{| class="wikitable"
{| class="wikitable"
! [$B003] & 7 → !! style="width:2em;"|0 !! style="width:2em;"|4 !! 1 or 5 !! 2 or 3 !! 6 or 7
! [$B003] & $03 → !! style="width:2em;"|0 !! style="width:2em;"|1 !! 2 or 3
|-
|-
! PPU bank !! colspan=5|Register used
! CHR bank !! colspan=3|Register used
|-
|-
| $0000-$03FF || R0 || R0 || rowspan=2|R0 || R0 || R0
| $0000-$03FF || R0 || rowspan=2|R0 || R0
|-
|-
| $0400-$07FF || R1 || R1 || R1 || R1
| $0400-$07FF || R1 || R1
|-
|-
| $0800-$0BFF || R2 || R2 || rowspan=2|R1 || R2 || R2
| $0800-$0BFF || R2 || rowspan=2|R1 || R2
|-
|-
| $0C00-$0FFF || R3 || R3 || R3 || R3
| $0C00-$0FFF || R3 || R3
|-
|-
| $1000-$13FF || R4 || R4 || rowspan=2|R2 || rowspan=2|R4 || rowspan=2|R4
| $1000-$13FF || R4 || rowspan=2|R2 || rowspan=2|R4
|-
|-
| $1400-$17FF || R5 || R5
| $1400-$17FF || R5
|-
|-
| $1800-$1BFF || R6 || R6 || rowspan=2|R3 || rowspan=2|R5 || rowspan=2|R5
| $1800-$1BFF || R6 || rowspan=2|R3 || rowspan=2|R5
|-
|-
| $1C00-$1FFF || R7 || R7
| $1C00-$1FFF || R7
|}
 
{| class="wikitable"
! [$B003] & $07 → !! 0, 6, or 7 !! style="width:4em;"|1 or 5 !! 2, 3, or 4
|-
|-
| $2000-$23FF || R6 || R6 || R4 || R6 || R6
! Nametable bank !! colspan=3|Register used
|-
|-
| $2400-$27FF || R6 || R7 || R5 || R7 || R6
| $2000-$23FF || R6 || R4 || R6
|-
|-
| $2800-$2BFF || R7 || R6 || R6 || R6 || R7
| $2400-$27FF || R6 || R5 || R7
|-
|-
| $2C00-$2FFF || R7 || R7 || R7 || R7 || R7
| $2800-$2BFF || R7 || R6 || R6
|-
| $2C00-$2FFF || R7 || R7 || R7
|}
|}


For the pattern tables, when the $20s bit of $B003 is set, 2 KiB banks pass
When bit 5 of $B003 is clear, CHR/CIRAM A10 will be controlled directly by the register LSB, causing 2 KiB banks to have duplicate 1 KiB halves.
PPU A10 through (limiting the register to seven bits wide by ignoring the LSB).
Existing Konami games did not use this configuration. This was intended for a different PCB (never used) where PPU A10 directly controls CHR A10 instead, permitting 512 KiB of CHR-ROM.
 
When bit 5 of $B003 is set, 2 KiB pattern table banks pass PPU A10 through (ignoring the LSB of the register). Nametables apply different rules at the same time: see below.
 
==== Mirroring ====
 
With $B003:5 set, there are four different modes corresponding to $B003 & 3 that each have 4 nametable mirroring settings. Only mode 0 was used by Konami's commercial games.
 
===== Mode 0 =====


For the nametables, if the $20s bit of $B003 is set and the
lower 4 bits of $B003 have one of the following values, CHR A10 is replaced:
{| class="wikitable"
{| class="wikitable"
! [$B003] & 15 !! CHR A10
! [$B003] & $F !! $0 !!  $4 !!  $8 !!  $C
|-
|-
| 0 or 7 || PPU A10 ("vertical mirroring")
! Mirroring
| vertical || horizontal || 1-screen A || 1-screen B
|-
|-
| 4 or 3 || PPU A11 ("horizontal mirroring")
! CIRAM A10
| PPU A10  || PPU A11   || Ground (0) || Vcc (1)
|}
 
This mode was not intended for use with ROM nametables ($B003:4 set), because it overrides the LSB of the nametable registers with the signal intended for CIRAM A10.
Because R6 and R7 are already in use to control the pattern banks, this is not very suitable if combined with ROM nametables ([[#Mode 3|Mode 3]] is designed for that instead).
 
{| class="wikitable"
! [$B003] & $F !!  $0 !!  $4 !!  $8 !!  $C
|-
! Mirroring
| horizontal pairs<br/> 2 KiB spread || vertical pairs<br/> 2 KiB spread || horizontal mirroring<br/> 1 KiB (even only) || vertical mirroring<br/> 1 KiB (odd only)
|-
! $2000-$23FF
| R6 even || R6 even || R6 even || R6 odd
|-
! $2400-$27FF
| R6 odd  || R7 even || R6 even || R7 odd
|-
! $2800-$2BFF
| R7 even || R6 odd  || R7 even || R6 odd
|-
! $2C00-$2FFF
| R7 odd  || R7 odd  || R7 even || R7 odd
|-
|-
| 8 or 15 || Ground
! Mode 3 equivalent
| $7 || $3 || $F || $B
|}
 
===== Mode 1 =====
Mode 1 uses R4-R7 to directly control 4-screen mapping. This is very effective with ROM nametables ($B003:4 set), but the LSB of each register still applies when using CIRAM.
 
{| class="wikitable"
! [$B003] & $F !!  $1 !!  $5 !!  $9 !!  $D
|-
|-
| 12 or 11 || Vcc
! Mirroring
| colspan=4|4-screen
|-
|-
| all other values || not replaced
! $2000-$23FF
| colspan=4|R4
|-
! $2400-$27FF
| colspan=4|R5
|-
! $2800-$2BFF
| colspan=4|R6
|-
! $2C00-$2FFF
| colspan=4|R7
|}
|}


If the $20s bit is clear, in both the pattern and name tables, the full
===== Mode 2 =====
eight-bit value from the register is used, even if this causes duplication. If these modes had ever been used, we assume Konami would have connected PPU A10 to the CHR ROM manually.
Mode 2 uses R6-R7 to select two ROM pages for horizontal or vertical mirroring. If using CIRAM, the LSB of each register applies.
 
{| class="wikitable"
! [$B003] & $F !!  $2 !!  $6 !!  $A !!  $E
|-
! Mirroring
| vertical || horizontal || vertical || horizontal
|-
! $2000-$23FF
| R6 || R6 || R6 || R6
|-
! $2400-$27FF
| R7 || R6 || R7 || R6
|-
! $2800-$2BFF
| R6 || R7 || R6 || R7
|-
! $2C00-$2FFF
| R7 || R7 || R7 || R7
|}
 
===== Mode 3 =====
 
This mode is intended for ROM nametables ($B003:4 set) but the nametable banking is extended to 2 KiB pages by forcing the LSB as a 0 (even) or 1 (odd) in different configurations.
 
This can be used to spread 2 adjacent ROM pages each across a pair of nametables.
{| class="wikitable"
! [$B003] & $F !!  $3 !!  $7 !!  $B !!  $F
|-
! Mirroring
| vertical pairs<br/> 2 KiB spread || horizontal pairs<br/> 2 KiB spread || vertical mirroring<br/> 1 KiB (odd only) || horizontal mirroring<br/> 1 KiB (even only)
|-
! $2000-$23FF
| R6 even || R6 even || R6 odd || R6 even
|-
! $2400-$27FF
| R7 even || R6 odd  || R7 odd || R6 even
|-
! $2800-$2BFF
| R6 odd  || R7 even || R6 odd || R7 even
|-
! $2C00-$2FFF
| R7 odd  || R7 odd  || R7 odd || R7 even
|-
! Mode 0 equivalent
| $4 || $0 || $C || $8
|}
 
The nametable configurations are redundant with [[#Mode 0|Mode 0]], but in a different order; however, the reuse of R6 and R7 as pattern banks makes mode 0 ineffective for ROM nametables.
 
===== Other =====
 
With $B003:5 clear, CHR/CIRAM A10 always directly uses the LSB of the register used to map that range, rather than having it overridden for mirroring control. (See nametable bank table above.)
 
This setting was intended to be used with a different PCB that would have connected PPU A10 directly to CHR A10, enabling 512 KiB CHR-ROM (with mode 1 having 2 KiB banks).
The actual behaviour here is a leftover consequence of being run on the wrong board:
 
{| class="wikitable"
! [$B003] & $F !! $0 !! $1 !! $2 !! $3 !! $4 !! $5 !! $6 !! $7 !! $8 !! $9 !! $A !! $B !! $C !! $D !! $E !! $F
|-
! Mirroring
| H  || 4  || colspan=3|V    || 4  || colspan=3|H    || 4  || colspan=3|V    || 4  || colspan=2|H
|-
! $2000-$23FF
| R6 || R4 || R6 || R6 || R6 || R4 || R6 || R6 || R6 || R4 || R6 || R6 || R6 || R4 || R6 || R6
|-
! $2400-$27FF
| R6 || R5 || R7 || R7 || R7 || R5 || R6 || R6 || R6 || R5 || R7 || R7 || R7 || R5 || R6 || R6
|-
! $2800-$2BFF
| R7 || R6 || R6 || R6 || R6 || R6 || R7 || R7 || R7 || R6 || R6 || R6 || R6 || R6 || R7 || R7
|-
! $2C00-$2FFF
| R7 || R7 || R7 || R7 || R7 || R7 || R7 || R7 || R7 || R7 || R7 || R7 || R7 || R7 || R7 || R7
|}
 
Using ROM nametables on the hypothetical board mentioned above would transform all of the "H" layouts into "horizontal pairs 2 KiB spread", and all of the "V" and "4" layouts would have disjoint 256 KiB halves for the left two and right two nametables.


=== IRQ control ($F00x) ===
=== IRQ control ($F00x) ===


$F000:  IRQ Latch
For details on IRQ operation, see [[VRC IRQ]]s. Many VRC mappers use the same IRQ system.
$F001:  IRQ Control
$F002:  IRQ Acknowledge


Many VRC mappers use the same IRQ systemFor details on IRQ operation, see [[VRC_irq|VRC IRQs]].
The VRC6 IRQ can be used to count either CPU cycles, or scanlines as a multiple of CPU cycles.
 
        7  bit  0
        ---------
$F000: LLLL LLLL - IRQ Latch
$F001: .... .MEA - IRQ Control
  $F002: .... .... - IRQ Acknowledge
 
*L - reload value for latch
*M - mode (1=cycle, 0=scanline)
*E - enable IRQ
*A - acknowledge bit


=== Sound ($900x, $A00x, $B000-$B002) ===
=== Sound ($900x, $A00x, $B000-$B002) ===
Line 124: Line 300:
For details on sound information, see [[VRC6_audio|VRC6 audio]].
For details on sound information, see [[VRC6_audio|VRC6 audio]].


== Disch's notes ==
== Revisions ==
TODO: incorporate any missing information into the article above, then remove these notes.
Three revisions of the VRC6 chip are known to exist:
  ========================
* 053328 - pin 1 is GND
  =  Mapper 024          =
* 053329 - pin 1 appears to be an input
  =      + 026          =
* 053330 - based on the SLA7340 CMOS gate array, pin 1 is GND
  ========================
 
  aka
  --------------------------
  VRC6
 
 
 
  Example Games:
  --------------------------
  Akumajou Densetsu        (024)
  Madara                  (026)
  Esper Dream 2            (026)
 
 
 
  Multiple numbers, just one mapper:
  --------------------------
  As is the VRC way...  VRC6 comes in two varieties.  Both variants operate exactly the same, only the reigster
  addresses are different:
 
    variant  lines    registers                      Mapper Number
    =================================================================
    VRC6a:    A0, A1    $x000, $x001, $x002, $x003      024
    VRC6b:    A1, A0    $x000, $x002, $x001, $x003      026
 
 
 
  This doc will use the 'VRC6a' registers (0,1,2,3) in all following register descriptions.  For 'VRC6b',
  simply reverse $x001 and $x002.
 
 
  Registers:
  --------------------------
  Some registers are mirrored across several addresses.  For example, writing to $8003 has the same effect as
  writing to $8000.
 
  $8000-$8003: [PPPP PPPP]  PRG Reg 0  (Select 16k @ $8000)
  $9000-$9002:                Sound, Pulse 1  (see sound section)
  $A000-$A002:                Sound, Pulse 2
  $B000-$B002:                Sound, Sawtooth
  $B003:        [.... MM..]  Mirroring:
    %00 = Vert
    %01 = Horz
    %10 = 1ScA
    %11 = 1ScB
 
  $C000-$C003:  [PPPP PPPP]  PRG Reg 1  (Select 8k @ $C000)
  $D000-$E003:  [CCCC CCCC]  CHR regs (See CHR setup)
  $F000-$F002:                IRQ regs (See IRQ section)
 
 
  PRG Setup:
  --------------------------
 
        $8000  $A000  $C000  $E000 
      +---------------+-------+-------+
      |    $8000    | $C000 | { -1} |
      +---------------+-------+-------+
 
 
  CHR Setup:
  --------------------------
 
        $0000  $0400  $0800  $0C00  $1000  $1400  $1800  $1C00
      +-------+-------+-------+-------+-------+-------+-------+-------+
      | $D000 | $D001 | $D002 | $D003 | $E000 | $E001 | $E002 | $E003 |
      +-------+-------+-------+-------+-------+-------+-------+-------+
 
 
  IRQs:
  --------------------------
 
  VRC6 use the "VRC IRQ" setup shared by several VRCs.  It uses the following registers:
 
 
    $F000:  [IIII IIII]  IRQ Reload
    $F001:  [.... .MEA]  IRQ Control
    $F002:  [.... ....]  IRQ Acknowledge
 
  For info on how these IRQs work, see the "VRC IRQs" section in mapper 021
 
 
  ==========================
  Sound:
  --------------------------
 
  VRC6 has two additional pulse channels, and one sawtooth channel.  Both operate very similarly to the NES's
  native channels.
 
 
 
    Pulse Channels:
    ------------------------
 
  $9000, $A000:  [MDDD VVVV]
        M = Mode (0=normal mode, 1=digitized mode)
        D = Duty cycle (duty cycle is (D+1)/16)
        V = Volume
 
  $9001, $A001:  [FFFF FFFF]
        F = Low 8 bits of Frequency
 
  $9002, $A002:  [E... FFFF]
        F = High 4 bits of Frequency
        E = Channel Enable (0=disabled, 1=enabled)
 
 
  Pulse 1 uses regs $900x
  Pulse 2 uses regs $A00x
 
 
    Just like the NES's own pulse channels, an internal counter is counted down each CPU cycle, and when it
  wraps, it's reloaded with the 'F' frequency value, and the duty cycle unit takes another step.  VRC6's pulses
  can have a duty cycle anywhere between 1/16 and 8/16 depending on the given 'D' value.
 
    Channel output is either 0 or 'V', depending on the current state of the duty cycle unit (or digitized
  mode).
 
    When 'M' is set (digitized mode), the duty cycle is ignored, and 'V' is always output.  In this mode, the
  channel essentially is no longer a Pulse wave, but rather $9000/$A000 acts like a 4-bit PCM streaming
  register (similar to $4011).
 
    When 'E' is clear (channel disabled), output of the channel is forced to '0' (silencing the channel).
 
  Generated tone in Hz can be calculated by the following:
 
        CPU_CLOCK
  Hz = -------------
        (F+1) * 16
 
 
    Sawtooth Channel:
    ------------------------
 
  $B000:  [..AA AAAA]
        A = Accum Rate
 
  $B001:  [FFFF FFFF]
        F = Low 8 bits of frequency
 
  $B002:  [E... FFFF]
        F = High 4 bits of frequency
        E = Channel Enable (0=disabled, 1=enabled)
 
 
    The sawtooth uses an 8-bit accumulation register.  Every time it is clocked, 'A' is added until the 7th
  clock, at which point it is reset to 0.  The high 5 bits of this accumulation reg are then used as the
  channel output.  Strangely, though, the accumulation register seems to only be clocked once for every *two*
  times the frequency divider expires.  This results in a tone that's an octave lower than you might expect.
 
    It's difficult to put in words, so here's an example using $0B as a value for the accum rate ('A'):
 
  Step    Accum.  Channel output
  -------------------------------
  0      $00      $00
  1      $00      $00    odd steps do nothing
  2      $0B      $01    even steps.. add value of 'A' to accum
  3      $0B      $01
  4      $16      $02
  5      $16      $02
  6      $21      $04
  7      $21      $04
  8      $2C      $05
  9      $2C      $05
  10      $37      $06
  11      $37      $06
  12      $42      $08    6th and final time 'A' is added
  13      $42      $08
  0      $00      $00    7th time, accum is reset instead
                          ... and the process repeats
 
    Channel output is the high 5 bits of the accumulation reg (right shift reg by 3).  If the accum rate is too
  high, the accum reg WILL wrap at 8 bits, causing ugly distortion.  The highest accum rate you can use without
  wrapping is $2A.
 
    If 'E' is clear (channel disabled), channel output is forced to 0 (silencing the channel).
 
  Generated tone in Hz can be calculated by the following:
 
        CPU_CLOCK
  Hz = -------------
        (F+1) * 14


== References ==
== References ==
* Official VRC6 documentation: http://www.assemblergames.com/forums/showthread.php?48390-Several-Famicom%28NES%29-misc-dev-documents-from-Nintendo-and-Konami
* Official VRC6 documentation: http://www.assemblergames.com/forums/showthread.php?48390-Several-Famicom%28NES%29-misc-dev-documents-from-Nintendo-and-Konami
* Naruko's explanation of the $B003 register according to the VRC6 documentation: http://forums.nesdev.org/viewtopic.php?f=11&t=10628
* Naruko's explanation of the $B003 register according to the VRC6 documentation: http://forums.nesdev.org/viewtopic.php?f=11&t=10628
*[http://nesdev.org/vrcvi.txt VRCVI Chip Info] by Kevin Horton (audio only)
*[http://nesdev.org/vrc6-j.txt VRCVI] by goroh (sound info is inaccurate)
*[http://nesdev.org/mappers.zip Comprehensive NES Mapper Document] by \Firebug\, information about mapper's initial state is inaccurate.
*[//forums.nesdev.org/viewtopic.php?t=11028 VRC6 mirroring test ROM]

Latest revision as of 14:54, 18 July 2022

VRC6
Company Konami
Games 3 in NesCartDB
Complexity ASIC
Boards 351951, 351949A
Pinout VRC6 pinout
PRG ROM capacity 256K
PRG ROM window 16K + 8K
PRG RAM capacity 8K
PRG RAM window 8K
CHR capacity 256K
CHR window 1K
Nametable mirroring H, V, or 1, switchable
Bus conflicts No
IRQ Yes
Audio Yes
iNES mappers 024, 026

The Konami's VRC6 ASIC mapper comes in two variants:

  • VRC6a - iNES Mapper 024 used for Akumajou Densetsu (Konami PCB 351951).
  • VRC6b - iNES Mapper 026 used for Madara and Esper Dream 2 (Konami PCB 351949A).

The difference between the two variants switches the A0 and A1 lines. The registers described on this page are for mapper 24, but for mapper 26 the register addresses must be adjusted ($x001 becomes $x002 and vice versa).

See VRC6 pinout for chip pinout.


Banks

CPU

  • $6000-$7FFF: 8 KB PRG-RAM bank, fixed
  • $8000-$BFFF: 16 KB switchable PRG ROM bank
  • $C000-$DFFF: 8 KB switchable PRG ROM bank
  • $E000-$FFFF: 8 KB PRG ROM bank, fixed to the last bank

PPU

  • $0000-$03FF: 1 KB switchable CHR ROM bank
  • $0400-$07FF: 1 KB switchable CHR ROM bank
  • $0800-$0BFF: 1 KB switchable CHR ROM bank
  • $0C00-$0FFF: 1 KB switchable CHR ROM bank
  • $1000-$13FF: 1 KB switchable CHR ROM bank
  • $1400-$17FF: 1 KB switchable CHR ROM bank
  • $1800-$1BFF: 1 KB switchable CHR ROM bank
  • $1C00-$1FFF: 1 KB switchable CHR ROM bank

Registers

Only address lines 0, 1, and 12-15 are used for registers, therefore mirrors can be found by ANDing the address with $F003 ($DE6A mirrors $D002)

The addresses described here are for mapper 24. The registers for mapper 26 can be found by swapping bits 0 and 1 of the address.

    variant   lines     registers                       Mapper Number
    =================================================================
    VRC6a:    A0, A1    $x000, $x001, $x002, $x003      024
    VRC6b:    A1, A0    $x000, $x002, $x001, $x003      026

16k PRG Select ($8000-$8003)

7  bit  0
---------
.... PPPP
     ||||
     ++++- Select 16 KB PRG ROM bank at $8000-$BFFF

8k PRG Select ($C000-$C003)

7  bit  0
---------
...P PPPP
   | ||||
   +-++++- Select 8 KB PRG ROM bank at $C000-$DFFF

PPU Banking Style ($B003)

7  bit  0
---------
W.PN MMDD
| || ||||
| || ||++- PPU banking mode; see below
| || ++--- Mirroring varies by banking mode, see below
| |+------ 1: Nametables come from CHRROM, 0: Nametables come from CIRAM
| +------- CHR A10 is 1: subject to further rules 0: according to the latched value
+--------- PRG RAM enable

The VRC6 supports the use of a larger RAM to provide more nametables. However, the three commercial VRC6 games neither provided extra nametable RAM, nor used ROM nametables. As a result these games only ever write the values $20, $24, $28, $2C, $A0, $A4, $A8, and $AC to this register.

CIRAM A10 is always connected to CHR A10, and bit 5 affects the behaviour of this signal (see below for details). The commercial games always left this bit set.

CHR Select 0…7 ($Dxxx, $Exxx)

For brevity, we refer to the registers at $D000 through $D003 and $E000 through $E003 as R0 through R7.

The lower 3 bits of the $B003 register affect where the registers are used:

[$B003] & $03 → 0 1 2 or 3
CHR bank Register used
$0000-$03FF R0 R0 R0
$0400-$07FF R1 R1
$0800-$0BFF R2 R1 R2
$0C00-$0FFF R3 R3
$1000-$13FF R4 R2 R4
$1400-$17FF R5
$1800-$1BFF R6 R3 R5
$1C00-$1FFF R7
[$B003] & $07 → 0, 6, or 7 1 or 5 2, 3, or 4
Nametable bank Register used
$2000-$23FF R6 R4 R6
$2400-$27FF R6 R5 R7
$2800-$2BFF R7 R6 R6
$2C00-$2FFF R7 R7 R7

When bit 5 of $B003 is clear, CHR/CIRAM A10 will be controlled directly by the register LSB, causing 2 KiB banks to have duplicate 1 KiB halves. Existing Konami games did not use this configuration. This was intended for a different PCB (never used) where PPU A10 directly controls CHR A10 instead, permitting 512 KiB of CHR-ROM.

When bit 5 of $B003 is set, 2 KiB pattern table banks pass PPU A10 through (ignoring the LSB of the register). Nametables apply different rules at the same time: see below.

Mirroring

With $B003:5 set, there are four different modes corresponding to $B003 & 3 that each have 4 nametable mirroring settings. Only mode 0 was used by Konami's commercial games.

Mode 0
[$B003] & $F $0 $4 $8 $C
Mirroring vertical horizontal 1-screen A 1-screen B
CIRAM A10 PPU A10 PPU A11 Ground (0) Vcc (1)

This mode was not intended for use with ROM nametables ($B003:4 set), because it overrides the LSB of the nametable registers with the signal intended for CIRAM A10. Because R6 and R7 are already in use to control the pattern banks, this is not very suitable if combined with ROM nametables (Mode 3 is designed for that instead).

[$B003] & $F $0 $4 $8 $C
Mirroring horizontal pairs
2 KiB spread
vertical pairs
2 KiB spread
horizontal mirroring
1 KiB (even only)
vertical mirroring
1 KiB (odd only)
$2000-$23FF R6 even R6 even R6 even R6 odd
$2400-$27FF R6 odd R7 even R6 even R7 odd
$2800-$2BFF R7 even R6 odd R7 even R6 odd
$2C00-$2FFF R7 odd R7 odd R7 even R7 odd
Mode 3 equivalent $7 $3 $F $B
Mode 1

Mode 1 uses R4-R7 to directly control 4-screen mapping. This is very effective with ROM nametables ($B003:4 set), but the LSB of each register still applies when using CIRAM.

[$B003] & $F $1 $5 $9 $D
Mirroring 4-screen
$2000-$23FF R4
$2400-$27FF R5
$2800-$2BFF R6
$2C00-$2FFF R7
Mode 2

Mode 2 uses R6-R7 to select two ROM pages for horizontal or vertical mirroring. If using CIRAM, the LSB of each register applies.

[$B003] & $F $2 $6 $A $E
Mirroring vertical horizontal vertical horizontal
$2000-$23FF R6 R6 R6 R6
$2400-$27FF R7 R6 R7 R6
$2800-$2BFF R6 R7 R6 R7
$2C00-$2FFF R7 R7 R7 R7
Mode 3

This mode is intended for ROM nametables ($B003:4 set) but the nametable banking is extended to 2 KiB pages by forcing the LSB as a 0 (even) or 1 (odd) in different configurations.

This can be used to spread 2 adjacent ROM pages each across a pair of nametables.

[$B003] & $F $3 $7 $B $F
Mirroring vertical pairs
2 KiB spread
horizontal pairs
2 KiB spread
vertical mirroring
1 KiB (odd only)
horizontal mirroring
1 KiB (even only)
$2000-$23FF R6 even R6 even R6 odd R6 even
$2400-$27FF R7 even R6 odd R7 odd R6 even
$2800-$2BFF R6 odd R7 even R6 odd R7 even
$2C00-$2FFF R7 odd R7 odd R7 odd R7 even
Mode 0 equivalent $4 $0 $C $8

The nametable configurations are redundant with Mode 0, but in a different order; however, the reuse of R6 and R7 as pattern banks makes mode 0 ineffective for ROM nametables.

Other

With $B003:5 clear, CHR/CIRAM A10 always directly uses the LSB of the register used to map that range, rather than having it overridden for mirroring control. (See nametable bank table above.)

This setting was intended to be used with a different PCB that would have connected PPU A10 directly to CHR A10, enabling 512 KiB CHR-ROM (with mode 1 having 2 KiB banks). The actual behaviour here is a leftover consequence of being run on the wrong board:

[$B003] & $F $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $A $B $C $D $E $F
Mirroring H 4 V 4 H 4 V 4 H
$2000-$23FF R6 R4 R6 R6 R6 R4 R6 R6 R6 R4 R6 R6 R6 R4 R6 R6
$2400-$27FF R6 R5 R7 R7 R7 R5 R6 R6 R6 R5 R7 R7 R7 R5 R6 R6
$2800-$2BFF R7 R6 R6 R6 R6 R6 R7 R7 R7 R6 R6 R6 R6 R6 R7 R7
$2C00-$2FFF R7 R7 R7 R7 R7 R7 R7 R7 R7 R7 R7 R7 R7 R7 R7 R7

Using ROM nametables on the hypothetical board mentioned above would transform all of the "H" layouts into "horizontal pairs 2 KiB spread", and all of the "V" and "4" layouts would have disjoint 256 KiB halves for the left two and right two nametables.

IRQ control ($F00x)

For details on IRQ operation, see VRC IRQs. Many VRC mappers use the same IRQ system.

The VRC6 IRQ can be used to count either CPU cycles, or scanlines as a multiple of CPU cycles.

       7  bit  0
       ---------
$F000: LLLL LLLL - IRQ Latch
$F001: .... .MEA - IRQ Control
$F002: .... .... - IRQ Acknowledge
  • L - reload value for latch
  • M - mode (1=cycle, 0=scanline)
  • E - enable IRQ
  • A - acknowledge bit

Sound ($900x, $A00x, $B000-$B002)

For details on sound information, see VRC6 audio.

Revisions

Three revisions of the VRC6 chip are known to exist:

  • 053328 - pin 1 is GND
  • 053329 - pin 1 appears to be an input
  • 053330 - based on the SLA7340 CMOS gate array, pin 1 is GND

References