summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus
diff options
context:
space:
mode:
author 0kmg <9137159+0kmg@users.noreply.github.com>2021-09-12 15:25:16 -0800
committer 0kmg <9137159+0kmg@users.noreply.github.com>2021-09-18 10:19:26 -0800
commit2976726f825bcc5ace266b651d1acc5df4736f3a (patch)
treee80806504f939dcdf4327ae3070da50aa3875e5e /src/devices/bus
parent8ffadea809767a0167b30052f0ab7165f6b22ace (diff)
bus/nes: Added support for Super Russian Roulette.
New working software list additions (nes.xml) ----------------------------------- Super Russian Roulette [re4mat]
Diffstat (limited to 'src/devices/bus')
-rw-r--r--src/devices/bus/nes/batlab.cpp203
-rw-r--r--src/devices/bus/nes/batlab.h45
-rw-r--r--src/devices/bus/nes/nes_carts.cpp2
-rw-r--r--src/devices/bus/nes/nes_ines.hxx2
-rw-r--r--src/devices/bus/nes/nes_pcb.hxx14
-rw-r--r--src/devices/bus/nes/nes_slot.cpp13
-rw-r--r--src/devices/bus/nes/nes_slot.h9
7 files changed, 285 insertions, 3 deletions
diff --git a/src/devices/bus/nes/batlab.cpp b/src/devices/bus/nes/batlab.cpp
new file mode 100644
index 00000000000..f341e5bcd8b
--- /dev/null
+++ b/src/devices/bus/nes/batlab.cpp
@@ -0,0 +1,203 @@
+// license:BSD-3-Clause
+// copyright-holders: kmg, Fabio Priuli
+/***********************************************************************************************************
+
+
+ NES/Famicom cartridge emulation for Batlab Electronics and related PCBs
+
+
+ Here we emulate the following homebrew PCBs
+
+ * BATLAP BATMAP-SRR-X [mapper 413]
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "batlab.h"
+
+#include "video/ppu2c0x.h" // this has to be included so that IRQ functions can access ppu2c0x_device::BOTTOM_VISIBLE_SCANLINE
+
+
+#ifdef NES_PCB_DEBUG
+#define VERBOSE 1
+#else
+#define VERBOSE 0
+#endif
+
+#define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0)
+
+
+//-------------------------------------------------
+// constructor
+//-------------------------------------------------
+
+DEFINE_DEVICE_TYPE(NES_BATMAP_SRRX, nes_batmap_srrx_device, "nes_batmap_srrx", "NES Cart Batlab BATMAP-SRR-X PCB")
+
+
+nes_batmap_srrx_device::nes_batmap_srrx_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : nes_nrom_device(mconfig, NES_BATMAP_SRRX, tag, owner, clock), m_reg(0), m_dpcm_addr(0), m_dpcm_ctrl(0), m_irq_count(0), m_irq_count_latch(0), m_irq_enable(0)
+{
+}
+
+
+
+void nes_batmap_srrx_device::device_start()
+{
+ common_start();
+ save_item(NAME(m_reg));
+ save_item(NAME(m_dpcm_addr));
+ save_item(NAME(m_dpcm_ctrl));
+ save_item(NAME(m_irq_enable));
+ save_item(NAME(m_irq_count));
+ save_item(NAME(m_irq_count_latch));
+}
+
+void nes_batmap_srrx_device::pcb_reset()
+{
+ prg8_89(0);
+ prg8_ab(0);
+ prg8_cd(3); // 0xd000-0xffff fixed PRG bank
+ prg8_ef(4);
+ chr4_0(0, CHRROM);
+ chr4_4(0x3d, CHRROM); // fixed CHR bank
+
+ m_reg = 0;
+ m_dpcm_addr = 0;
+ m_dpcm_ctrl = 0;
+
+ m_irq_enable = 0;
+ m_irq_count = m_irq_count_latch = 0;
+}
+
+
+/*-------------------------------------------------
+ mapper specific handlers
+ -------------------------------------------------*/
+
+/*-------------------------------------------------
+
+ Batlab BATMAP-SRR-X board
+
+ Games: Super Russian Roulette
+
+ According to dumper it uses a CPLD. This provides PRG
+ and CHR banking, MMC3-like scanline IRQ, and access
+ to an 8MB ROM of DPCM for streaming digitized speech.
+
+ The memory map for reads is as follows:
+
+ 0x4800~ read DPCM data byte (and data pointer++)
+ 0x5000~ 4K fixed to PRG 0x1000
+ 0x6000~ 8K, reg 0
+ 0x8000~ 8K, reg 1
+ 0xA000~ 8K, reg 2
+ 0xC000~ Same as 0x4800
+ 0xD000~ 12K fixed to PRG 0x7000-0xffff
+
+ The DPCM ROM data pointer is at least 23-bits wide
+ and is written serially, by bit, at 0xc000 using
+ the MSB of each write. There is a control register (?)
+ at 0xd000. It's not clear what it does since for each
+ complete sound played it is always written with the
+ sequence 0x01, 0x00, 0x02. Other sources say bit 1 is
+ a flag that turns on/off incrementing of the pointer.
+
+ NES 2.0: mapper 413
+
+ In MAME: Supported.
+
+ -------------------------------------------------*/
+
+// IRQ based on our MMC3 implementation, details for SRR are unclear
+void nes_batmap_srrx_device::hblank_irq(int scanline, int vblank, int blanked)
+{
+ if (scanline < ppu2c0x_device::BOTTOM_VISIBLE_SCANLINE)
+ {
+ if (!m_irq_count)
+ m_irq_count = m_irq_count_latch;
+ else
+ m_irq_count--;
+
+ if (m_irq_enable && !blanked && !m_irq_count)
+ {
+ LOG_MMC(("irq fired, scanline: %d\n", scanline));
+ set_irq_line(ASSERT_LINE);
+ }
+ }
+}
+
+u8 nes_batmap_srrx_device::read_dpcm()
+{
+ m_dpcm_addr &= m_misc_rom_size - 1;
+ return m_misc_rom[m_dpcm_addr++];
+}
+
+u8 nes_batmap_srrx_device::read_l(offs_t offset)
+{
+// LOG_MMC(("batmap_srrx read_l, offset: %04x", offset));
+
+ offset += 0x100;
+ switch (offset & 0x1800)
+ {
+ case 0x0000:
+ return get_open_bus();
+ case 0x0800:
+ return read_dpcm();
+ default:
+ return m_prg[offset]; // fixed to second 4K
+ }
+}
+
+u8 nes_batmap_srrx_device::read_m(offs_t offset)
+{
+// LOG_MMC(("batmap_srrx read_m, offset: %04x", offset));
+ return m_prg[(m_reg * 0x2000 + offset) & (m_prg_size - 1)];
+}
+
+u8 nes_batmap_srrx_device::read_h(offs_t offset)
+{
+ LOG_MMC(("batmap_srrx read_h, offset: %04x", offset));
+
+ if ((offset & 0x7000) == 0x4000)
+ return read_dpcm();
+ else
+ return hi_access_rom(offset);
+}
+
+void nes_batmap_srrx_device::write_h(offs_t offset, u8 data)
+{
+ LOG_MMC(("batmap_srrx write_h, offset: %04x, data: %02x\n", offset, data));
+
+ switch (offset & 0x7000)
+ {
+ case 0x0000:
+ m_irq_count_latch = data;
+ break;
+ case 0x1000:
+ m_irq_count = 0;
+ break;
+ case 0x2000:
+ case 0x3000:
+ m_irq_enable = BIT(offset, 12);
+ if (!m_irq_enable)
+ set_irq_line(CLEAR_LINE);
+ break;
+ case 0x4000:
+ m_dpcm_addr = (m_dpcm_addr << 1 | data >> 7);
+ break;
+ case 0x5000:
+ m_dpcm_ctrl = data;
+ break;
+ case 0x6000:
+ case 0x7000:
+ switch (data >> 6)
+ {
+ case 0: m_reg = data & 0x3f; break;
+ case 1: prg8_89(data & 0x3f); break;
+ case 2: prg8_ab(data & 0x3f); break;
+ case 3: chr4_0(data & 0x3f, CHRROM); break;
+ }
+ break;
+ }
+}
diff --git a/src/devices/bus/nes/batlab.h b/src/devices/bus/nes/batlab.h
new file mode 100644
index 00000000000..2b35d29951d
--- /dev/null
+++ b/src/devices/bus/nes/batlab.h
@@ -0,0 +1,45 @@
+// license:BSD-3-Clause
+// copyright-holders: kmg, Fabio Priuli
+#ifndef MAME_BUS_NES_BATLAB_H
+#define MAME_BUS_NES_BATLAB_H
+
+#pragma once
+
+#include "nxrom.h"
+
+
+// ======================> nes_batmap_srrx_device
+
+class nes_batmap_srrx_device : public nes_nrom_device
+{
+public:
+ // construction/destruction
+ nes_batmap_srrx_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ virtual u8 read_l(offs_t offset) override;
+ virtual u8 read_m(offs_t offset) override;
+ virtual u8 read_h(offs_t offset) override;
+ virtual void write_h(offs_t offset, u8 data) override;
+
+ virtual void hblank_irq(int scanline, int vblank, int blanked) override;
+ virtual void pcb_reset() override;
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+
+private:
+ u8 read_dpcm();
+ u8 m_reg;
+ u32 m_dpcm_addr;
+ u8 m_dpcm_ctrl;
+
+ uint16_t m_irq_count, m_irq_count_latch;
+ int m_irq_enable;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(NES_BATMAP_SRRX, nes_batmap_srrx_device)
+
+#endif // MAME_BUS_NES_BATLAB_H
diff --git a/src/devices/bus/nes/nes_carts.cpp b/src/devices/bus/nes/nes_carts.cpp
index 873f62c5616..6542b54cb73 100644
--- a/src/devices/bus/nes/nes_carts.cpp
+++ b/src/devices/bus/nes/nes_carts.cpp
@@ -34,6 +34,7 @@
#include "act53.h"
#include "aladdin.h"
#include "ave.h"
+#include "batlab.h"
#include "benshieng.h"
#include "camerica.h"
#include "cne.h"
@@ -450,6 +451,7 @@ void nes_cart(device_slot_interface &device)
device.option_add_internal("pjoy84", NES_PJOY84);
device.option_add_internal("nocash_nochr", NES_NOCHR);
device.option_add_internal("action53", NES_ACTION53);
+ device.option_add_internal("batmap_srrx", NES_BATMAP_SRRX);
device.option_add_internal("cufrom", NES_CUFROM);
device.option_add_internal("unrom512", NES_UNROM512);
device.option_add_internal("2a03pur", NES_2A03PURITANS);
diff --git a/src/devices/bus/nes/nes_ines.hxx b/src/devices/bus/nes/nes_ines.hxx
index f7a1790b210..2ad980aee7d 100644
--- a/src/devices/bus/nes/nes_ines.hxx
+++ b/src/devices/bus/nes/nes_ines.hxx
@@ -448,7 +448,7 @@ static const nes_mmc mmc_list[] =
// 410 Unused or JY?
{ 411, BMC_A88S1 },
// 412 INTV 10-in-1 PnP 2nd edition
- // 413 homebrew game Super Russian Roulette
+ { 413, BATMAP_SRRX }, // homebrew game Super Russian Roulette
// 414 9999999-in-1 multicart
{ 415, BTL_0353 }, // Lucky (Roger) Rabbit FDS conversion
{ 416, BMC_N32_4IN1 },
diff --git a/src/devices/bus/nes/nes_pcb.hxx b/src/devices/bus/nes/nes_pcb.hxx
index f57614e27b4..ac1eb21ea54 100644
--- a/src/devices/bus/nes/nes_pcb.hxx
+++ b/src/devices/bus/nes/nes_pcb.hxx
@@ -362,6 +362,7 @@ static const nes_pcb pcb_list[] =
{ "unl_eh8813a", UNL_EH8813A }, // Dr. Mario II
{ "nocash_nochr", NOCASH_NOCHR },
{ "action53", UNL_ACTION53 },
+ { "batmap_srrx", BATMAP_SRRX },
{ "cufrom", UNL_CUFROM },
{ "unrom512", UNL_UNROM512 },
{ "2a03pur", UNL_2A03PURITANS },
@@ -670,7 +671,18 @@ void nes_cart_slot_device::call_load_pcb()
memcpy(m_cart->get_vrom_base(), get_software_region("chr"), vrom_size);
}
- // SETUP steps 7: allocate the remaining pointer, when needed
+ // SETUP steps 7: allocate pointers for any extra chip data, when needed
+ if (m_pcb_id == BATMAP_SRRX)
+ {
+ uint32_t dpcm_size = get_software_region_length("dpcm");
+ if (dpcm_size)
+ {
+ m_cart->misc_rom_alloc(dpcm_size, tag());
+ memcpy(m_cart->get_misc_rom_base(), get_software_region("dpcm"), dpcm_size);
+ }
+ }
+
+ // SETUP steps 8: allocate the remaining pointers, when needed
if (vram_size)
m_cart->vram_alloc(vram_size);
if (prgram_size)
diff --git a/src/devices/bus/nes/nes_slot.cpp b/src/devices/bus/nes/nes_slot.cpp
index f75694bd041..ebaf5ea0406 100644
--- a/src/devices/bus/nes/nes_slot.cpp
+++ b/src/devices/bus/nes/nes_slot.cpp
@@ -117,7 +117,9 @@ device_nes_cart_interface::device_nes_cart_interface(const machine_config &mconf
// main NES CPU here, even if it does not belong to this device.
, m_maincpu(*this, ":maincpu")
, m_mapper_sram(nullptr)
+ , m_misc_rom(nullptr)
, m_mapper_sram_size(0)
+ , m_misc_rom_size(0)
, m_ce_mask(0)
, m_ce_state(0)
, m_vrc_ls_prg_a(0)
@@ -230,6 +232,17 @@ void device_nes_cart_interface::vrom_alloc(size_t size, const char *tag)
}
}
+void device_nes_cart_interface::misc_rom_alloc(size_t size, const char *tag)
+{
+ if (m_misc_rom == nullptr)
+ {
+ std::string tempstring(tag);
+ tempstring.append(NESSLOT_MISC_ROM_REGION_TAG);
+ m_misc_rom = device().machine().memory().region_alloc(tempstring.c_str(), size, 1, ENDIANNESS_LITTLE)->base();
+ m_misc_rom_size = size;
+ }
+}
+
void device_nes_cart_interface::prgram_alloc(size_t size)
{
m_prgram.resize(size);
diff --git a/src/devices/bus/nes/nes_slot.h b/src/devices/bus/nes/nes_slot.h
index 4fddd287a5b..965cbffd4e0 100644
--- a/src/devices/bus/nes/nes_slot.h
+++ b/src/devices/bus/nes/nes_slot.h
@@ -139,9 +139,10 @@ enum
WAIXING_SGZLZ, WAIXING_SGZ, WAIXING_WXZS, WAIXING_SECURITY, WAIXING_SH2,
WAIXING_DQ8, WAIXING_FFV, WAIXING_WXZS2, SUPERGAME_LIONKING, SUPERGAME_BOOGERMAN,
KAY_BOARD, NITRA_TDA, GOUDER_37017, NANJING_BOARD, ZEMINA_BOARD,
+ // homebrew PCBs
NOCASH_NOCHR, // homebrew PCB design which uses NTRAM for CHRRAM
UNL_ACTION53, // homebrew PCB for homebrew multicarts
- UNL_CUFROM, UNL_UNROM512, UNL_2A03PURITANS, // homebrew PCBs
+ BATMAP_SRRX, UNL_CUFROM, UNL_UNROM512, UNL_2A03PURITANS,
// 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)
@@ -196,6 +197,7 @@ public:
void prg_alloc(size_t size, const char *tag);
void vrom_alloc(size_t size, const char *tag);
+ void misc_rom_alloc(size_t size, const char *tag);
void prgram_alloc(size_t size);
void vram_alloc(size_t size);
void battery_alloc(size_t size);
@@ -224,6 +226,7 @@ public:
uint8_t *get_ciram_base() { return m_ciram; }
uint8_t *get_battery_base() { return &m_battery[0]; }
uint8_t *get_mapper_sram_base() { return m_mapper_sram; }
+ uint8_t *get_misc_rom_base() { return m_misc_rom; }
uint32_t get_prg_size() const { return m_prg_size; }
uint32_t get_prgram_size() const { return m_prgram.size(); }
@@ -231,6 +234,7 @@ public:
uint32_t get_vram_size() const { return m_vram.size(); }
uint32_t get_battery_size() const { return m_battery.size(); }
uint32_t get_mapper_sram_size() const { return m_mapper_sram_size; }
+ uint32_t get_misc_rom_size() const { return m_misc_rom_size; }
virtual void ppu_latch(offs_t offset) {}
virtual void hblank_irq(int scanline, int vblank, int blanked) {}
@@ -271,8 +275,10 @@ protected:
// these are specific of some boards but must be accessible from the driver
// E.g. additional save ram for HKROM, X1-005 & X1-017 boards, or ExRAM for MMC5
uint8_t *m_mapper_sram;
+ uint8_t *m_misc_rom;
std::vector<uint8_t> m_ext_ntram;
uint32_t m_mapper_sram_size;
+ uint32_t m_misc_rom_size;
int m_ce_mask;
int m_ce_state;
@@ -449,5 +455,6 @@ DECLARE_DEVICE_TYPE(NES_CART_SLOT, nes_cart_slot_device)
#define NESSLOT_PRGROM_REGION_TAG ":cart:prg_rom"
#define NESSLOT_CHRROM_REGION_TAG ":cart:chr_rom"
+#define NESSLOT_MISC_ROM_REGION_TAG ":cart:misc_rom"
#endif // MAME_BUS_NES_NES_SLOT_H