diff --git a/hash/pce.xml b/hash/pce.xml
index 23be70743d3..fdbb08c9d21 100644
--- a/hash/pce.xml
+++ b/hash/pce.xml
@@ -4502,4 +4502,17 @@ https://mametesters.org/view.php?id=6597
+
+ Arcade Card Pro
+ 1994
+ NEC
+
+
+
+
+
+
+
+
+
diff --git a/hash/pcecd.xml b/hash/pcecd.xml
index 158c0815ff7..374a7913edc 100644
--- a/hash/pcecd.xml
+++ b/hash/pcecd.xml
@@ -63,7 +63,7 @@ license:CC0-1.0
-
+
@@ -374,7 +374,7 @@ https://www.unseen64.net/2021/01/04/angelus2-holynight-pcengine-cancelled/
-
+
@@ -535,7 +535,7 @@ https://www.unseen64.net/2021/01/04/angelus2-holynight-pcengine-cancelled/
-
+
@@ -1413,7 +1413,7 @@ Returns to intro when pressing Run button on title (player has to hold start in
-
+
@@ -1675,7 +1675,7 @@ Cheat: Up, up, up, down, down, down, II, II, II, I, I, I during intro for "debug
-
+
@@ -1740,7 +1740,7 @@ Uses sound LFO FM
-
+
@@ -1941,7 +1941,7 @@ Unsupported [セーブくん] joypad slot peripheral
-
+
@@ -1957,7 +1957,7 @@ Unsupported [セーブくん] joypad slot peripheral
-
+
@@ -1973,7 +1973,7 @@ Unsupported [セーブくん] joypad slot peripheral
-
+
@@ -2037,7 +2037,7 @@ Unsupported [セーブくん] joypad slot peripheral
-
+
@@ -2473,7 +2473,7 @@ New game intro sports glitchy portraits
-
+
@@ -2505,7 +2505,7 @@ New game intro sports glitchy portraits
-
+
@@ -3058,7 +3058,7 @@ Hangs after first attack turn (shoot to the foe behind the tree) (fixed)
-
+
@@ -3197,7 +3197,7 @@ Verify [redbook] lip sync and repeat (uses track mode)
-
+
@@ -3210,7 +3210,7 @@ Verify [redbook] lip sync and repeat (uses track mode)
1994
NEC Home Electronics
-
+
@@ -3226,7 +3226,7 @@ Verify [redbook] lip sync and repeat (uses track mode)
-
+
@@ -3246,7 +3246,7 @@ Crashes on (skippable) new game intro, [SCSI] timing sensitive
-
+
@@ -3342,7 +3342,7 @@ Crashes on (skippable) new game intro, [SCSI] timing sensitive
-
+
@@ -4251,7 +4251,7 @@ Unsupported [セーブくん] joypad slot peripheral
-
+
@@ -4284,7 +4284,7 @@ Unsupported [セーブくん] joypad slot peripheral
-
+
@@ -4912,7 +4912,7 @@ Hangs on technique screen after level select (assuming you pick them up in stage
-
+
@@ -4925,7 +4925,7 @@ Hangs on technique screen after level select (assuming you pick them up in stage
1994
Hudson
-
+
@@ -5100,7 +5100,7 @@ Unsupported [セーブくん] joypad slot peripheral
-
+
@@ -5539,7 +5539,7 @@ Offset [CRTC] screen
-
+
@@ -5738,7 +5738,7 @@ Eventually hangs requiring a transfer ready irq [SCSI] (untested)
-
+
@@ -5914,7 +5914,7 @@ Eventually hangs requiring a transfer ready irq [SCSI] (untested)
-
+
@@ -5946,7 +5946,7 @@ Eventually hangs requiring a transfer ready irq [SCSI] (untested)
-
+
@@ -6087,7 +6087,7 @@ Eventually hangs requiring a transfer ready irq [SCSI] (untested)
-
+
@@ -6183,7 +6183,7 @@ Eventually hangs requiring a transfer ready irq [SCSI] (untested)
-
+
@@ -6295,7 +6295,7 @@ Eventually hangs requiring a transfer ready irq [SCSI] (untested)
-
+
@@ -6778,7 +6778,7 @@ Cuts off [ADPCM] playback, enables half irq
-
+
@@ -6893,7 +6893,7 @@ Hangs or resets after giving yes to "Is it OK?" prompt (fixed)
-
+
@@ -6907,7 +6907,7 @@ Hangs or resets after giving yes to "Is it OK?" prompt (fixed)
Hudson
-
+
@@ -6923,7 +6923,7 @@ Hangs or resets after giving yes to "Is it OK?" prompt (fixed)
-
+
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index 6d720410673..6891b5d1d9a 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -4257,6 +4257,10 @@ if (BUSES["PCE"]~=null) then
MAME_DIR .. "src/devices/bus/pce/pce_slot.h",
MAME_DIR .. "src/devices/bus/pce/pce_rom.cpp",
MAME_DIR .. "src/devices/bus/pce/pce_rom.h",
+ MAME_DIR .. "src/devices/bus/pce/pce_scdsys.cpp",
+ MAME_DIR .. "src/devices/bus/pce/pce_scdsys.h",
+ MAME_DIR .. "src/devices/bus/pce/pce_acard.cpp",
+ MAME_DIR .. "src/devices/bus/pce/pce_acard.h",
}
end
diff --git a/src/devices/bus/pce/pce_acard.cpp b/src/devices/bus/pce/pce_acard.cpp
new file mode 100644
index 00000000000..9a6d81403e0
--- /dev/null
+++ b/src/devices/bus/pce/pce_acard.cpp
@@ -0,0 +1,232 @@
+// license:BSD-3-Clause
+// copyright-holders:Fabio Priuli, Angelo Salese
+/***********************************************************************************************************
+
+
+ PC-Engine Arcade Card emulation
+
+ TODO:
+ - Proper Arcade Card Duo support
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "pce_acard.h"
+
+
+
+//-------------------------------------------------
+// pce_acard_device - constructor
+//-------------------------------------------------
+
+DEFINE_DEVICE_TYPE(PCE_ROM_ACARD_DUO, pce_acard_duo_device, "pce_acard_duo", "Arcade Card Duo")
+DEFINE_DEVICE_TYPE(PCE_ROM_ACARD_PRO, pce_acard_pro_device, "pce_acard_pro", "Arcade Card Pro")
+
+
+pce_acard_duo_device::pce_acard_duo_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , device_pce_cart_interface( mconfig, *this )
+ , m_ram(*this, "ram", 0x200000, ENDIANNESS_LITTLE)
+ , m_shift(0)
+ , m_shift_reg(0)
+ , m_rotate_reg(0)
+{
+}
+
+pce_acard_duo_device::pce_acard_duo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : pce_acard_duo_device(mconfig, PCE_ROM_ACARD_DUO, tag, owner, clock)
+{
+}
+
+pce_acard_pro_device::pce_acard_pro_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : pce_acard_duo_device(mconfig, PCE_ROM_ACARD_PRO, tag, owner, clock)
+ , m_scdsys()
+{
+}
+
+
+//-------------------------------------------------
+// mapper specific start/reset
+//-------------------------------------------------
+
+
+void pce_acard_duo_device::device_start()
+{
+ save_item(STRUCT_MEMBER(m_port, m_ctrl));
+ save_item(STRUCT_MEMBER(m_port, m_base_addr));
+ save_item(STRUCT_MEMBER(m_port, m_addr_offset));
+ save_item(STRUCT_MEMBER(m_port, m_addr_inc));
+ save_item(NAME(m_shift));
+ save_item(NAME(m_shift_reg));
+ save_item(NAME(m_rotate_reg));
+}
+
+void pce_acard_pro_device::device_start()
+{
+ pce_acard_duo_device::device_start();
+
+ m_scdsys.init(*this);
+ m_scdsys.set_region(false);
+}
+
+void pce_acard_duo_device::device_reset()
+{
+ for (auto &port : m_port)
+ {
+ port.m_ctrl = 0;
+ port.m_base_addr = 0;
+ port.m_addr_offset = 0;
+ port.m_addr_inc = 0;
+ }
+ m_shift = 0;
+ m_shift_reg = 0;
+ m_rotate_reg = 0;
+}
+
+/*-------------------------------------------------
+ mapper specific handlers
+ -------------------------------------------------*/
+
+void pce_acard_duo_device::install_memory_handlers(address_space &space)
+{
+ space.install_readwrite_handler(0x080000, 0x087fff, emu::rw_delegate(*this, FUNC(pce_acard_duo_device::ram_r)), emu::rw_delegate(*this, FUNC(pce_acard_duo_device::ram_w)));
+ // TODO: mirrored?
+ space.install_readwrite_handler(0x1ffa00, 0x1ffaff, 0, 0x100, 0, emu::rw_delegate(*this, FUNC(pce_acard_duo_device::peripheral_r)), emu::rw_delegate(*this, FUNC(pce_acard_duo_device::peripheral_w)));
+}
+
+void pce_acard_pro_device::install_memory_handlers(address_space &space)
+{
+ space.install_rom(0x000000, 0x03ffff, 0x040000, m_rom); // TODO: underdumped or mirrored?
+ space.install_ram(0x0d0000, 0x0fffff, m_scdsys.ram());
+ space.install_read_handler(0x1ff8c0, 0x1ff8c7, 0, 0x130, 0, emu::rw_delegate(*this, FUNC(pce_acard_pro_device::register_r)));
+ pce_acard_duo_device::install_memory_handlers(space);
+}
+
+uint8_t pce_acard_duo_device::ram_r(offs_t offset)
+{
+ return peripheral_r((offset & 0x6000) >> 9);
+}
+
+void pce_acard_duo_device::ram_w(offs_t offset, uint8_t data)
+{
+ peripheral_w((offset & 0x6000) >> 9, data);
+}
+
+uint8_t pce_acard_duo_device::peripheral_r(offs_t offset)
+{
+ if ((offset & 0xe0) == 0xe0)
+ {
+ switch (offset & 0x1f)
+ {
+ case 0x00: return (m_shift >> 0) & 0xff;
+ case 0x01: return (m_shift >> 8) & 0xff;
+ case 0x02: return (m_shift >> 16) & 0xff;
+ case 0x03: return (m_shift >> 24) & 0xff;
+ case 0x04: return m_shift_reg;
+ case 0x05: return m_rotate_reg;
+ case 0x1c: return 0x00;
+ case 0x1d: return 0x00;
+ case 0x1e: return 0x10; // Version number (MSB?)
+ case 0x1f: return 0x51; // Arcade Card ID
+ }
+
+ return 0xff;
+ }
+
+ dram_port &port = m_port[(offset & 0x30) >> 4];
+
+ switch (offset & 0x8f)
+ {
+ case 0x00:
+ case 0x01:
+ {
+ uint8_t const res = m_ram[port.ram_addr()];
+
+ if (!machine().side_effects_disabled())
+ port.addr_increment();
+
+ return res;
+ }
+ case 0x02: return (port.m_base_addr >> 0) & 0xff;
+ case 0x03: return (port.m_base_addr >> 8) & 0xff;
+ case 0x04: return (port.m_base_addr >> 16) & 0xff;
+ case 0x05: return (port.m_addr_offset >> 0) & 0xff;
+ case 0x06: return (port.m_addr_offset >> 8) & 0xff;
+ case 0x07: return (port.m_addr_inc >> 0) & 0xff;
+ case 0x08: return (port.m_addr_inc >> 8) & 0xff;
+ case 0x09: return port.m_ctrl;
+ default: return 0xff;
+ }
+}
+
+void pce_acard_duo_device::peripheral_w(offs_t offset, uint8_t data)
+{
+ if ((offset & 0xe0) == 0xe0)
+ {
+ switch (offset & 0x0f)
+ {
+ case 0: m_shift = (data & 0xff) | (m_shift & 0xffffff00); break;
+ case 1: m_shift = (data << 8) | (m_shift & 0xffff00ff); break;
+ case 2: m_shift = (data << 16) | (m_shift & 0xff00ffff); break;
+ case 3: m_shift = (data << 24) | (m_shift & 0x00ffffff); break;
+ case 4:
+ m_shift_reg = data & 0x0f;
+
+ if (m_shift_reg != 0)
+ {
+ m_shift = (m_shift_reg < 8)
+ ? (m_shift << m_shift_reg)
+ : (m_shift >> (16 - m_shift_reg));
+ }
+ break;
+ case 5:
+ m_rotate_reg = data & 0x0f;
+
+ if (m_rotate_reg != 0)
+ {
+ m_shift = (m_rotate_reg < 8)
+ ? ((m_shift << m_rotate_reg) | (m_shift >> (32 - m_rotate_reg)))
+ : ((m_shift >> (16 - m_rotate_reg)) | (m_shift << (32 - (16 - m_rotate_reg))));
+ }
+ break;
+ }
+ }
+ else
+ {
+ dram_port &port = m_port[(offset & 0x30) >> 4];
+
+ switch (offset & 0x8f)
+ {
+ case 0x00:
+ case 0x01:
+ m_ram[port.ram_addr()] = data;
+
+ port.addr_increment();
+ break;
+
+ case 0x02: port.m_base_addr = (data & 0xff) | (port.m_base_addr & 0xffff00); break;
+ case 0x03: port.m_base_addr = (data << 8) | (port.m_base_addr & 0xff00ff); break;
+ case 0x04: port.m_base_addr = (data << 16) | (port.m_base_addr & 0x00ffff); break;
+ case 0x05:
+ port.m_addr_offset = (data & 0xff) | (port.m_addr_offset & 0xff00);
+
+ if ((port.m_ctrl & 0x60) == 0x20)
+ port.adjust_addr();
+ break;
+ case 0x06:
+ port.m_addr_offset = (data << 8) | (port.m_addr_offset & 0x00ff);
+
+ if ((port.m_ctrl & 0x60) == 0x40)
+ port.adjust_addr();
+ break;
+ case 0x07: port.m_addr_inc = (data & 0xff) | (port.m_addr_inc & 0xff00); break;
+ case 0x08: port.m_addr_inc = (data << 8) | (port.m_addr_inc & 0x00ff); break;
+ case 0x09: port.m_ctrl = data & 0x7f; break;
+ case 0x0a:
+ if ((port.m_ctrl & 0x60) == 0x60)
+ port.adjust_addr();
+ break;
+ }
+ }
+}
diff --git a/src/devices/bus/pce/pce_acard.h b/src/devices/bus/pce/pce_acard.h
new file mode 100644
index 00000000000..2c3622ac2b2
--- /dev/null
+++ b/src/devices/bus/pce/pce_acard.h
@@ -0,0 +1,114 @@
+// license:BSD-3-Clause
+// copyright-holders:Fabio Priuli, Angelo Salese
+#ifndef MAME_BUS_PCE_PCE_ACARD_H
+#define MAME_BUS_PCE_PCE_ACARD_H
+
+#pragma once
+
+#include "pce_scdsys.h"
+#include "pce_slot.h"
+
+
+// ======================> pce_acard_duo_device
+
+class pce_acard_duo_device : public device_t,
+ public device_pce_cart_interface
+{
+public:
+ // construction/destruction
+ pce_acard_duo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // reading and writing
+ virtual void install_memory_handlers(address_space &space) override;
+
+protected:
+ // construction/destruction
+ pce_acard_duo_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ uint8_t ram_r(offs_t offset);
+ void ram_w(offs_t offset, uint8_t data);
+ uint8_t peripheral_r(offs_t offset);
+ void peripheral_w(offs_t offset, uint8_t data);
+
+ /* Arcade Card specific */
+ memory_share_creator m_ram;
+
+ struct dram_port
+ {
+ uint32_t ram_addr()
+ {
+ if (BIT(m_ctrl, 1))
+ return (m_base_addr + m_addr_offset + (BIT(m_ctrl, 3) ? 0xff0000 : 0)) & 0x1fffff;
+ else
+ return m_base_addr & 0x1fffff;
+ }
+
+ void addr_increment()
+ {
+ if (BIT(m_ctrl, 0))
+ {
+ if (BIT(m_ctrl, 4))
+ {
+ m_base_addr += m_addr_inc;
+ m_base_addr &= 0xffffff;
+ }
+ else
+ {
+ m_addr_offset += m_addr_inc;
+ }
+ }
+ }
+
+ void adjust_addr()
+ {
+ m_base_addr += m_addr_offset + (BIT(m_ctrl, 3) ? 0xff0000 : 0);
+ m_base_addr &= 0xffffff;
+ }
+
+ uint8_t m_ctrl;
+ uint32_t m_base_addr;
+ uint16_t m_addr_offset;
+ uint16_t m_addr_inc;
+ };
+
+ dram_port m_port[4];
+ uint32_t m_shift;
+ uint8_t m_shift_reg;
+ uint8_t m_rotate_reg;
+};
+
+
+// ======================> pce_acard_duo_device
+
+class pce_acard_pro_device : public pce_acard_duo_device
+
+{
+public:
+ // construction/destruction
+ pce_acard_pro_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // reading and writing
+ virtual void install_memory_handlers(address_space &space) override;
+
+protected:
+ virtual void device_start() override;
+
+private:
+ pce_scdsys_shared m_scdsys;
+
+ // reading
+ uint8_t register_r(offs_t offset) { return m_scdsys.register_r(offset); }
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(PCE_ROM_ACARD_DUO, pce_acard_duo_device)
+DECLARE_DEVICE_TYPE(PCE_ROM_ACARD_PRO, pce_acard_pro_device)
+
+
+#endif // MAME_BUS_PCE_PCE_ACARD_H
diff --git a/src/devices/bus/pce/pce_rom.cpp b/src/devices/bus/pce/pce_rom.cpp
index 947354005c9..64d2e1e1e9f 100644
--- a/src/devices/bus/pce/pce_rom.cpp
+++ b/src/devices/bus/pce/pce_rom.cpp
@@ -18,16 +18,15 @@
// pce_rom_device - constructor
//-------------------------------------------------
-DEFINE_DEVICE_TYPE(PCE_ROM_STD, pce_rom_device, "pce_rom", "PCE/TG16 HuCards")
-DEFINE_DEVICE_TYPE(PCE_ROM_CDSYS3, pce_cdsys3_device, "pce_cdsys3", "PCE/TG16 CD-System HuCard v3.00")
-DEFINE_DEVICE_TYPE(PCE_ROM_POPULOUS, pce_populous_device, "pce_populous", "PCE Populous HuCard")
-DEFINE_DEVICE_TYPE(PCE_ROM_SF2, pce_sf2_device, "pce_sf2", "PCE Street Fighter 2 CE HuCard")
-DEFINE_DEVICE_TYPE(PCE_ROM_TENNOKOE, pce_tennokoe_device, "pce_tennokoe", "PCE Tennokoe Bank HuCard")
+DEFINE_DEVICE_TYPE(PCE_ROM_STD, pce_rom_device, "pce_rom", "PCE/TG16 HuCards")
+DEFINE_DEVICE_TYPE(PCE_ROM_POPULOUS, pce_populous_device, "pce_populous", "PCE Populous HuCard")
+DEFINE_DEVICE_TYPE(PCE_ROM_SF2, pce_sf2_device, "pce_sf2", "PCE Street Fighter 2 CE HuCard")
+DEFINE_DEVICE_TYPE(PCE_ROM_TENNOKOE, pce_tennokoe_device, "pce_tennokoe", "PCE Tennokoe Bank HuCard")
pce_rom_device::pce_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
- , device_pce_cart_interface( mconfig, *this )
+ , device_pce_cart_interface(mconfig, *this)
{
}
@@ -36,24 +35,20 @@ pce_rom_device::pce_rom_device(const machine_config &mconfig, const char *tag, d
{
}
-pce_cdsys3_device::pce_cdsys3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : pce_rom_device(mconfig, PCE_ROM_CDSYS3, tag, owner, clock)
-{
-}
-
pce_populous_device::pce_populous_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: pce_rom_device(mconfig, PCE_ROM_POPULOUS, tag, owner, clock)
{
}
pce_sf2_device::pce_sf2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : pce_rom_device(mconfig, PCE_ROM_SF2, tag, owner, clock), m_bank_base(0)
+ : pce_rom_device(mconfig, PCE_ROM_SF2, tag, owner, clock)
+ , m_rom_bank(*this, "rom_bank")
{
}
pce_tennokoe_device::pce_tennokoe_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : pce_rom_device(mconfig, PCE_ROM_TENNOKOE, tag, owner, clock),
- device_nvram_interface(mconfig, *this)
+ : pce_rom_device(mconfig, PCE_ROM_TENNOKOE, tag, owner, clock)
+ , device_nvram_interface(mconfig, *this)
{
}
@@ -63,14 +58,9 @@ pce_tennokoe_device::pce_tennokoe_device(const machine_config &mconfig, const ch
//-------------------------------------------------
-void pce_sf2_device::device_start()
-{
- save_item(NAME(m_bank_base));
-}
-
void pce_sf2_device::device_reset()
{
- m_bank_base = 0;
+ m_rom_bank->set_entry(0);
}
void pce_tennokoe_device::device_start()
@@ -128,98 +118,65 @@ bool pce_tennokoe_device::nvram_write(util::write_stream &file)
mapper specific handlers
-------------------------------------------------*/
-uint8_t pce_rom_device::read_cart(offs_t offset)
+uint8_t pce_rom_device::rom_r(offs_t offset)
{
int bank = offset / 0x20000;
return m_rom[rom_bank_map[bank] * 0x20000 + (offset & 0x1ffff)];
}
-
-uint8_t pce_cdsys3_device::read_cart(offs_t offset)
+void pce_rom_device::install_memory_handlers(address_space &space)
{
- int bank = offset / 0x20000;
- if (!m_ram.empty() && offset >= 0xd0000)
- return m_ram[offset - 0xd0000];
-
- return m_rom[rom_bank_map[bank] * 0x20000 + (offset & 0x1ffff)];
-}
-
-void pce_cdsys3_device::write_cart(offs_t offset, uint8_t data)
-{
- if (!m_ram.empty() && offset >= 0xd0000)
- m_ram[offset - 0xd0000] = data;
+ space.install_read_handler(0x00000, 0xfffff, emu::rw_delegate(*this, FUNC(pce_rom_device::rom_r)));
}
-uint8_t pce_populous_device::read_cart(offs_t offset)
+void pce_populous_device::install_memory_handlers(address_space &space)
{
- int bank = offset / 0x20000;
- if (!m_ram.empty() && offset >= 0x80000 && offset < 0x88000)
- return m_ram[offset & 0x7fff];
-
- return m_rom[rom_bank_map[bank] * 0x20000 + (offset & 0x1ffff)];
-}
-
-void pce_populous_device::write_cart(offs_t offset, uint8_t data)
-{
- if (!m_ram.empty() && offset >= 0x80000 && offset < 0x88000)
- m_ram[offset & 0x7fff] = data;
+ pce_rom_device::install_memory_handlers(space);
+ space.install_ram(0x80000, 0x87fff, &m_ram[0]);
}
-uint8_t pce_sf2_device::read_cart(offs_t offset)
+void pce_sf2_device::bank_w(offs_t offset, uint8_t data)
{
- if (offset < 0x80000)
- return m_rom[offset];
+ m_rom_bank->set_entry(offset & 3);
+}
+
+
+void pce_sf2_device::install_memory_handlers(address_space &space)
+{
+ m_rom_bank->configure_entries(0, 4, m_rom + 0x80000, 0x80000);
+ space.install_rom(0x000000, 0x07ffff, m_rom);
+ space.install_read_bank(0x080000, 0x0fffff, m_rom_bank);
+ space.install_write_handler(0x001ff0, 0x001ff3, emu::rw_delegate(*this, FUNC(pce_sf2_device::bank_w)));
+}
+
+
+uint8_t pce_tennokoe_device::bram_r(offs_t offset)
+{
+ if (m_bram_locked)
+ return 0xff;
else
- return m_rom[0x80000 + m_bank_base * 0x80000 + (offset & 0x7ffff)];
+ return m_bram[offset & (m_bram_size-1)];
}
-void pce_sf2_device::write_cart(offs_t offset, uint8_t data)
+void pce_tennokoe_device::bram_w(offs_t offset, uint8_t data)
{
- if (offset >= 0x1ff0 && offset < 0x1ff4)
- m_bank_base = offset & 3;
+ if (!m_bram_locked)
+ m_bram[offset & (m_bram_size-1)] = data;
}
-uint8_t pce_tennokoe_device::read_cart(offs_t offset)
+void pce_tennokoe_device::bram_lock_w(offs_t offset, uint8_t data)
{
- switch((offset & 0xf0000) >> 16)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- return m_rom[offset];
- case 8:
- if (m_bram_locked)
- return 0xff;
- else
- return m_bram[offset & (m_bram_size-1)];
- }
-
- logerror("tennokoe: ROM reading at %06x\n",offset);
- return 0xff;
+ // TODO: lock/unlock mechanism is a complete guess, needs real HW study
+ m_bram_locked = (data == 0);
}
-void pce_tennokoe_device::write_cart(offs_t offset, uint8_t data)
+void pce_tennokoe_device::install_memory_handlers(address_space &space)
{
- switch((offset & 0xf0000) >> 16)
- {
- case 8:
- if(!m_bram_locked)
- m_bram[offset & (m_bram_size-1)] = data;
- break;
- case 0xf:
- // TODO: lock/unlock mechanism is a complete guess, needs real HW study
- // (writes to ports $c0000, $d0000, $f0000)
- m_bram_locked = (data == 0);
- [[fallthrough]];
- default:
- logerror("tennokoe: ROM writing at %06x %02x\n",offset,data);
- break;
- }
+ space.install_rom(0x000000, 0x07ffff, m_rom);
+ space.install_readwrite_handler(0x080000, 0x081fff, 0, 0x00e000, 0, emu::rw_delegate(*this, FUNC(pce_tennokoe_device::bram_r)), emu::rw_delegate(*this, FUNC(pce_tennokoe_device::bram_w)));
+ // (writes to ports $c0000, $d0000, $f0000)
+ space.install_write_handler(0x0f0000, 0x0f0000, 0, 0x00ffff, 0, emu::rw_delegate(*this, FUNC(pce_tennokoe_device::bram_lock_w)));
}
+
diff --git a/src/devices/bus/pce/pce_rom.h b/src/devices/bus/pce/pce_rom.h
index 43499851eb7..714e891706f 100644
--- a/src/devices/bus/pce/pce_rom.h
+++ b/src/devices/bus/pce/pce_rom.h
@@ -19,7 +19,7 @@ public:
pce_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// reading and writing
- virtual uint8_t read_cart(offs_t offset) override;
+ virtual void install_memory_handlers(address_space &space) override;
protected:
pce_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
@@ -27,24 +27,10 @@ protected:
// device-level overrides
virtual void device_start() override { }
virtual void device_reset() override { }
+
+ uint8_t rom_r(offs_t offset);
};
-// ======================> pce_cdsys3_device
-
-class pce_cdsys3_device : public pce_rom_device
-{
-public:
- // construction/destruction
- pce_cdsys3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- // reading and writing
- virtual uint8_t read_cart(offs_t offset) override;
- virtual void write_cart(offs_t offset, uint8_t data) override;
-};
-
-
-// ======================> pce_populous_device
-
class pce_populous_device : public pce_rom_device
{
public:
@@ -52,11 +38,9 @@ public:
pce_populous_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// reading and writing
- virtual uint8_t read_cart(offs_t offset) override;
- virtual void write_cart(offs_t offset, uint8_t data) override;
+ virtual void install_memory_handlers(address_space &space) override;
};
-
// ======================> pce_sf2_device
class pce_sf2_device : public pce_rom_device
@@ -66,16 +50,16 @@ public:
pce_sf2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// reading and writing
- virtual uint8_t read_cart(offs_t offset) override;
- virtual void write_cart(offs_t offset, uint8_t data) override;
+ virtual void install_memory_handlers(address_space &space) override;
protected:
// device-level overrides
- virtual void device_start() override;
virtual void device_reset() override;
private:
- uint8_t m_bank_base;
+ void bank_w(offs_t offset, uint8_t data);
+
+ memory_bank_creator m_rom_bank;
};
// ======================> pce_tennokoe_device
@@ -88,8 +72,7 @@ public:
pce_tennokoe_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// reading and writing
- virtual uint8_t read_cart(offs_t offset) override;
- virtual void write_cart(offs_t offset, uint8_t data) override;
+ virtual void install_memory_handlers(address_space &space) override;
protected:
// device-level overrides
@@ -100,6 +83,10 @@ protected:
virtual bool nvram_write(util::write_stream &file) override;
private:
+ uint8_t bram_r(offs_t offset);
+ void bram_w(offs_t offset, uint8_t data);
+ void bram_lock_w(offs_t offset, uint8_t data);
+
const uint32_t m_bram_size = 0x800*4;
uint8_t m_bram[0x800*4];
@@ -108,11 +95,10 @@ private:
// device type definition
-DECLARE_DEVICE_TYPE(PCE_ROM_STD, pce_rom_device)
-DECLARE_DEVICE_TYPE(PCE_ROM_CDSYS3, pce_cdsys3_device)
-DECLARE_DEVICE_TYPE(PCE_ROM_POPULOUS, pce_populous_device)
-DECLARE_DEVICE_TYPE(PCE_ROM_SF2, pce_sf2_device)
-DECLARE_DEVICE_TYPE(PCE_ROM_TENNOKOE, pce_tennokoe_device)
+DECLARE_DEVICE_TYPE(PCE_ROM_STD, pce_rom_device)
+DECLARE_DEVICE_TYPE(PCE_ROM_POPULOUS, pce_populous_device)
+DECLARE_DEVICE_TYPE(PCE_ROM_SF2, pce_sf2_device)
+DECLARE_DEVICE_TYPE(PCE_ROM_TENNOKOE, pce_tennokoe_device)
#endif // MAME_BUS_PCE_PCE_ROM_H
diff --git a/src/devices/bus/pce/pce_scdsys.cpp b/src/devices/bus/pce/pce_scdsys.cpp
new file mode 100644
index 00000000000..78b413f9d31
--- /dev/null
+++ b/src/devices/bus/pce/pce_scdsys.cpp
@@ -0,0 +1,98 @@
+// license:BSD-3-Clause
+// copyright-holders:Fabio Priuli, Wilbert Pol
+/***********************************************************************************************************
+
+
+ PC-Engine & Turbografx-16 Super System Card emulation
+
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "pce_scdsys.h"
+
+
+
+//-------------------------------------------------
+// pce_cdsys3_device - constructor
+//-------------------------------------------------
+
+DEFINE_DEVICE_TYPE(PCE_ROM_CDSYS3J, pce_cdsys3j_device, "pce_cdsys3j", "PCE Super System Card")
+DEFINE_DEVICE_TYPE(PCE_ROM_CDSYS3U, pce_cdsys3u_device, "pce_cdsys3u", "TG16 Super System Card")
+
+
+pce_cdsys3_device::pce_cdsys3_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , device_pce_cart_interface(mconfig, *this)
+ , m_scdsys()
+{
+}
+
+pce_cdsys3j_device::pce_cdsys3j_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : pce_cdsys3_device(mconfig, PCE_ROM_CDSYS3J, tag, owner, clock)
+{
+}
+
+pce_cdsys3u_device::pce_cdsys3u_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : pce_cdsys3_device(mconfig, PCE_ROM_CDSYS3U, tag, owner, clock)
+{
+}
+
+pce_scdsys_shared::pce_scdsys_shared()
+ : m_ram(nullptr)
+ , m_region(false)
+{
+}
+
+
+//-------------------------------------------------
+// mapper specific start/reset
+//-------------------------------------------------
+
+void pce_cdsys3_device::device_start()
+{
+ m_scdsys.init(*this);
+ m_scdsys.set_region(false);
+}
+
+void pce_cdsys3u_device::device_start()
+{
+ pce_cdsys3_device::device_start();
+ m_scdsys.set_region(true);
+}
+
+void pce_scdsys_shared::init(device_t &device)
+{
+ m_ram = make_unique_clear(0x30000);
+
+ device.save_pointer(NAME(m_ram), 0x30000);
+}
+
+/*-------------------------------------------------
+ mapper specific handlers
+ -------------------------------------------------*/
+
+uint8_t pce_scdsys_shared::register_r(offs_t offset)
+{
+ switch (offset & 0x0f)
+ {
+ // TODO: 0x1 through 0x3 is Super CD-ROM²/PCE Duo stuff?
+ case 0x1: return 0xaa;
+ case 0x2: return 0x55;
+ case 0x3: return 0x00;
+ case 0x5: return (m_region) ? 0x55 : 0xaa;
+ case 0x6: return (m_region) ? 0xaa : 0x55;
+ case 0x7: return 0x03;
+ }
+ return 0x00;
+}
+
+
+void pce_cdsys3_device::install_memory_handlers(address_space &space)
+{
+ // TODO: ROM address mirrored?
+ space.install_rom(0x000000, 0x03ffff, 0x040000, m_rom);
+ space.install_ram(0x0d0000, 0x0fffff, m_scdsys.ram());
+ space.install_read_handler(0x1ff8c0, 0x1ff8c7, 0, 0x330, 0, emu::rw_delegate(*this, FUNC(pce_cdsys3_device::register_r)));
+}
diff --git a/src/devices/bus/pce/pce_scdsys.h b/src/devices/bus/pce/pce_scdsys.h
new file mode 100644
index 00000000000..1a4220bdc57
--- /dev/null
+++ b/src/devices/bus/pce/pce_scdsys.h
@@ -0,0 +1,83 @@
+// license:BSD-3-Clause
+// copyright-holders:Fabio Priuli, Wilbert Pol
+#ifndef MAME_BUS_PCE_PCE_SCDSYS_H
+#define MAME_BUS_PCE_PCE_SCDSYS_H
+
+#pragma once
+
+#include "pce_slot.h"
+
+
+// ======================> pce_scdsys_shared
+
+class pce_scdsys_shared
+{
+public:
+ // construction/destruction
+ pce_scdsys_shared();
+
+ // configuration
+ void set_region(bool region) { m_region = region; }
+
+ // reading and writing
+ uint8_t register_r(offs_t offset);
+
+ uint8_t *ram() { return m_ram.get(); }
+
+ void init(device_t &device);
+
+private:
+ std::unique_ptr m_ram; // internal RAM
+ bool m_region; // Cartridge region
+};
+
+// ======================> pce_cdsys3_device
+
+class pce_cdsys3_device : public device_t,
+ public device_pce_cart_interface
+{
+public:
+ // reading and writing
+ virtual void install_memory_handlers(address_space &space) override;
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+
+ // construction/destruction
+ pce_cdsys3_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ // helper classes
+ pce_scdsys_shared m_scdsys;
+
+ // reading
+ uint8_t register_r(offs_t offset) { return m_scdsys.register_r(offset); }
+};
+
+// ======================> pce_cdsys3j_device
+
+class pce_cdsys3j_device : public pce_cdsys3_device
+{
+public:
+ // construction/destruction
+ pce_cdsys3j_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+};
+
+// ======================> pce_cdsys3u_device
+
+class pce_cdsys3u_device : public pce_cdsys3_device
+{
+public:
+ // construction/destruction
+ pce_cdsys3u_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual void device_start() override;
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(PCE_ROM_CDSYS3J, pce_cdsys3j_device)
+DECLARE_DEVICE_TYPE(PCE_ROM_CDSYS3U, pce_cdsys3u_device)
+
+
+#endif // MAME_BUS_PCE_PCE_SCDSYS_H
diff --git a/src/devices/bus/pce/pce_slot.cpp b/src/devices/bus/pce/pce_slot.cpp
index 5da567d4931..15c0062ea13 100644
--- a/src/devices/bus/pce/pce_slot.cpp
+++ b/src/devices/bus/pce/pce_slot.cpp
@@ -139,7 +139,9 @@ pce_cart_slot_device::pce_cart_slot_device(const machine_config &mconfig, const
device_cartrom_image_interface(mconfig, *this),
device_single_card_slot_interface(mconfig, *this),
m_interface("pce_cart"),
- m_type(PCE_STD), m_cart(nullptr)
+ m_type(PCE_STD),
+ m_cart(nullptr),
+ m_address_space(*this, finder_base::DUMMY_TAG, -1, 8)
{
}
@@ -181,6 +183,8 @@ static const pce_slot slot_list[] =
{ PCE_POPULOUS, "populous" },
{ PCE_SF2, "sf2" },
{ PCE_TENNOKOE, "tennokoe" },
+ { PCE_ACARD_DUO, "acard_duo" },
+ { PCE_ACARD_PRO, "acard_pro" },
};
static int pce_get_pcb_id(const char *slot)
@@ -260,8 +264,8 @@ std::pair pce_cart_slot_device::call_load()
if (m_type == PCE_POPULOUS)
m_cart->ram_alloc(0x8000);
- if (m_type == PCE_CDSYS3J || m_type == PCE_CDSYS3U)
- m_cart->ram_alloc(0x30000);
+
+ m_cart->install_memory_handlers(*m_address_space);
}
return std::make_pair(std::error_condition(), std::string());
@@ -333,25 +337,3 @@ std::string pce_cart_slot_device::get_default_card_software(get_default_card_sof
return software_get_default_slot("rom");
}
-
-/*-------------------------------------------------
- read
- -------------------------------------------------*/
-
-uint8_t pce_cart_slot_device::read_cart(offs_t offset)
-{
- if (m_cart)
- return m_cart->read_cart(offset);
- else
- return 0xff;
-}
-
-/*-------------------------------------------------
- write
- -------------------------------------------------*/
-
-void pce_cart_slot_device::write_cart(offs_t offset, uint8_t data)
-{
- if (m_cart)
- m_cart->write_cart(offset, data);
-}
diff --git a/src/devices/bus/pce/pce_slot.h b/src/devices/bus/pce/pce_slot.h
index c78c1f536ad..337214d0b81 100644
--- a/src/devices/bus/pce/pce_slot.h
+++ b/src/devices/bus/pce/pce_slot.h
@@ -21,7 +21,9 @@ enum
PCE_CDSYS3U,
PCE_POPULOUS,
PCE_SF2,
- PCE_TENNOKOE
+ PCE_TENNOKOE,
+ PCE_ACARD_DUO,
+ PCE_ACARD_PRO
};
@@ -33,9 +35,7 @@ public:
// construction/destruction
virtual ~device_pce_cart_interface();
- // reading and writing
- virtual uint8_t read_cart(offs_t offset) { return 0xff; }
- virtual void write_cart(offs_t offset, uint8_t data) {}
+ virtual void install_memory_handlers(address_space &space) { }
void rom_alloc(uint32_t size);
void ram_alloc(uint32_t size);
@@ -80,6 +80,9 @@ public:
pce_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~pce_cart_slot_device();
+ // configuration
+ template void set_address_space(T &&tag, int no) { m_address_space.set_tag(std::forward(tag), no); }
+
// device_image_interface implementation
virtual std::pair call_load() override;
virtual void call_unload() override;
@@ -96,10 +99,6 @@ public:
void set_intf(const char * interface) { m_interface = interface; }
- // reading and writing
- uint8_t read_cart(offs_t offset);
- void write_cart(offs_t offset, uint8_t data);
-
protected:
// device_t implementation
virtual void device_start() override;
@@ -107,6 +106,7 @@ protected:
const char *m_interface;
int m_type;
device_pce_cart_interface *m_cart;
+ required_address_space m_address_space;
};
diff --git a/src/mame/nec/pce.cpp b/src/mame/nec/pce.cpp
index d7c61b664b0..37d12aefaa4 100644
--- a/src/mame/nec/pce.cpp
+++ b/src/mame/nec/pce.cpp
@@ -55,7 +55,9 @@ Super System Card:
#include "emu.h"
#include "pce.h"
+#include "bus/pce/pce_acard.h"
#include "bus/pce/pce_rom.h"
+#include "bus/pce/pce_scdsys.h"
#include "cpu/h6280/h6280.h"
#include "sound/cdda.h"
#include "sound/msm5205.h"
@@ -74,18 +76,12 @@ static INPUT_PORTS_START( pce )
//PORT_START("JOY_P.1")
// pachinko controller paddle maps here (!?) with this arrangement
//PORT_BIT( 0xff, 0x00, IPT_PADDLE ) PORT_MINMAX(0,0x5f) PORT_SENSITIVITY(15) PORT_KEYDELTA(15) PORT_CENTERDELTA(0) PORT_CODE_DEC(KEYCODE_N) PORT_CODE_INC(KEYCODE_M)
-
- PORT_START("A_CARD")
- PORT_CONFNAME( 0x01, 0x01, "Arcade Card" )
- PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
- PORT_CONFSETTING( 0x01, DEF_STR( On ) )
INPUT_PORTS_END
void pce_state::pce_mem(address_map &map)
{
- map(0x000000, 0x0FFFFF).rw(m_cartslot, FUNC(pce_cart_slot_device::read_cart), FUNC(pce_cart_slot_device::write_cart));
map(0x100000, 0x10FFFF).ram().share("cd_ram");
map(0x110000, 0x1EDFFF).noprw();
map(0x1EE000, 0x1EE7FF).rw(m_cd, FUNC(pce_cd_device::bram_r), FUNC(pce_cd_device::bram_w));
@@ -104,7 +100,6 @@ void pce_state::pce_io(address_map &map)
void pce_state::sgx_mem(address_map &map)
{
- map(0x000000, 0x0FFFFF).rw(m_cartslot, FUNC(pce_cart_slot_device::read_cart), FUNC(pce_cart_slot_device::write_cart));
map(0x100000, 0x10FFFF).ram().share("cd_ram");
map(0x110000, 0x1EDFFF).noprw();
map(0x1EE000, 0x1EE7FF).rw(m_cd, FUNC(pce_cd_device::bram_r), FUNC(pce_cd_device::bram_w));
@@ -134,11 +129,13 @@ uint32_t pce_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, c
static void pce_cart(device_slot_interface &device)
{
device.option_add_internal("rom", PCE_ROM_STD);
- device.option_add_internal("cdsys3u", PCE_ROM_CDSYS3);
- device.option_add_internal("cdsys3j", PCE_ROM_CDSYS3);
+ device.option_add_internal("cdsys3u", PCE_ROM_CDSYS3U);
+ device.option_add_internal("cdsys3j", PCE_ROM_CDSYS3J);
device.option_add_internal("populous", PCE_ROM_POPULOUS);
device.option_add_internal("sf2", PCE_ROM_SF2);
device.option_add_internal("tennokoe", PCE_ROM_TENNOKOE);
+ device.option_add_internal("acard_duo", PCE_ROM_ACARD_DUO);
+ device.option_add_internal("acard_pro", PCE_ROM_ACARD_PRO);
}
void pce_state::pce_common(machine_config &config)
@@ -177,6 +174,8 @@ void pce_state::pce_common(machine_config &config)
// TODO: expansion port not emulated
PCE_CD(config, m_cd, 0);
+ m_cd->irq().set_inputline(m_maincpu, 1);
+ m_cd->set_maincpu(m_maincpu);
SOFTWARE_LIST(config, "cd_list").set_original("pcecd");
}
@@ -186,6 +185,7 @@ void pce_state::pce(machine_config &config)
{
pce_common(config);
PCE_CART_SLOT(config, m_cartslot, pce_cart, nullptr, "pce_cart").set_must_be_loaded(true);
+ m_cartslot->set_address_space(m_maincpu, AS_PROGRAM);
SOFTWARE_LIST(config, "cart_list").set_original("pce");
// bundled pad (in white PC engine) has not support autofire
@@ -196,6 +196,7 @@ void pce_state::tg16(machine_config &config)
{
pce_common(config);
PCE_CART_SLOT(config, m_cartslot, pce_cart, nullptr, "tg16_cart").set_must_be_loaded(true);
+ m_cartslot->set_address_space(m_maincpu, AS_PROGRAM);
SOFTWARE_LIST(config, "cart_list").set_original("tg16");
// turbo pad bundled
@@ -257,11 +258,14 @@ void pce_state::sgx(machine_config &config)
PCE_CONTROL_PORT(config, m_port_ctrl, pce_control_port_devices, "joypad2_turbo");
PCE_CART_SLOT(config, m_cartslot, pce_cart, nullptr, "pce_cart").set_must_be_loaded(true);
+ m_cartslot->set_address_space(m_maincpu, AS_PROGRAM);
SOFTWARE_LIST(config, "cart_list").set_original("sgx");
SOFTWARE_LIST(config, "pce_list").set_compatible("pce");
// TODO: expansion port not emulated
PCE_CD(config, m_cd, 0);
+ m_cd->irq().set_inputline(m_maincpu, 1);
+ m_cd->set_maincpu(m_maincpu);
SOFTWARE_LIST(config, "cd_list").set_original("pcecd");
}
diff --git a/src/mame/nec/pce.h b/src/mame/nec/pce.h
index a4d5374b0de..87d4d24cf62 100644
--- a/src/mame/nec/pce.h
+++ b/src/mame/nec/pce.h
@@ -44,8 +44,7 @@ public:
m_huc6260(*this, "huc6260"),
m_cartslot(*this, "cartslot"),
m_cd(*this, "pce_cd"),
- m_port_ctrl(*this, "ctrl"),
- m_a_card(*this, "A_CARD")
+ m_port_ctrl(*this, "ctrl")
{ }
void init_tg16();
@@ -67,17 +66,12 @@ private:
required_device m_cartslot;
optional_device m_cd;
required_device m_port_ctrl;
- required_ioport m_a_card;
u8 m_io_port_options = 0;
- u8 m_sys3_card = 0;
- u8 m_acard = 0;
void controller_w(u8 data);
u8 controller_r();
void cd_intf_w(offs_t offset, u8 data);
u8 cd_intf_r(offs_t offset);
- u8 acard_wram_r(offs_t offset);
- void acard_wram_w(offs_t offset, u8 data);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void pce_io(address_map &map);
void pce_mem(address_map &map);
diff --git a/src/mame/nec/pce_cd.cpp b/src/mame/nec/pce_cd.cpp
index 58493c1a9c5..9ee6127ce63 100644
--- a/src/mame/nec/pce_cd.cpp
+++ b/src/mame/nec/pce_cd.cpp
@@ -83,7 +83,8 @@ pce_cd_device::pce_cd_device(const machine_config &mconfig, const char *tag, dev
: device_t(mconfig, PCE_CD, tag, owner, clock)
, device_memory_interface(mconfig, *this)
, m_space_config("io", ENDIANNESS_LITTLE, 8, 4, 0, address_map_constructor(FUNC(pce_cd_device::regs_map), this))
- , m_maincpu(*this, ":maincpu")
+ , m_maincpu(*this, finder_base::DUMMY_TAG)
+ , m_irq_cb(*this)
, m_msm(*this, "msm5205")
, m_cdda(*this, "cdda")
, m_nvram(*this, "bram")
@@ -116,9 +117,6 @@ void pce_cd_device::device_start()
m_command_buffer = make_unique_clear(PCE_CD_COMMAND_BUFFER_SIZE);
m_command_buffer_index = 0;
- /* Set up Arcade Card RAM buffer */
- m_acard_ram = make_unique_clear(PCE_ACARD_RAM_SIZE);
-
m_data_buffer = make_unique_clear(8192);
m_data_buffer_size = 0;
m_data_buffer_index = 0;
@@ -180,14 +178,6 @@ void pce_cd_device::device_start()
save_item(NAME(m_data_buffer_size));
save_item(NAME(m_data_buffer_index));
save_item(NAME(m_data_transferred));
- save_pointer(NAME(m_acard_ram), PCE_ACARD_RAM_SIZE);
- save_item(NAME(m_acard_latch));
- save_item(NAME(m_acard_ctrl));
- save_item(NAME(m_acard_base_addr));
- save_item(NAME(m_acard_addr_offset));
- save_item(NAME(m_acard_addr_inc));
- save_item(NAME(m_acard_shift));
- save_item(NAME(m_acard_shift_reg));
save_item(NAME(m_current_frame));
save_item(NAME(m_end_frame));
save_item(NAME(m_last_frame));
@@ -1085,11 +1075,11 @@ void pce_cd_device::set_irq_line(int num, int state)
, m_irq_mask & 0x7c
, m_irq_status & 0x7c
);
- m_maincpu->set_input_line(1, ASSERT_LINE);
+ m_irq_cb(ASSERT_LINE);
}
else
{
- m_maincpu->set_input_line(1, CLEAR_LINE);
+ m_irq_cb(CLEAR_LINE);
}
}
@@ -1317,10 +1307,12 @@ uint8_t pce_cd_device::irq_status_r()
{
uint8_t res = m_irq_status & 0x6e;
// a read here locks the BRAM
- m_bram_locked = 1;
+ if (!machine().side_effects_disabled())
+ m_bram_locked = 1;
res |= (m_cd_motor_on ? 0x10 : 0);
// TODO: gross hack, needs actual behaviour of CDDA data select
- m_irq_status ^= 0x02;
+ if (!machine().side_effects_disabled())
+ m_irq_status ^= 0x02;
return res;
}
@@ -1664,7 +1656,8 @@ uint8_t pce_cd_device::get_adpcm_ram_byte()
{
if (m_adpcm_read_buf > 0)
{
- m_adpcm_read_buf--;
+ if (!machine().side_effects_disabled())
+ m_adpcm_read_buf--;
return 0;
}
else
@@ -1672,7 +1665,8 @@ uint8_t pce_cd_device::get_adpcm_ram_byte()
uint8_t res;
res = m_adpcm_ram[m_adpcm_read_ptr];
- m_adpcm_read_ptr = ((m_adpcm_read_ptr + 1) & 0xffff);
+ if (!machine().side_effects_disabled())
+ m_adpcm_read_ptr = ((m_adpcm_read_ptr + 1) & 0xffff);
return res;
}
@@ -1700,154 +1694,3 @@ void pce_cd_device::intf_w(offs_t offset, uint8_t data)
address_space &io_space = this->space(AS_IO);
io_space.write_byte(offset & 0xf, data);
}
-
-/*
- *
- * PC Engine Arcade Card emulation
- *
- */
-
-
-
-uint8_t pce_cd_device::acard_r(offs_t offset)
-{
- uint8_t r_num;
-
- if ((offset & 0x2e0) == 0x2e0)
- {
- switch (offset & 0x2ef)
- {
- case 0x2e0: return (m_acard_shift >> 0) & 0xff;
- case 0x2e1: return (m_acard_shift >> 8) & 0xff;
- case 0x2e2: return (m_acard_shift >> 16) & 0xff;
- case 0x2e3: return (m_acard_shift >> 24) & 0xff;
- case 0x2e4: return (m_acard_shift_reg);
- case 0x2e5: return m_acard_latch;
- case 0x2ee: return 0x10;
- case 0x2ef: return 0x51;
- }
-
- return 0;
- }
-
- r_num = (offset & 0x30) >> 4;
-
- switch (offset & 0x0f)
- {
- case 0x00:
- case 0x01:
- {
- uint8_t res;
- if (m_acard_ctrl[r_num] & 2)
- res = m_acard_ram[(m_acard_base_addr[r_num] + m_acard_addr_offset[r_num]) & 0x1fffff];
- else
- res = m_acard_ram[m_acard_base_addr[r_num] & 0x1fffff];
-
- if (m_acard_ctrl[r_num] & 0x1)
- {
- if (m_acard_ctrl[r_num] & 0x10)
- {
- m_acard_base_addr[r_num] += m_acard_addr_inc[r_num];
- m_acard_base_addr[r_num] &= 0xffffff;
- }
- else
- {
- m_acard_addr_offset[r_num] += m_acard_addr_inc[r_num];
- }
- }
-
- return res;
- }
- case 0x02: return (m_acard_base_addr[r_num] >> 0) & 0xff;
- case 0x03: return (m_acard_base_addr[r_num] >> 8) & 0xff;
- case 0x04: return (m_acard_base_addr[r_num] >> 16) & 0xff;
- case 0x05: return (m_acard_addr_offset[r_num] >> 0) & 0xff;
- case 0x06: return (m_acard_addr_offset[r_num] >> 8) & 0xff;
- case 0x07: return (m_acard_addr_inc[r_num] >> 0) & 0xff;
- case 0x08: return (m_acard_addr_inc[r_num] >> 8) & 0xff;
- case 0x09: return m_acard_ctrl[r_num];
- default: return 0;
- }
-}
-
-void pce_cd_device::acard_w(offs_t offset, uint8_t data)
-{
- uint8_t w_num;
-
- if ((offset & 0x2e0) == 0x2e0)
- {
- switch (offset & 0x0f)
- {
- case 0: m_acard_shift = (data & 0xff) | (m_acard_shift & 0xffffff00); break;
- case 1: m_acard_shift = (data << 8) | (m_acard_shift & 0xffff00ff); break;
- case 2: m_acard_shift = (data << 16) | (m_acard_shift & 0xff00ffff); break;
- case 3: m_acard_shift = (data << 24) | (m_acard_shift & 0x00ffffff); break;
- case 4:
- {
- m_acard_shift_reg = data & 0x0f;
-
- if (m_acard_shift_reg != 0)
- {
- m_acard_shift = (m_acard_shift_reg < 8) ?
- (m_acard_shift << m_acard_shift_reg)
- : (m_acard_shift >> (16 - m_acard_shift_reg));
- }
- }
- break;
- case 5: m_acard_latch = data; break;
- }
- }
- else
- {
- w_num = (offset & 0x30) >> 4;
-
- switch (offset & 0x0f)
- {
- case 0x00:
- case 0x01:
- if (m_acard_ctrl[w_num] & 2)
- m_acard_ram[(m_acard_base_addr[w_num] + m_acard_addr_offset[w_num]) & 0x1fffff] = data;
- else
- m_acard_ram[m_acard_base_addr[w_num] & 0x1FFFFF] = data;
-
- if (m_acard_ctrl[w_num] & 0x1)
- {
- if (m_acard_ctrl[w_num] & 0x10)
- {
- m_acard_base_addr[w_num] += m_acard_addr_inc[w_num];
- m_acard_base_addr[w_num] &= 0xffffff;
- }
- else
- {
- m_acard_addr_offset[w_num] += m_acard_addr_inc[w_num];
- }
- }
-
- break;
-
- case 0x02: m_acard_base_addr[w_num] = (data & 0xff) | (m_acard_base_addr[w_num] & 0xffff00); break;
- case 0x03: m_acard_base_addr[w_num] = (data << 8) | (m_acard_base_addr[w_num] & 0xff00ff); break;
- case 0x04: m_acard_base_addr[w_num] = (data << 16) | (m_acard_base_addr[w_num] & 0x00ffff); break;
- case 0x05: m_acard_addr_offset[w_num] = (data & 0xff) | (m_acard_addr_offset[w_num] & 0xff00); break;
- case 0x06:
- m_acard_addr_offset[w_num] = (data << 8) | (m_acard_addr_offset[w_num] & 0x00ff);
-
- if ((m_acard_ctrl[w_num] & 0x60) == 0x40)
- {
- m_acard_base_addr[w_num] += m_acard_addr_offset[w_num] + ((m_acard_ctrl[w_num] & 0x08) ? 0xff0000 : 0);
- m_acard_base_addr[w_num] &= 0xffffff;
- }
- break;
- case 0x07: m_acard_addr_inc[w_num] = (data & 0xff) | (m_acard_addr_inc[w_num] & 0xff00); break;
- case 0x08: m_acard_addr_inc[w_num] = (data << 8) | (m_acard_addr_inc[w_num] & 0x00ff); break;
- case 0x09: m_acard_ctrl[w_num] = data & 0x7f; break;
- case 0x0a:
- if ((m_acard_ctrl[w_num] & 0x60) == 0x60)
- {
- m_acard_base_addr[w_num] += m_acard_addr_offset[w_num];
- m_acard_base_addr[w_num] &= 0xffffff;
- }
- break;
- }
- }
-}
diff --git a/src/mame/nec/pce_cd.h b/src/mame/nec/pce_cd.h
index f7da64b9a16..4fdd6e0ddfd 100644
--- a/src/mame/nec/pce_cd.h
+++ b/src/mame/nec/pce_cd.h
@@ -47,16 +47,18 @@ public:
// construction/destruction
pce_cd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ // configuration
+ template void set_maincpu(T &&tag) { m_maincpu.set_tag(std::forward(tag)); }
+ auto irq() { return m_irq_cb.bind(); }
+
void update();
void late_setup();
void bram_w(offs_t offset, uint8_t data);
void intf_w(offs_t offset, uint8_t data);
- void acard_w(offs_t offset, uint8_t data);
uint8_t bram_r(offs_t offset);
uint8_t intf_r(offs_t offset);
- uint8_t acard_r(offs_t offset);
protected:
// device-level overrides
@@ -135,6 +137,7 @@ private:
TIMER_CALLBACK_MEMBER(adpcm_dma_timer_callback);
required_device m_maincpu;
+ devcb_write_line m_irq_cb;
std::unique_ptr m_bram;
std::unique_ptr m_adpcm_ram;
@@ -175,16 +178,6 @@ private:
int m_data_buffer_index = 0;
int m_data_transferred = 0;
- /* Arcade Card specific */
- std::unique_ptr m_acard_ram;
- uint8_t m_acard_latch = 0;
- uint8_t m_acard_ctrl[4];
- uint32_t m_acard_base_addr[4];
- uint16_t m_acard_addr_offset[4];
- uint16_t m_acard_addr_inc[4];
- uint32_t m_acard_shift = 0;
- uint8_t m_acard_shift_reg = 0;
-
uint32_t m_current_frame = 0;
uint32_t m_end_frame = 0;
uint32_t m_last_frame = 0;
diff --git a/src/mame/nec/pce_m.cpp b/src/mame/nec/pce_m.cpp
index 25bf3ea3952..deef178979d 100644
--- a/src/mame/nec/pce_m.cpp
+++ b/src/mame/nec/pce_m.cpp
@@ -29,26 +29,10 @@ void pce_state::machine_start()
// saving is only partially supported: it should be fine with cart games
// OTOH CD states are saved but not correctly restored!
save_item(NAME(m_io_port_options));
- save_item(NAME(m_acard));
}
void pce_state::machine_reset()
{
- /* Note: Arcade Card BIOS contents are the same as System 3, only internal HW differs.
- We use a category to select between modes (some games can be run in either S-CD or A-CD modes) */
- m_acard = m_a_card->read() & 1;
-
- if (m_cartslot->get_type() == PCE_CDSYS3J)
- {
- m_sys3_card = 1;
- m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x080000, 0x087fff, read8sm_delegate(*this, FUNC(pce_state::acard_wram_r)), write8sm_delegate(*this, FUNC(pce_state::acard_wram_w)));
- }
-
- if (m_cartslot->get_type() == PCE_CDSYS3U)
- {
- m_sys3_card = 3;
- m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x080000, 0x087fff, read8sm_delegate(*this, FUNC(pce_state::acard_wram_r)), write8sm_delegate(*this, FUNC(pce_state::acard_wram_w)));
- }
}
void pce_state::controller_w(u8 data)
@@ -72,9 +56,6 @@ void pce_state::cd_intf_w(offs_t offset, u8 data)
{
m_cd->update();
- if (offset & 0x200 && m_sys3_card && m_acard) // route Arcade Card handling ports
- return m_cd->acard_w(offset, data);
-
m_cd->intf_w(offset, data);
m_cd->update();
@@ -84,32 +65,5 @@ u8 pce_state::cd_intf_r(offs_t offset)
{
m_cd->update();
- if (offset & 0x200 && m_sys3_card && m_acard) // route Arcade Card handling ports
- return m_cd->acard_r(offset);
-
- if ((offset & 0xc0) == 0xc0 && m_sys3_card) //System 3 Card header handling
- {
- switch (offset & 0xcf)
- {
- case 0xc1: return 0xaa;
- case 0xc2: return 0x55;
- case 0xc3: return 0x00;
- case 0xc5: return (m_sys3_card & 2) ? 0x55 : 0xaa;
- case 0xc6: return (m_sys3_card & 2) ? 0xaa : 0x55;
- case 0xc7: return 0x03;
- }
- }
-
return m_cd->intf_r(offset);
}
-
-
-u8 pce_state::acard_wram_r(offs_t offset)
-{
- return cd_intf_r(0x200 | (offset & 0x6000) >> 9);
-}
-
-void pce_state::acard_wram_w(offs_t offset, u8 data)
-{
- cd_intf_w(0x200 | (offset & 0x6000) >> 9, data);
-}