VRC6: Difference between revisions
(→CHR Select 0…7 ($Dxxx, $Exxx): Make the 2KiB pattern table banks more visually obvious) |
Rainwarrior (talk | contribs) (merging mapper 24/26 reduntant material here for redirect) |
||
Line 1: | Line 1: | ||
[[Category:ASIC mappers]][[Category:Mappers with ROM nametables]] | [[Category:ASIC mappers]][[Category:Mappers with ROM nametables]] | ||
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'''). | |||
# '''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). | |||
Line 119: | Line 123: | ||
For details on sound information, see [[VRC6_audio|VRC6 audio]]. | For details on sound information, see [[VRC6_audio|VRC6 audio]]. | ||
== Disch's notes == | |||
TODO: incorporate any missing information into the article above, then remove these notes. | |||
======================== | |||
= Mapper 024 = | |||
= + 026 = | |||
======================== | |||
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 |
Revision as of 13:55, 17 March 2014
The Konami's VRC6 ASIC mapper comes in two variants:
- iNES Mapper 024 used for Akumajou Densetsu (Konami PCB 351951).
- 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).
Overview
- PRG ROM size: Up to 256 KB
- PRG ROM bank size: 16 KB at $8000, 8 KB at $C000
- PRG RAM: Up to 8 KB
- CHR capacity: Up to 256 KB ROM
- CHR bank size: 1 KB
- Nametable mirroring: Controlled by mapper
- Subject to bus conflicts: No
See VRC6 pinout for chip pinout.
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)
16k PRG Select ($8000-$8003)
7 bit 0 --------- .... PPPP |||| ++++- Select 16 KB PRG ROM at $8000
8k PRG Select ($C000-$C003)
7 bit 0 --------- ...P PPPP | |||| +-++++- Select 8 KB PRG ROM at $C000
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, 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.
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] & 7 → | 0 | 4 | 1 or 5 | 2 or 3 | 6 or 7 |
---|---|---|---|---|---|
PPU bank | Register used | ||||
$0000-$03FF | R0 | R0 | R0 | R0 | R0 |
$0400-$07FF | R1 | R1 | R1 | R1 | |
$0800-$0BFF | R2 | R2 | R1 | R2 | R2 |
$0C00-$0FFF | R3 | R3 | R3 | R3 | |
$1000-$13FF | R4 | R4 | R2 | R4 | R4 |
$1400-$17FF | R5 | R5 | |||
$1800-$1BFF | R6 | R6 | R3 | R5 | R5 |
$1C00-$1FFF | R7 | R7 | |||
$2000-$23FF | R6 | R6 | R4 | R6 | R6 |
$2400-$27FF | R6 | R7 | R5 | R7 | R6 |
$2800-$2BFF | R7 | R6 | R6 | R6 | R7 |
$2C00-$2FFF | R7 | R7 | R7 | R7 | R7 |
For the pattern tables, when the $20s bit of $B003 is set, 2 KiB banks pass PPU A10 through (limiting the register to seven bits wide by ignoring the LSB).
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:
[$B003] & 15 | CHR A10 |
---|---|
0 or 7 | PPU A10 ("vertical mirroring") |
4 or 3 | PPU A11 ("horizontal mirroring") |
8 or 15 | Ground |
12 or 11 | Vcc |
all other values | not replaced |
If the $20s bit is clear, in both the pattern and name tables, the full 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.
IRQ control ($F00x)
$F000: IRQ Latch $F001: IRQ Control $F002: IRQ Acknowledge
Many VRC mappers use the same IRQ system. For details on IRQ operation, see VRC IRQs.
Sound ($900x, $A00x, $B000-$B002)
For details on sound information, see VRC6 audio.
Disch's notes
TODO: incorporate any missing information into the article above, then remove these notes.
======================== = Mapper 024 = = + 026 = ======================== 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
- 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