From 63dd624665efdbe59d5ba745f705663d2c7f4c25 Mon Sep 17 00:00:00 2001 From: Fabio Priuli Date: Thu, 6 Feb 2014 17:44:32 +0000 Subject: [PATCH] (MESS) nes: added support for Multi-Discrete PCB (aka Mapper 28) used by Action 53 - Function 16 - Volume ONE - "Streemerz Bundle" homebrew multicart. [Fabio Priuli] --- .gitattributes | 2 + src/mess/drivers/nes.c | 1 + src/mess/includes/nes.h | 1 + src/mess/machine/nes_act53.c | 207 ++++++++++++++++++++++++++++++++++ src/mess/machine/nes_act53.h | 36 ++++++ src/mess/machine/nes_ines.inc | 2 +- src/mess/machine/nes_pcb.inc | 1 + src/mess/machine/nes_slot.h | 1 + src/mess/mess.mak | 1 + 9 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 src/mess/machine/nes_act53.c create mode 100644 src/mess/machine/nes_act53.h diff --git a/.gitattributes b/.gitattributes index 767fd2a0937..79f84fe10da 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8126,6 +8126,8 @@ src/mess/machine/ne1000.h svneol=native#text/plain src/mess/machine/ne2000.c svneol=native#text/plain src/mess/machine/ne2000.h svneol=native#text/plain src/mess/machine/nes.c svneol=native#text/plain +src/mess/machine/nes_act53.c svneol=native#text/plain +src/mess/machine/nes_act53.h svneol=native#text/plain src/mess/machine/nes_ave.c svneol=native#text/plain src/mess/machine/nes_ave.h svneol=native#text/plain src/mess/machine/nes_bandai.c svneol=native#text/plain diff --git a/src/mess/drivers/nes.c b/src/mess/drivers/nes.c index 74f59d2cbec..430de412d8d 100644 --- a/src/mess/drivers/nes.c +++ b/src/mess/drivers/nes.c @@ -1016,6 +1016,7 @@ SLOT_INTERFACE_START(nes_cart) SLOT_INTERFACE_INTERNAL("bmc_830118c", NES_BMC_830118C) SLOT_INTERFACE_INTERNAL("pjoy84", NES_PJOY84) SLOT_INTERFACE_INTERNAL("nocash_nochr", NES_NOCHR) + SLOT_INTERFACE_INTERNAL("nes_action53", NES_ACTION53) // other unsupported... SLOT_INTERFACE_INTERNAL("ninjaryu", NES_NROM) // mapper 111 - UNSUPPORTED SLOT_INTERFACE_INTERNAL("unl_dance", NES_NROM) // UNSUPPORTED diff --git a/src/mess/includes/nes.h b/src/mess/includes/nes.h index 2cc0bdfdc9e..315f3047c29 100644 --- a/src/mess/includes/nes.h +++ b/src/mess/includes/nes.h @@ -33,6 +33,7 @@ #include "machine/nes_sunsoft_dcs.h" #include "machine/nes_taito.h" // unlicensed/bootleg/pirate PCBs +#include "machine/nes_act53.h" #include "machine/nes_ave.h" #include "machine/nes_benshieng.h" #include "machine/nes_camerica.h" diff --git a/src/mess/machine/nes_act53.c b/src/mess/machine/nes_act53.c new file mode 100644 index 00000000000..87527b0a2b9 --- /dev/null +++ b/src/mess/machine/nes_act53.c @@ -0,0 +1,207 @@ +/*********************************************************************************************************** + + + NES/Famicom cartridge emulation for Action 53 + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + + + Here we emulate the Multi-Discrete PCB designed by Tepples for + this homebew multicart [mapper 28] + + ***********************************************************************************************************/ + + +#include "emu.h" +#include "machine/nes_act53.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_ACTION53 = &device_creator; + + +nes_action53_device::nes_action53_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : nes_nrom_device(mconfig, NES_ACTION53, "NES Cart Action 53 PCB", tag, owner, clock, "nes_action53", __FILE__) +{ +} + + + +void nes_action53_device::device_start() +{ + common_start(); + save_item(NAME(m_sel)); + save_item(NAME(m_reg)); + m_reg[0] = 0x00; + m_reg[1] = 0x0f; + m_reg[2] = 0x00; + m_reg[3] = 0x3f; +} + +void nes_action53_device::pcb_reset() +{ + m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; + // register content is not touched by reset + update_prg(); +} + + +/*------------------------------------------------- + mapper specific handlers + -------------------------------------------------*/ + +/*------------------------------------------------- + + Board ACTION 53 + + In MESS: *VERY* preliminary support. + + This board uses 4 registers (reg is selected by writes to 0x5xxx) + Info from nesdev wiki + + R:$00: [...M ..CC] + C = CHR Reg + M = Mirroring + This bit overwrites bit 0 of R:$80, but only if bit 1 of + R:$80 is clear + + R:$01: [...M PPPP] + P = PRG Reg + M = Mirroring + This bit overwrites bit 0 of R:$80, but only if bit 1 of + R:$80 is clear + + R:$80: [..GG PSMM] + G = Game Size (0=32K, 1=64K, 2=128K, 3=256K) + P = PRG Size (0=32k mode, 1=16k mode) + S = Slot select: + 0 = $C000 swappable, $8000 fixed to bottom of 32K outer bank + 1 = $8000 swappable, $C000 fixed to top of 32K outer bank + This bit is ignored when 'P' is clear (32k mode) + M = Mirroring control: + %00 = 1ScA + %01 = 1ScB + %10 = Vert + %11 = Horz + + R:$81: [..BB BBBB] + Outer PRG Reg + + + -------------------------------------------------*/ + +void nes_action53_device::update_prg() +{ + UINT8 prg_lo = 0, prg_hi = 0, helper = 0; + UINT8 out = (m_reg[3] & 0x3f) << 1; // Outer PRG reg + UINT8 size = (m_reg[2] & 0x30) >> 4; // Game size + UINT8 mask = (1 << (size + 1)) - 1; // Bits to be taken from PRG reg + + if (!BIT(m_reg[2], 3)) + { + helper = (out & ~mask) | ((m_reg[1] << 1) & mask); + //32K mode + prg_lo = (helper & 0xfe); + prg_hi = (helper | 0x01); + } + else + { + helper = (out & ~mask) | (m_reg[1] & mask); + if (BIT(m_reg[2], 2)) + { + //16K mode with fixed HI + prg_lo = helper; + prg_hi = (out | 0x01); + } + else + { + //16K mode with fixed LO + prg_lo = (out & 0xfe); + prg_hi = helper; + } + } + +// printf("banks : 0x%2X - 0x%2X\n", prg_lo, prg_hi); + prg16_89ab(prg_lo); + prg16_cdef(prg_hi); +} + +void nes_action53_device::update_mirr() +{ + switch (m_reg[2] & 0x03) + { + case 0: + set_nt_mirroring(PPU_MIRROR_LOW); + break; + case 1: + set_nt_mirroring(PPU_MIRROR_HIGH); + break; + case 2: + set_nt_mirroring(PPU_MIRROR_VERT); + break; + case 3: + set_nt_mirroring(PPU_MIRROR_HORZ); + break; + } +} + +WRITE8_MEMBER(nes_action53_device::write_l) +{ + LOG_MMC(("action 53 write_l, offset: %04x, data: %02x\n", offset, data)); + offset += 0x100; + if (offset >= 0x1000) + m_sel = BIT(data, 0) | (BIT(data, 7) << 1); +} + + +WRITE8_MEMBER(nes_action53_device::write_h) +{ + LOG_MMC(("action 53 write_h, offset: %04x, data: %02x\n", offset, data)); + + if (m_reg[m_sel] != data) + { + m_reg[m_sel] = data; + + switch (m_sel) + { + case 0: + if (!BIT(m_reg[2],1)) + { + m_reg[2] &= 0xfe; + m_reg[2] |= BIT(data,4); + update_mirr(); + } + chr8(m_reg[0] & 0x03, m_chr_source); + break; + case 1: + if (!BIT(m_reg[2],1)) + { + m_reg[2] &= 0xfe; + m_reg[2] |= BIT(data,4); + update_mirr(); + } + update_prg(); + break; + case 2: + update_prg(); + update_mirr(); + break; + case 3: + update_prg(); + break; + } + } +} diff --git a/src/mess/machine/nes_act53.h b/src/mess/machine/nes_act53.h new file mode 100644 index 00000000000..0d9b2cea489 --- /dev/null +++ b/src/mess/machine/nes_act53.h @@ -0,0 +1,36 @@ +#ifndef __NES_ACTION53_H +#define __NES_ACTION53_H + +#include "machine/nes_nxrom.h" + + +// ======================> nes_racermate_device + +class nes_action53_device : public nes_nrom_device +{ +public: + // construction/destruction + nes_action53_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // device-level overrides + virtual void device_start(); + virtual DECLARE_WRITE8_MEMBER(write_l); + virtual DECLARE_WRITE8_MEMBER(write_h); + + virtual void pcb_reset(); + +private: + void update_prg(); + void update_mirr(); + UINT8 m_sel; + UINT8 m_reg[4]; +}; + + + + + +// device type definition +extern const device_type NES_ACTION53; + +#endif diff --git a/src/mess/machine/nes_ines.inc b/src/mess/machine/nes_ines.inc index edb70d9542e..08adf48c30c 100644 --- a/src/mess/machine/nes_ines.inc +++ b/src/mess/machine/nes_ines.inc @@ -57,7 +57,7 @@ static const nes_mmc mmc_list[] = { 25, KONAMI_VRC4 }, { 26, KONAMI_VRC6 }, { 27, UNL_WORLDHERO }, // 27 World Hero board - Unsupported - // 28 Unused + { 28, BTL_ACTION53 }, // 28 - Multi-discrete PCB designed by Tepples for Action 53 // 29 Unused // 30 Unused // 31 Unused diff --git a/src/mess/machine/nes_pcb.inc b/src/mess/machine/nes_pcb.inc index 2c251635e5e..e3c0dd3c671 100644 --- a/src/mess/machine/nes_pcb.inc +++ b/src/mess/machine/nes_pcb.inc @@ -300,6 +300,7 @@ static const nes_pcb pcb_list[] = { "tf1201", UNL_TF1201 }, { "unl_cfight", UNL_CITYFIGHT }, { "nocash_nochr", NOCASH_NOCHR }, + { "nes_action53", BTL_ACTION53 }, { "ffe3", FFE3_BOARD }, { "ffe4", FFE4_BOARD }, { "ffe8", FFE8_BOARD }, diff --git a/src/mess/machine/nes_slot.h b/src/mess/machine/nes_slot.h index b017e986482..2394bf3d4d5 100644 --- a/src/mess/machine/nes_slot.h +++ b/src/mess/machine/nes_slot.h @@ -120,6 +120,7 @@ enum KAY_BOARD, HOSENKAN_BOARD, NITRA_TDA, GOUDER_37017, NANJING_BOARD, WHIRLWIND_2706, NOCASH_NOCHR, // homebrew PCB design which uses NTRAM for CHRRAM + BTL_ACTION53, // homebrew PCB for homebrew multicarts /* FFE boards, for mappers 6, 8, 17 */ FFE3_BOARD, FFE4_BOARD, FFE8_BOARD, TEST_BOARD, /* Unsupported (for place-holder boards, with no working emulation) & no-board (at init) */ diff --git a/src/mess/mess.mak b/src/mess/mess.mak index 67fa9daec37..afb41015efc 100644 --- a/src/mess/mess.mak +++ b/src/mess/mess.mak @@ -1535,6 +1535,7 @@ $(MESSOBJ)/nintendo.a: \ $(MESS_MACHINE)/nes_mmc3.o \ $(MESS_MACHINE)/nes_mmc3_clones.o \ $(MESS_MACHINE)/nes_mmc5.o \ + $(MESS_MACHINE)/nes_act53.o \ $(MESS_MACHINE)/nes_ave.o \ $(MESS_MACHINE)/nes_bandai.o \ $(MESS_MACHINE)/nes_benshieng.o \