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); -}