RAMBO-1: Difference between revisions
(118/158 mirroring in a nutshell) |
(Move Disch's notes from iNES Mapper 064) |
||
Line 128: | Line 128: | ||
Mapper 64 has mirroring like mapper 4, as described above. | Mapper 64 has mirroring like mapper 4, as described above. | ||
Mapper 158, used for ''Alien Syndrome'', has mirroring like [[iNES Mapper 118|mapper 118]] (TLSROM), where CIRAM A10 is connected to CHR A17, and bit 7 of each CHR bank mapped into PPU $0000-$0FFF controls which page of CIRAM is used for the corresponding nametable in $2000-$2FFF. | Mapper 158, used for ''Alien Syndrome'', has mirroring like [[iNES Mapper 118|mapper 118]] (TLSROM), where CIRAM A10 is connected to CHR A17, and bit 7 of each CHR bank mapped into PPU $0000-$0FFF controls which page of CIRAM is used for the corresponding nametable in $2000-$2FFF. | ||
== Disch's Notes == | |||
Here are Disch's original notes: | |||
======================== | |||
= Mapper 064 = | |||
======================== | |||
aka | |||
-------------------------- | |||
Tengen RAMBO-1 | |||
Example Games: | |||
-------------------------- | |||
Klax | |||
Skull and Crossbones | |||
Shinobi | |||
Notes: | |||
-------------------------- | |||
This mapper is very similar to MMC3. It uses a similar swapping system, but adds a little functionality. | |||
IRQs are set up similar as well... but have some major differences. | |||
This is one of those mappers that is a big pain to implement in an emu -- especially since so few games use | |||
it. And the games that use it really blow hard. | |||
Registers: | |||
-------------------------- | |||
Range,Mask: $8000-FFFF, $E001 | |||
$8000: [CPK. AAAA] | |||
C = CHR mode select | |||
P = PRG mode select | |||
K = full 1k CHR mode select (see CHR setup) | |||
A = Address for use with $8001 | |||
$8001: [DDDD DDDD] Data port | |||
R:0 -> CHR reg 0 | |||
R:1 -> CHR reg 1 | |||
R:2 -> CHR reg 2 | |||
R:3 -> CHR reg 3 | |||
R:4 -> CHR reg 4 | |||
R:5 -> CHR reg 5 | |||
R:6 -> PRG reg 0 | |||
R:7 -> PRG reg 1 | |||
R:8 -> CHR reg 6 | |||
R:9 -> CHR reg 7 | |||
R:A - R:E not used | |||
R:F -> PRG reg 2 | |||
$A000: [.... ...M] Mirroring | |||
0 = Vert | |||
1 = Horz | |||
$C000: [IIII IIII] IRQ Reload value | |||
$C001: [.... ...M] IRQ Mode select and reset | |||
0 = Scanline (A12) mode | |||
1 = Cycle mode | |||
$E000: [.... ....] IRQ Acknowledge/Disable | |||
$E001: [.... ....] IRQ Enable | |||
PRG Setup: | |||
--------------------------- | |||
PRG mode is selected via $8000.6 | |||
$8000 $A000 $C000 $E000 | |||
+-------+-------+-------+-------+ | |||
PRG Mode 0: | R:6 | R:7 | R:F | { -1} | | |||
+-------+-------+-------+-------+ | |||
PRG Mode 1: | R:F | R:6 | R:7 | { -1} | | |||
+-------+-------+-------+-------+ | |||
CHR Setup: | |||
--------------------------- | |||
$8000 has 2 bits to configure CHR modes. Therefore there are effectively 4 CHR modes. | |||
$8000: [CPK. AAAA] <--- C and K bits relevant to CHR | |||
$0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00 | |||
+---------------+---------------+-------+-------+-------+-------+ | |||
C=0, K=0 | <R:0> | <R:1> | R:2 | R:3 | R:4 | R:5 | | |||
+---------------+---------------+-------+-------+-------+-------+ | |||
C=0, K=1 | R:0 | R:8 | R:1 | R:9 | R:2 | R:3 | R:4 | R:5 | | |||
+-------+-------+-------+-------+---------------+---------------+ | |||
C=1, K=0 | R:2 | R:3 | R:4 | R:5 | <R:0> | <R:1> | | |||
+-------+-------+-------+-------+---------------+---------------+ | |||
C=1, K=1 | R:2 | R:3 | R:4 | R:5 | R:0 | R:8 | R:1 | R:9 | | |||
+-------+-------+-------+-------+-------+-------+-------+-------+ | |||
IRQs: | |||
--------------------------- | |||
There are two separate IRQ modes. One uses A12 to count scanlines in a manner just like MMC3 does (see | |||
mapper 004 for details on how scanlines are counted and the restrictions involved). The other mode uses CPU | |||
cycles with a 4-step prescaler (so the IRQ counter gets clocked every 4 CPU cycles). | |||
Regardless of the mode used to clock the counter... every time the counter is clocked, the following actions | |||
occur: | |||
- If Reset reg ($C001) was written to after previous clock... | |||
a) reload IRQ counter with IRQ Reload value **PLUS ONE** | |||
- Otherwise... If IRQ Counter is 0... | |||
a) reload IRQ counter with IRQ Reload value | |||
- Otherwise... | |||
a) Decrement IRQ counter by 1 | |||
b) If IRQ counter is now 0 and IRQs are enabled, trigger IRQ | |||
Just like with MMC3, the counter is clocked and updated even when IRQs are disabled -- however IRQs will only | |||
be triggered when enabled. | |||
Note about the plus one: I'm not sure if 1 is really added or if there's simply an additional 1 clock delay | |||
before the IRQ counter is updated. From a software standpoint, it doesn't really matter -- adding the | |||
additional 1 works without any side-effects. | |||
Registers involved with IRQs: | |||
--------------------------- | |||
$C000: [IIII IIII] - IRQ Reload value | |||
$C001: [.... ...M] - IRQ Reset reg, mode select | |||
0 = Scanline mode (A12) | |||
1 = CPU Cycle mode (with prescaler) | |||
Any write to this register will make it so that the IRQ counter will reload with the reload value +1 on | |||
its next clock. Whether or not writing to this register clears the IRQ counter like it does with MMC3 isn't | |||
known... and doesn't matter, since it's reloaded later anyway. | |||
Also, any write to this register will reset the CPU cycle prescaler (so that it will be 4 CPU cycles | |||
until the next clock). | |||
$E000: [.... ....] - IRQ Acknowledge/Disable | |||
Any write to this register will acknowledge the pending IRQ, and disable IRQs | |||
$E001: [.... ....] - IRQ Enable | |||
Any write to this register will enable IRQs | |||
A note about IRQs: | |||
------------------ | |||
Scanline IRQs seem to trip a little later than they do on the MMC3. It looks like about a 5 dot delay | |||
from the normal MMC3 IRQ time (265 instead of 260). Failure to put in this delay results in shaking and | |||
other graphical quirks in some games... notably Klax. This delay also seems to exist for CPU cycle driven | |||
IRQs (Skull & Crossbones will suffer without it). Perhaps the RAMBO-1's IRQ generating hardware is a little | |||
slower than usual? | |||
Apart from that timing difference, A12 clocks RAMBO-1's IRQ counter just exactly like it does MMC3, so all | |||
the notes about A12, $2006/7, etc from the mapper 004 documentation apply to this mapper as well. |
Revision as of 06:24, 9 October 2012
The Tengen RAMBO-1 is an ASIC mapper, assigned to iNES mappers 64 and 158. This mapper is basically Tengen's version of the MMC3, but with some extra features.
Overview
- PRG ROM size: Up to 256 KB
- PRG ROM bank size: 8 KB
- PRG RAM: Unknown
- CHR capacity: Up to 256 KB ROM
- CHR bank size: All 1 KB, or 2 2KB and 4 1KB
- Nametable mirroring: Controlled by mapper
- Subject to bus conflicts: No
Banks
- CPU $8000-$9FFF: 8 KB switchable PRG ROM bank
- CPU $A000-$BFFF: 8 KB switchable PRG ROM bank
- CPU $C000-$DFFF: 8 KB switchable PRG ROM bank
- CPU $E000-$FFFF: 8 KB PRG ROM bank, fixed to the last bank
- PPU -- Three selectable configurations:
- 1 KB switchable CHR banks at $0000, $0400, $0800, $0C00, $1000, $1400, $1800, $1C00
- 2 KB switchable CHR banks at $0000, $0800; 1 KB switchable CHR banks at $1000, $1400, $1800, $1C00
- 2 KB switchable CHR banks at $1000, $1800; 1 KB switchable CHR banks at $0000, $0400, $0800, $0C00
Registers
The RAMBO-1 has 4 pairs of registers at $8000-$9FFF, $A000-$BFFF, $C000-$DFFF, and $E000-$FFFF - even addresses ($8000, $8002, etc.) select the low register and odd addresses ($8001, $8003, etc.) select the high register in each pair.
Bank select ($8000-$9FFE, even)
7 bit 0 ---- ---- CPKx RRRR ||| |||| ||| ++++- Specify which bank register to update on next write to Bank Data register ||| 0: Select 2 (K=0) or 1 (K=1) KB CHR bank at PPU $0000 (or $1000); ||| 1: Select 2 (K=0) or 1 (K=1) KB CHR bank at PPU $0800 (or $1800); ||| 2: Select 1 KB CHR bank at PPU $1000-$13FF (or $0000-$03FF); ||| 3: Select 1 KB CHR bank at PPU $1400-$17FF (or $0400-$07FF); ||| 4: Select 1 KB CHR bank at PPU $1800-$1BFF (or $0800-$0BFF); ||| 5: Select 1 KB CHR bank at PPU $1C00-$1FFF (or $0C00-$0FFF); ||| 6: Select 8 KB PRG ROM bank at $8000-$9FFF (or $A000-$BFFF); ||| 7: Select 8 KB PRG ROM bank at $A000-$BFFF (or $C000-$DFFF); ||| 8: If K=1, Select 1 KB CHR bank at PPU $0400 (or $1400); ||| 9: If K=1, Select 1 KB CHR bank at PPU $0C00 (or $1C00); ||| F: Select 8 KB PRG ROM bank at $C000-$DFFF (or $8000-$9FFF); ||+------- Full 1KB CHR bank mode (0: two 2KB banks at $0000-$0FFF (or $1000-$1FFF), || 1: four 1KB banks at $0000-$0FFF (or $1000-$1FFF)) |+-------- PRG ROM bank mode (0: $8000-$9FFF uses bank selected with R:6, | $A000-$BFFF uses bank selected with R:7, | $C000-$DFFF uses bank selected with R:F; | 1: $8000-$9FFF uses bank selected with R:F, | $A000-$BFFF uses bank selected with R:6, -- NOT 7 | $C000-$DFFF uses bank selected with R:7) -- NOT 6 +--------- CHR A12 inversion (0: two 2 KB banks (or four 1 KB banks) at $0000-$0FFF, four 1 KB banks at $1000-$1FFF; 1: two 2 KB banks (or four 1 KB banks) at $1000-$1FFF, four 1 KB banks at $0000-$0FFF)
In PRG ROM bank mode 1, the functions of registers 6 and 7 are backward compared to the corresponding mode of MMC3.
Bank data ($8001-$9FFF, odd)
7 bit 0 ---- ---- DDDD DDDD |||| |||| ++++-++++- New bank value, based on last value written to Bank select register (mentioned above)
Mirroring ($A000-$BFFE, even)
7 bit 0 ---- ---- xxxx xxxM | +- Mirroring (0: vertical; 1: horizontal)
This applies to mapper 64 only (see Variants below).
IRQ latch ($C000-$DFFE, even)
7 bit 0 ---- ---- DDDD DDDD |||| |||| ++++-++++- IRQ latch value
This register specifies the IRQ counter reload value. When the IRQ counter is zero (or a reload is requested through $C001), this value will be copied into the IRQ counter at the end of the current scanline.
IRQ mode select / reload ($C001-$DFFF, odd)
7 bit 0 ---- ---- xxxx xxxM | +- IRQ mode select (0: Scanline Mode, 1: CPU Cycle Mode)
Writing to this register also clears the IRQ counter so that it will be reloaded at next clock, or the next scanline, depending on the selected mode. This also resets the prescaler in cycle mode, so the next clock will occur 4 cycles later.
IRQ acknowledge / disable ($E000-$FFFE, even)
7 bit 0 ---- ---- xxxx xxxx
Writing any value to this register will disable counter interrupts AND acknowledge any pending interrupts.
IRQ enable ($E001-$FFFF, odd)
7 bit 0 ---- ---- xxxx xxxx
Writing any value to this register will enable counter interrupts.
IRQ counter operation
The counter can be set to either scanline mode or cpu cycle mode.
In scanline mode, the counter is clocked using the same method the MMC3 uses, and follows the same restrictions. However, the actual interrupt seems to trigger 5 pixels later, compared to the MMC3.
In CPU cycle mode, the counter is clocked every 4 CPU cycles. Again, the actual interrupt seems to trigger 5 pixels later than when they're fired.
Whichever method is being used, the counter behaves the following way:
- IF $C001 was written to after previous clock
- reload IRQ counter with IRQ Reload value PLUS ONE (see note)
- ELSE IF IRQ counter is 0
- reload IRQ counter with IRQ Reload value
- ELSE
- Decrement IRQ counter by 1
- IF IRQ counter is now 0 AND IRQs are enabled
- trigger IRQ (which takes effect 5 pixels later)
Note: When $C001 is written to, it's unknown as to whether reload+1 is written to the counter, or if the counter just takes an extra clock to start counting.
Variants
Mapper 64 has mirroring like mapper 4, as described above. Mapper 158, used for Alien Syndrome, has mirroring like mapper 118 (TLSROM), where CIRAM A10 is connected to CHR A17, and bit 7 of each CHR bank mapped into PPU $0000-$0FFF controls which page of CIRAM is used for the corresponding nametable in $2000-$2FFF.
Disch's Notes
Here are Disch's original notes: ======================== = Mapper 064 = ======================== aka -------------------------- Tengen RAMBO-1 Example Games: -------------------------- Klax Skull and Crossbones Shinobi Notes: -------------------------- This mapper is very similar to MMC3. It uses a similar swapping system, but adds a little functionality. IRQs are set up similar as well... but have some major differences. This is one of those mappers that is a big pain to implement in an emu -- especially since so few games use it. And the games that use it really blow hard. Registers: -------------------------- Range,Mask: $8000-FFFF, $E001 $8000: [CPK. AAAA] C = CHR mode select P = PRG mode select K = full 1k CHR mode select (see CHR setup) A = Address for use with $8001 $8001: [DDDD DDDD] Data port R:0 -> CHR reg 0 R:1 -> CHR reg 1 R:2 -> CHR reg 2 R:3 -> CHR reg 3 R:4 -> CHR reg 4 R:5 -> CHR reg 5 R:6 -> PRG reg 0 R:7 -> PRG reg 1 R:8 -> CHR reg 6 R:9 -> CHR reg 7 R:A - R:E not used R:F -> PRG reg 2 $A000: [.... ...M] Mirroring 0 = Vert 1 = Horz $C000: [IIII IIII] IRQ Reload value $C001: [.... ...M] IRQ Mode select and reset 0 = Scanline (A12) mode 1 = Cycle mode $E000: [.... ....] IRQ Acknowledge/Disable $E001: [.... ....] IRQ Enable PRG Setup: --------------------------- PRG mode is selected via $8000.6 $8000 $A000 $C000 $E000 +-------+-------+-------+-------+ PRG Mode 0: | R:6 | R:7 | R:F | { -1} | +-------+-------+-------+-------+ PRG Mode 1: | R:F | R:6 | R:7 | { -1} | +-------+-------+-------+-------+ CHR Setup: --------------------------- $8000 has 2 bits to configure CHR modes. Therefore there are effectively 4 CHR modes. $8000: [CPK. AAAA] <--- C and K bits relevant to CHR $0000 $0400 $0800 $0C00 $1000 $1400 $1800 $1C00 +---------------+---------------+-------+-------+-------+-------+ C=0, K=0 | <R:0> | <R:1> | R:2 | R:3 | R:4 | R:5 | +---------------+---------------+-------+-------+-------+-------+ C=0, K=1 | R:0 | R:8 | R:1 | R:9 | R:2 | R:3 | R:4 | R:5 | +-------+-------+-------+-------+---------------+---------------+ C=1, K=0 | R:2 | R:3 | R:4 | R:5 | <R:0> | <R:1> | +-------+-------+-------+-------+---------------+---------------+ C=1, K=1 | R:2 | R:3 | R:4 | R:5 | R:0 | R:8 | R:1 | R:9 | +-------+-------+-------+-------+-------+-------+-------+-------+ IRQs: --------------------------- There are two separate IRQ modes. One uses A12 to count scanlines in a manner just like MMC3 does (see mapper 004 for details on how scanlines are counted and the restrictions involved). The other mode uses CPU cycles with a 4-step prescaler (so the IRQ counter gets clocked every 4 CPU cycles). Regardless of the mode used to clock the counter... every time the counter is clocked, the following actions occur: - If Reset reg ($C001) was written to after previous clock... a) reload IRQ counter with IRQ Reload value **PLUS ONE** - Otherwise... If IRQ Counter is 0... a) reload IRQ counter with IRQ Reload value - Otherwise... a) Decrement IRQ counter by 1 b) If IRQ counter is now 0 and IRQs are enabled, trigger IRQ Just like with MMC3, the counter is clocked and updated even when IRQs are disabled -- however IRQs will only be triggered when enabled. Note about the plus one: I'm not sure if 1 is really added or if there's simply an additional 1 clock delay before the IRQ counter is updated. From a software standpoint, it doesn't really matter -- adding the additional 1 works without any side-effects. Registers involved with IRQs: --------------------------- $C000: [IIII IIII] - IRQ Reload value $C001: [.... ...M] - IRQ Reset reg, mode select 0 = Scanline mode (A12) 1 = CPU Cycle mode (with prescaler) Any write to this register will make it so that the IRQ counter will reload with the reload value +1 on its next clock. Whether or not writing to this register clears the IRQ counter like it does with MMC3 isn't known... and doesn't matter, since it's reloaded later anyway. Also, any write to this register will reset the CPU cycle prescaler (so that it will be 4 CPU cycles until the next clock). $E000: [.... ....] - IRQ Acknowledge/Disable Any write to this register will acknowledge the pending IRQ, and disable IRQs $E001: [.... ....] - IRQ Enable Any write to this register will enable IRQs A note about IRQs: ------------------ Scanline IRQs seem to trip a little later than they do on the MMC3. It looks like about a 5 dot delay from the normal MMC3 IRQ time (265 instead of 260). Failure to put in this delay results in shaking and other graphical quirks in some games... notably Klax. This delay also seems to exist for CPU cycle driven IRQs (Skull & Crossbones will suffer without it). Perhaps the RAMBO-1's IRQ generating hardware is a little slower than usual? Apart from that timing difference, A12 clocks RAMBO-1's IRQ counter just exactly like it does MMC3, so all the notes about A12, $2006/7, etc from the mapper 004 documentation apply to this mapper as well.