INES Mapper 067: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
m (add cat:cycleIRQ, DEFAULTSORT)
(→‎Registers: update per krzysiobal)
Line 24: Line 24:
== Registers ==
== Registers ==


=== CHR bank 0 ($8800) ===
=== Interrupt Acknowledge ($8000) ===
The value written here selects a 2 KiB CHR ROM bank at PPU $0000-$07FF.
Mask: $8800


=== CHR bank 1 ($9800) ===
Any write to this address or any of its mirrors acknowledges a pending IRQ.
The value written here selects a 2 KiB CHR ROM bank at PPU $0800-$0FFF.


=== CHR bank 2 ($A800) ===
=== CHR bank 0…3 ($8800..$BFFF) ===
The value written here selects a 2 KiB CHR ROM bank at PPU $1000-$17FF.
Mask: $F800


=== CHR bank 3 ($B800) ===
Note that the hardware only has six pins for CHR banking, for a limit of 128KB of CHR.
The value written here selects a 2 KiB CHR ROM bank at PPU $1800-$1FFF.
 
{| class="wikitable"
! Write to CPU address
! 2KB CHR bank affected
|-
| $8800 || $0000-$07FF
|-
| $9800 || $0800-$07FF
|-
| $A800 || $1000-$07FF
|-
| $B800 || $1800-$07FF
|}


=== IRQ load ($C800, write twice) ===
=== IRQ load ($C800, write twice) ===
Line 47: Line 58:
While bit 4 is true, the 16-bit count decreases by 1 every CPU cycle.
While bit 4 is true, the 16-bit count decreases by 1 every CPU cycle.
Whenever the count wraps from $0000 to $FFFF, the mapper asserts an IRQ and pauses itself.
Whenever the count wraps from $0000 to $FFFF, the mapper asserts an IRQ and pauses itself.
Writes also acknowledge IRQ and reset a latch such that the next $C800 write goes to the ''high'' byte of the count.
Writes reset a latch such that the next $C800 write goes to the ''high'' byte of the count.
 
Despite previous notes, writes to this register do not acknowledge the IRQ.


=== Mirroring ($E800) ===
=== Mirroring ($E800) ===
Line 57: Line 70:


=== PRG bank ($F800) ===
=== PRG bank ($F800) ===
The value written here selects a 16 KiB CHR ROM bank at CPU $8000-$BFFF. As in mapper 2, $C000-$FFFF is fixed to the last bank of PRG ROM.
7  bit  0
 
...X PPPP
    | ||||
    | ++++- select a 16 KiB CHR ROM bank at CPU $8000-$BFFF. $C000-$FFFF is fixed to the last bank of PRG ROM.
    +------ (unused by existing hardware) External interrupt enable


== IRQ Operation ==
== IRQ Operation ==

Revision as of 20:04, 13 February 2020


iNES Mapper 067 represents the Sunsoft-3 mapper, used in Fantasy Zone II (J), Mito Koumon II - Sekai Manyuu Ki, and the Vs. System game Vs. Platoon.

Overview

  • PRG ROM size: Hardware supports at least 128 KiB, emulators may support up to 4 MiB
  • PRG ROM bank size: 16 KiB
  • PRG RAM: None
  • CHR bank size: 2 KiB
  • CHR ROM size: Hardware supports at least 128 KiB, emulators may support up to 512 KiB
  • Nametable mirroring: Controlled by mapper (Horizontal, Vertical, 1-screen)
  • Subject to bus conflicts: No

All extant games used 128 KiB PRG-ROM, and 128 KiB CHR-ROM. The actual internal size of the Sunsoft-3's banking registers is unknown, but support for at least 128 KiB is demonstrated by the existing games.

Banks

  • CPU $8000-$BFFF: 16 KiB switchable PRG ROM bank
  • CPU $C000-$FFFF: 16 KiB PRG ROM bank, fixed to the last bank
  • PPU $0000-$07FF: 2 KiB switchable CHR bank
  • PPU $0800-$0FFF: 2 KiB switchable CHR bank
  • PPU $1000-$17FF: 2 KiB switchable CHR bank
  • PPU $1800-$1FFF: 2 KiB switchable CHR bank

Registers

Interrupt Acknowledge ($8000)

Mask: $8800

Any write to this address or any of its mirrors acknowledges a pending IRQ.

CHR bank 0…3 ($8800..$BFFF)

Mask: $F800

Note that the hardware only has six pins for CHR banking, for a limit of 128KB of CHR.

Write to CPU address 2KB CHR bank affected
$8800 $0000-$07FF
$9800 $0800-$07FF
$A800 $1000-$07FF
$B800 $1800-$07FF

IRQ load ($C800, write twice)

Write the high then low byte of a 16-bit CPU cycle count, much like PPUADDR. This directly affects the current count, not a reload value. The write state is reset by writing to the register at $D800.

IRQ enable ($D800)

7  bit  0
...P ....
   |
   +------ 0: Pause counter; 1: Count

While bit 4 is true, the 16-bit count decreases by 1 every CPU cycle. Whenever the count wraps from $0000 to $FFFF, the mapper asserts an IRQ and pauses itself. Writes reset a latch such that the next $C800 write goes to the high byte of the count.

Despite previous notes, writes to this register do not acknowledge the IRQ.

Mirroring ($E800)

7  bit  0
.... ..MM
       ||
       ++- Nametable mirroring (0=vertical, 1=horizontal, 2=1scA, 3=1scB)
            aka connect VRAM A10 to (0=PPU A10, 1=PPU A11, 2=Gnd, 3=Vcc)

PRG bank ($F800)

7  bit  0
...X PPPP
   | ||||
   | ++++- select a 16 KiB CHR ROM bank at CPU $8000-$BFFF. $C000-$FFFF is fixed to the last bank of PRG ROM.
   +------ (unused by existing hardware) External interrupt enable

IRQ Operation

$C800 is a write-twice register (similar to $2005 and $2006). The first write sets the *high* 8 bits of the IRQ counter, and the second write sets the *low* 8 bits. This directly changes the actual IRQ counter -- not a reload value.

Any write to $D800 will acknowledge the IRQ, and will also reset the toggle so that the next write to $C800 will be the first write. $D800, of course, also enables/disables IRQs (bit 4).

The IRQ counter, when enabled, counts down every CPU cycle. When it wraps ($0000->FFFF), it disables itself and triggers an IRQ.

References