mame/src/mess/machine/nes_rexsoft.c
Fabio Priuli 937fd2493f (MESS) nes.c: fixed NINA-001 emulation (mapper 34), promoting Impossible Mission II to working
state [Fabio Priuli]
(MESS) nes.c: improved Taito LROG017 emulation (mapper 77), promoting Napoleon Senki to working
state [Fabio Priuli]
(MESS) nes.c: added emulation of the Sachen SA-9602B pcb used by Mei Shao Nv Meng Gong Chang,
a chinese port of Princess Maker by Sachen, based on the great work done by Cah4e3 in FCEUMM 
[Fabio Priuli]

out of whatsnew: this change also moves the summary of known issues in the appropriate source files
(some pirate and multigame cart issues have to be rechecked, due to the amount of changes done since
they were last checked, so I will add them back after a few test)
2013-04-22 13:23:56 +00:00

265 lines
6.5 KiB
C

/***********************************************************************************************************
NES/Famicom cartridge emulation for Rex Soft PCBs
Copyright MESS Team.
Visit http://mamedev.org for licensing and usage restrictions.
Here we emulate the following PCBs
* Rex Soft DragonBall Z V [mapper 12]
* Rex Soft SL-1632 [mapper 14]
TODO:
- fix 0x6000-0x7fff accesses, write_m/read_m
- check glitches in SL-1632
***********************************************************************************************************/
#include "emu.h"
#include "machine/nes_rexsoft.h"
#ifdef NES_PCB_DEBUG
#define VERBOSE 1
#else
#define VERBOSE 0
#endif
#define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0)
//-------------------------------------------------
// constructor
//-------------------------------------------------
const device_type NES_REX_DBZ5 = &device_creator<nes_rex_dbz5_device>;
const device_type NES_REX_SL1632 = &device_creator<nes_rex_sl1632_device>;
nes_rex_dbz5_device::nes_rex_dbz5_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: nes_txrom_device(mconfig, NES_REX_DBZ5, "NES Cart Rex Soft DragonBall Z V PCB", tag, owner, clock, "nes_rex_dbz5", __FILE__)
{
}
nes_rex_sl1632_device::nes_rex_sl1632_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: nes_txrom_device(mconfig, NES_REX_SL1632, "NES Cart Rex Soft SL-1632 PCB", tag, owner, clock, "nes_rex_sl1632", __FILE__)
{
}
void nes_rex_dbz5_device::device_start()
{
mmc3_start();
save_item(NAME(m_extra));
}
void nes_rex_dbz5_device::pcb_reset()
{
m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
mmc3_common_initialize(0xff, 0xff, 0);
m_extra = 0;
}
void nes_rex_sl1632_device::device_start()
{
mmc3_start();
save_item(NAME(m_mode));
save_item(NAME(m_mirror));
save_item(NAME(m_extra_bank));
}
void nes_rex_sl1632_device::pcb_reset()
{
m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
m_mode = 0;
m_mirror = 0;
memset(m_extra_bank, 0, sizeof(m_extra_bank));
m_extra_bank[2] = 0xfe;
m_extra_bank[3] = 0xff;
mmc3_common_initialize(0xff, 0xff, 0);
}
/*-------------------------------------------------
mapper specific handlers
-------------------------------------------------*/
/*-------------------------------------------------
Bootleg Board by Rex Soft
Games: Dragon Ball Z 5, Dragon Ball Z Super
MMC3 clone. Writes to 0x4100-0x5fff (or from 0x4020?)
possibly select higher VROM pages (to allow up to
512 banks instead of 256 only): bit0 selects the
higher pages for PPU banks 0-3 (0x0000-0x0fff), while
bit4 selects the higher pages for PPU banks 4-7 (0x1000-0x1fff)
iNES: mapper 12
In MESS: Supported
-------------------------------------------------*/
WRITE8_MEMBER(nes_rex_dbz5_device::write_l)
{
LOG_MMC(("rex_dbz write_l, offset: %04x, data: %02x\n", offset, data));
m_extra = data;
set_chr(m_chr_source, m_chr_base, m_chr_mask);
}
/* we would need to use this read handler in 0x6000-0x7fff as well */
READ8_MEMBER(nes_rex_dbz5_device::read_l)
{
LOG_MMC(("rex_dbz read_l, offset: %04x\n", offset));
return 0x01;
}
void nes_rex_dbz5_device::chr_cb(int start, int bank, int source)
{
int shift = (start < 4) ? 8 : 4;
bank |= ((m_extra << shift) & 0x100);
chr1_x(start, bank, source);
}
/*-------------------------------------------------
Rex Soft SL1632 Board
Games: Samurai Spirits
MMC3 clone
iNES: mapper 14
In MESS: Supported
-------------------------------------------------*/
void nes_rex_sl1632_device::set_prg(int prg_base, int prg_mask)
{
if (m_mode & 0x02)
{
// here standard MMC3 bankswitch
UINT8 prg_flip = (m_latch & 0x40) ? 2 : 0;
prg_cb(0, prg_base | (m_mmc_prg_bank[0 ^ prg_flip] & prg_mask));
prg_cb(1, prg_base | (m_mmc_prg_bank[1] & prg_mask));
prg_cb(2, prg_base | (m_mmc_prg_bank[2 ^ prg_flip] & prg_mask));
prg_cb(3, prg_base | (m_mmc_prg_bank[3] & prg_mask));
}
else
{
prg8_89(m_extra_bank[0]);
prg8_ab(m_extra_bank[1]);
prg8_cd(m_extra_bank[2]);
prg8_ef(m_extra_bank[3]);
}
}
void nes_rex_sl1632_device::set_chr(UINT8 chr, int chr_base, int chr_mask)
{
static const UINT8 conv_table[8] = {5, 5, 5, 5, 3, 3, 1, 1};
UINT8 chr_page = (m_latch & 0x80) >> 5;
UINT8 bank[8];
UINT8 chr_base2[8];
if (m_mode & 0x02)
{
for (int i = 0; i < 8; i++)
{
// since the mapper acts on 1K CHR chunks, we have 8 banks which use the 6 m_mmc_vrom_bank from MMC3 base class
if (i < 4)
bank[i] = ((m_mmc_vrom_bank[i / 2] & 0xfe) | (i & 1));
else
bank[i] = m_mmc_vrom_bank[i - 2];
chr_base2[i] = chr_base | ((m_mode << conv_table[i]) & 0x100);
}
}
else
{
for (int i = 0; i < 8; i++)
{
bank[i] = m_extra_bank[i + 4]; // first 4 m_extra_banks are PRG
chr_base2[i] = chr_base;
}
}
chr1_x(chr_page ^ 0, chr_base2[0] | (bank[0] & chr_mask), chr);
chr1_x(chr_page ^ 1, chr_base2[1] | (bank[1] & chr_mask), chr);
chr1_x(chr_page ^ 2, chr_base2[2] | (bank[2] & chr_mask), chr);
chr1_x(chr_page ^ 3, chr_base2[3] | (bank[3] & chr_mask), chr);
chr1_x(chr_page ^ 4, chr_base2[4] | (bank[4] & chr_mask), chr);
chr1_x(chr_page ^ 5, chr_base2[5] | (bank[5] & chr_mask), chr);
chr1_x(chr_page ^ 6, chr_base2[6] | (bank[6] & chr_mask), chr);
chr1_x(chr_page ^ 7, chr_base2[7] | (bank[7] & chr_mask), chr);
}
WRITE8_MEMBER(nes_rex_sl1632_device::write_h)
{
UINT8 helper1, helper2;
LOG_MMC(("rex_sl1632 write_h, offset: %04x, data: %02x\n", offset, data));
if (offset == 0x2131)
{
m_mode = data;
set_prg(m_prg_base, m_prg_mask);
set_chr(m_chr_source, m_chr_base, m_chr_mask);
if (!(m_mode & 0x02))
set_nt_mirroring(BIT(m_mirror, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
}
if (m_mode & 0x02)
{
switch (offset & 0x6001)
{
case 0x2000:
set_nt_mirroring(BIT(m_mirror, 0) ? PPU_MIRROR_VERT : PPU_MIRROR_HORZ);
break;
default:
txrom_write(space, offset, data, mem_mask);
break;
}
}
else if (offset >= 0x3000 && offset <= 0x6003)
{
helper1 = (offset & 0x01) << 2;
offset = ((offset & 0x02) | (offset >> 10)) >> 1;
helper2 = ((offset + 2) & 0x07) + 4; // '+4' because first 4 m_extra_banks are for PRG!
m_extra_bank[helper2] = (m_extra_bank[helper2] & (0xf0 >> helper1)) | ((data & 0x0f) << helper1);
set_chr(m_chr_source, m_chr_base, m_chr_mask);
}
else
{
switch (offset & 0x7003)
{
case 0x0000:
case 0x2000:
m_extra_bank[offset >> 13] = data;
set_prg(m_prg_base, m_prg_mask);
break;
case 0x1000:
m_mirror = data;
set_nt_mirroring(BIT(m_mirror, 0) ? PPU_MIRROR_HORZ : PPU_MIRROR_VERT);
break;
}
}
}