spectrum: Improved expansion interface to allow devices to act on opcode fetches.

- Added Multiface One/128/3, and MultiPrint devices.
This commit is contained in:
Nigel Barnes 2019-03-10 13:23:23 +00:00
parent d62970843f
commit 09f698ddc8
29 changed files with 744 additions and 225 deletions

View File

@ -3268,6 +3268,8 @@ if (BUSES["SPECTRUM"]~=null) then
MAME_DIR .. "src/devices/bus/spectrum/kempjoy.h",
MAME_DIR .. "src/devices/bus/spectrum/melodik.cpp",
MAME_DIR .. "src/devices/bus/spectrum/melodik.h",
MAME_DIR .. "src/devices/bus/spectrum/mface.cpp",
MAME_DIR .. "src/devices/bus/spectrum/mface.h",
MAME_DIR .. "src/devices/bus/spectrum/mikroplus.cpp",
MAME_DIR .. "src/devices/bus/spectrum/mikroplus.h",
MAME_DIR .. "src/devices/bus/spectrum/plus2test.cpp",

View File

@ -43,7 +43,6 @@ device_spectrum_expansion_interface::device_spectrum_expansion_interface(const m
spectrum_expansion_slot_device::spectrum_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SPECTRUM_EXPANSION_SLOT, tag, owner, clock),
device_slot_interface(mconfig, *this),
m_io(*this, finder_base::DUMMY_TAG, -1),
m_card(nullptr),
m_irq_handler(*this),
m_nmi_handler(*this)
@ -51,23 +50,6 @@ spectrum_expansion_slot_device::spectrum_expansion_slot_device(const machine_con
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void spectrum_expansion_slot_device::device_config_complete()
{
// for passthrough connectors, use the parent slot's I/O space
if (m_io.finder_tag() == finder_base::DUMMY_TAG && dynamic_cast<device_spectrum_expansion_interface *>(owner()) != nullptr)
{
auto parent = dynamic_cast<spectrum_expansion_slot_device *>(owner()->owner());
if (parent != nullptr)
m_io.set_tag(parent->m_io, parent->m_io.spacenum());
}
}
//-------------------------------------------------
// device_validity_check - device-specific checks
//-------------------------------------------------
@ -103,18 +85,6 @@ void spectrum_expansion_slot_device::device_reset()
{
}
//-------------------------------------------------
// port_fe_r
//-------------------------------------------------
uint8_t spectrum_expansion_slot_device::port_fe_r(offs_t offset)
{
if (m_card)
return m_card->port_fe_r(offset);
else
return 0xff;
}
//-------------------------------------------------
// romcs
//-------------------------------------------------
@ -127,6 +97,38 @@ READ_LINE_MEMBER(spectrum_expansion_slot_device::romcs)
return 0;
}
//-------------------------------------------------
// fetch_r
//-------------------------------------------------
void spectrum_expansion_slot_device::opcode_fetch(offs_t offset)
{
if (m_card)
m_card->opcode_fetch(offset);
}
//-------------------------------------------------
// iorq_r
//-------------------------------------------------
uint8_t spectrum_expansion_slot_device::iorq_r(offs_t offset)
{
if (m_card)
return m_card->iorq_r(offset);
else
return 0xff;
}
//-------------------------------------------------
// iorq_w
//-------------------------------------------------
void spectrum_expansion_slot_device::iorq_w(offs_t offset, uint8_t data)
{
if (m_card)
m_card->iorq_w(offset, data);
}
//-------------------------------------------------
// mreq_r
//-------------------------------------------------
@ -156,13 +158,18 @@ void spectrum_expansion_slot_device::mreq_w(offs_t offset, uint8_t data)
// slot devices
//#include "beta.h"
//#include "disciple.h"
#include "intf1.h"
#include "intf2.h"
#include "fuller.h"
#include "kempjoy.h"
#include "melodik.h"
#include "mface.h"
#include "mikroplus.h"
//#include "opus.h"
#include "plus2test.h"
//#include "plusd.h"
#include "protek.h"
#include "uslot.h"
#include "usource.h"
@ -171,12 +178,20 @@ void spectrum_expansion_slot_device::mreq_w(offs_t offset, uint8_t data)
void spectrum_expansion_devices(device_slot_interface &device)
{
//device.option_add("beta", SPECTRUM_BETA);
//device.option_add("betaplus", SPECTRUM_BETAPLUS);
//device.option_add("disciple", SPECTRUM_DISCIPLE);
device.option_add("intf1", SPECTRUM_INTF1);
device.option_add("intf2", SPECTRUM_INTF2);
device.option_add("fuller", SPECTRUM_FULLER);
device.option_add("kempjoy", SPECTRUM_KEMPJOY);
device.option_add("melodik", SPECTRUM_MELODIK);
device.option_add("mface1", SPECTRUM_MFACE1);
device.option_add("mface128", SPECTRUM_MFACE128);
device.option_add("mikroplus", SPECTRUM_MIKROPLUS);
device.option_add("mprint", SPECTRUM_MPRINT);
//device.option_add("opus", SPECTRUM_OPUS);
//device.option_add("plusd", SPECTRUM_PLUSD);
device.option_add("protek", SPECTRUM_PROTEK);
device.option_add("uslot", SPECTRUM_USLOT);
device.option_add("usource", SPECTRUM_USOURCE);
@ -185,15 +200,20 @@ void spectrum_expansion_devices(device_slot_interface &device)
void spec128_expansion_devices(device_slot_interface &device)
{
//device.option_add("beta128", SPECTRUM_BETA128);
//device.option_add("disciple", SPECTRUM_DISCIPLE);
device.option_add("intf1", SPECTRUM_INTF1);
device.option_add("intf2", SPECTRUM_INTF2);
device.option_add("kempjoy", SPECTRUM_KEMPJOY);
device.option_add("mface128", SPECTRUM_MFACE128);
device.option_add("mikroplus", SPECTRUM_MIKROPLUS);
device.option_add("mprint", SPECTRUM_MPRINT);
device.option_add("plus2test", SPECTRUM_PLUS2TEST);
device.option_add("protek", SPECTRUM_PROTEK);
}
void specpls3_expansion_devices(device_slot_interface &device)
{
device.option_add("mface3", SPECTRUM_MFACE3);
}

View File

@ -69,25 +69,22 @@ public:
spectrum_expansion_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock = 0);
template <typename T> void set_io_space(T &&tag, int spacenum) { m_io.set_tag(std::forward<T>(tag), spacenum); }
// callbacks
auto irq_handler() { return m_irq_handler.bind(); }
auto nmi_handler() { return m_nmi_handler.bind(); }
void opcode_fetch(offs_t offset);
uint8_t mreq_r(offs_t offset);
void mreq_w(offs_t offset, uint8_t data);
uint8_t port_fe_r(offs_t offset);
uint8_t iorq_r(offs_t offset);
void iorq_w(offs_t offset, uint8_t data);
DECLARE_READ_LINE_MEMBER( romcs );
DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_irq_handler(state); }
DECLARE_WRITE_LINE_MEMBER( nmi_w ) { m_nmi_handler(state); }
required_address_space m_io;
protected:
// device-level overrides
virtual void device_config_complete() override;
virtual void device_validity_check(validity_checker &valid) const override;
virtual void device_start() override;
virtual void device_reset() override;
@ -109,14 +106,14 @@ public:
device_spectrum_expansion_interface(const machine_config &mconfig, device_t &device);
// reading and writing
virtual void opcode_fetch(offs_t offset) { };
virtual uint8_t mreq_r(offs_t offset) { return 0xff; }
virtual void mreq_w(offs_t offset, uint8_t data) { }
virtual uint8_t port_fe_r(offs_t offset) { return 0xff; }
virtual uint8_t iorq_r(offs_t offset) { return 0xff; }
virtual void iorq_w(offs_t offset, uint8_t data) { }
virtual DECLARE_READ_LINE_MEMBER(romcs) { return 0; }
protected:
address_space &io_space() { return *m_slot->m_io; }
spectrum_expansion_slot_device *m_slot;
};

View File

@ -84,35 +84,28 @@ void spectrum_fuller_device::device_start()
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void spectrum_fuller_device::device_reset()
{
io_space().install_write_handler(0x3f, 0x3f, 0, 0xff00, 0, write8smo_delegate(FUNC(ay8910_device::address_w), m_psg.target()));
io_space().install_readwrite_handler(0x5f, 0x5f, 0, 0xff00, 0, read8smo_delegate(FUNC(ay8910_device::data_r), m_psg.target()), write8smo_delegate(FUNC(ay8910_device::data_w), m_psg.target()));
io_space().install_read_handler(0x7f, 0x7f, 0, 0xff00, 0, read8smo_delegate(FUNC(spectrum_fuller_device::joystick_r), this));
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
uint8_t spectrum_fuller_device::joystick_r()
{
return m_joy->read() | (0xff ^ 0x8f);
}
READ_LINE_MEMBER(spectrum_fuller_device::romcs)
{
return m_exp->romcs();
}
void spectrum_fuller_device::opcode_fetch(offs_t offset)
{
m_exp->opcode_fetch(offset);
}
uint8_t spectrum_fuller_device::mreq_r(offs_t offset)
{
return m_exp->mreq_r(offset);
uint8_t data = 0xff;
if (m_exp->romcs())
data &= m_exp->mreq_r(offset);
return data;
}
void spectrum_fuller_device::mreq_w(offs_t offset, uint8_t data)
@ -121,12 +114,32 @@ void spectrum_fuller_device::mreq_w(offs_t offset, uint8_t data)
m_exp->mreq_w(offset, data);
}
uint8_t spectrum_fuller_device::port_fe_r(offs_t offset)
uint8_t spectrum_fuller_device::iorq_r(offs_t offset)
{
uint8_t data = 0xff;
if (m_exp->romcs())
data &= m_exp->port_fe_r(offset);
uint8_t data = m_exp->iorq_r(offset);
switch (offset & 0xff)
{
case 0x5f:
data &= m_psg->data_r();
break;
case 0x7f:
data &= m_joy->read() | (0xff ^ 0x8f);
break;
}
return data;
}
void spectrum_fuller_device::iorq_w(offs_t offset, uint8_t data)
{
switch (offset & 0xff)
{
case 0x3f:
m_psg->address_w(data);
break;
case 0x5f:
m_psg->data_w(data);
break;
}
m_exp->iorq_w(offset, data);
}

View File

@ -32,20 +32,19 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// optional information overrides
virtual void device_add_mconfig(machine_config &config) override;
virtual ioport_constructor device_input_ports() const override;
virtual void opcode_fetch(offs_t offset) override;
virtual uint8_t mreq_r(offs_t offset) override;
virtual void mreq_w(offs_t offset, uint8_t data) override;
virtual uint8_t port_fe_r(offs_t offset) override;
virtual uint8_t iorq_r(offs_t offset) override;
virtual void iorq_w(offs_t offset, uint8_t data) override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
private:
uint8_t joystick_r();
required_device<spectrum_expansion_slot_device> m_exp;
required_device<ay8910_device> m_psg;
required_ioport m_joy;

View File

@ -85,6 +85,7 @@ spectrum_intf1_device::spectrum_intf1_device(const machine_config &mconfig, cons
void spectrum_intf1_device::device_start()
{
save_item(NAME(m_romcs));
}
//-------------------------------------------------
@ -105,29 +106,33 @@ READ_LINE_MEMBER(spectrum_intf1_device::romcs)
return m_romcs | m_exp->romcs();
}
uint8_t spectrum_intf1_device::mreq_r(offs_t offset)
void spectrum_intf1_device::opcode_fetch(offs_t offset)
{
uint8_t temp;
uint8_t data = 0xff;
m_exp->opcode_fetch(offset);
if (!machine().side_effects_disabled())
{
if (offset == 0x0008 || offset == 0x1708)
switch (offset)
{
case 0x0008: case 0x1708:
m_romcs = 1;
break;
case 0x0700:
m_romcs = 0;
break;
}
}
}
temp = m_exp->mreq_r(offset);
if (m_exp->romcs())
data &= temp;
uint8_t spectrum_intf1_device::mreq_r(offs_t offset)
{
uint8_t data = 0xff;
if (m_romcs)
data &= m_rom->base()[offset & 0x1fff];
if (!machine().side_effects_disabled())
{
if (offset == 0x0700)
m_romcs = 0;
}
if (m_exp->romcs())
data &= m_exp->mreq_r(offset);
return data;
}
@ -138,12 +143,12 @@ void spectrum_intf1_device::mreq_w(offs_t offset, uint8_t data)
m_exp->mreq_w(offset, data);
}
uint8_t spectrum_intf1_device::port_fe_r(offs_t offset)
uint8_t spectrum_intf1_device::iorq_r(offs_t offset)
{
uint8_t data = 0xff;
if (m_exp->romcs())
data &= m_exp->port_fe_r(offset);
return data;
return m_exp->iorq_r(offset);
}
void spectrum_intf1_device::iorq_w(offs_t offset, uint8_t data)
{
m_exp->iorq_w(offset, data);
}

View File

@ -36,9 +36,11 @@ protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void opcode_fetch(offs_t offset) override;
virtual uint8_t mreq_r(offs_t offset) override;
virtual void mreq_w(offs_t offset, uint8_t data) override;
virtual uint8_t port_fe_r(offs_t offset) override;
virtual uint8_t iorq_r(offs_t offset) override;
virtual void iorq_w(offs_t offset, uint8_t data) override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
private:

View File

@ -125,17 +125,20 @@ uint8_t spectrum_intf2_device::mreq_r(offs_t offset)
return 0xff;
}
uint8_t spectrum_intf2_device::port_fe_r(offs_t offset)
uint8_t spectrum_intf2_device::iorq_r(offs_t offset)
{
uint8_t data = 0xff;
uint8_t lines = offset >> 8;
switch (offset & 0xff)
{
case 0xfe:
if (((offset >> 8) & 8) == 0)
data = m_exp_line3->read() | (0xff ^ 0x1f);
if ((lines & 8) == 0)
data = m_exp_line3->read() | (0xff ^ 0x1f);
if ((lines & 16) == 0)
data = m_exp_line4->read() | (0xff ^ 0x1f);
if (((offset >> 8) & 16) == 0)
data = m_exp_line4->read() | (0xff ^ 0x1f);
break;
}
return data;
}

View File

@ -36,7 +36,7 @@ protected:
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
virtual uint8_t mreq_r(offs_t offset) override;
virtual uint8_t port_fe_r(offs_t offset) override;
virtual uint8_t iorq_r(offs_t offset) override;
private:
image_init_result load_cart(device_image_interface &image, generic_slot_device *slot);

View File

@ -65,21 +65,17 @@ void spectrum_kempjoy_device::device_start()
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void spectrum_kempjoy_device::device_reset()
{
io_space().install_read_handler(0x1f, 0x1f, 0, 0xff00, 0, read8smo_delegate(FUNC(spectrum_kempjoy_device::joystick_r), this));
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
uint8_t spectrum_kempjoy_device::joystick_r()
uint8_t spectrum_kempjoy_device::iorq_r(offs_t offset)
{
return m_joy->read() & 0x1f;
uint8_t data = 0xff;
if (offset == 0x1f)
{
data = m_joy->read() & 0x1f;
}
return data;
}

View File

@ -31,14 +31,13 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// optional information overrides
virtual ioport_constructor device_input_ports() const override;
private:
uint8_t joystick_r();
virtual uint8_t iorq_r(offs_t offset) override;
private:
required_ioport m_joy;
};

View File

@ -60,16 +60,6 @@ void spectrum_melodik_device::device_start()
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void spectrum_melodik_device::device_reset()
{
io_space().install_write_handler(0x8000, 0x8000, 0, 0x3ffd, 0, write8smo_delegate(FUNC(ay8910_device::address_w), m_psg.target()));
io_space().install_readwrite_handler(0xc000, 0xc000, 0, 0x3ffd, 0, read8smo_delegate(FUNC(ay8910_device::data_r), m_psg.target()), write8smo_delegate(FUNC(ay8910_device::data_w), m_psg.target()));
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
@ -79,9 +69,19 @@ READ_LINE_MEMBER(spectrum_melodik_device::romcs)
return m_exp->romcs();
}
void spectrum_melodik_device::opcode_fetch(offs_t offset)
{
m_exp->opcode_fetch(offset);
}
uint8_t spectrum_melodik_device::mreq_r(offs_t offset)
{
return m_exp->mreq_r(offset);
uint8_t data = 0xff;
if (m_exp->romcs())
data &= m_exp->mreq_r(offset);
return data;
}
void spectrum_melodik_device::mreq_w(offs_t offset, uint8_t data)
@ -90,12 +90,29 @@ void spectrum_melodik_device::mreq_w(offs_t offset, uint8_t data)
m_exp->mreq_w(offset, data);
}
uint8_t spectrum_melodik_device::port_fe_r(offs_t offset)
uint8_t spectrum_melodik_device::iorq_r(offs_t offset)
{
uint8_t data = 0xff;
if (m_exp->romcs())
data &= m_exp->port_fe_r(offset);
uint8_t data = m_exp->iorq_r(offset);
switch (offset & 0xc002)
{
case 0xc000:
data &= m_psg->data_r();
break;
}
return data;
}
void spectrum_melodik_device::iorq_w(offs_t offset, uint8_t data)
{
switch (offset & 0xc002)
{
case 0x8000:
m_psg->address_w(data);
break;
case 0xc000:
m_psg->data_w(data);
break;
}
m_exp->iorq_w(offset, data);
}

View File

@ -32,14 +32,15 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// optional information overrides
virtual void device_add_mconfig(machine_config &config) override;
virtual void opcode_fetch(offs_t offset) override;
virtual uint8_t mreq_r(offs_t offset) override;
virtual void mreq_w(offs_t offset, uint8_t data) override;
virtual uint8_t port_fe_r(offs_t offset) override;
virtual uint8_t iorq_r(offs_t offset) override;
virtual void iorq_w(offs_t offset, uint8_t data) override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
private:

View File

@ -0,0 +1,321 @@
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/*********************************************************************
Romantic Robot Multiface One/128/3
*********************************************************************/
#include "emu.h"
#include "mface.h"
/***************************************************************************
DEVICE DEFINITIONS
***************************************************************************/
DEFINE_DEVICE_TYPE(SPECTRUM_MFACE1, spectrum_mface1_device, "spectrum_mface1", "Multiface One")
DEFINE_DEVICE_TYPE(SPECTRUM_MFACE128, spectrum_mface128_device, "spectrum_mface128", "Multiface 128")
DEFINE_DEVICE_TYPE(SPECTRUM_MFACE3, spectrum_mface3_device, "spectrum_mface3", "Multiface 3")
DEFINE_DEVICE_TYPE(SPECTRUM_MPRINT, spectrum_mprint_device, "spectrum_mprint", "MultiPrint")
//-------------------------------------------------
// INPUT_PORTS( mface )
//-------------------------------------------------
INPUT_PORTS_START(mface)
PORT_START("BUTTON")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Multiface") PORT_CODE(KEYCODE_F12) PORT_CHANGED_MEMBER(DEVICE_SELF, spectrum_mface1_device, magic_button, nullptr)
INPUT_PORTS_END
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
ioport_constructor spectrum_mface1_device::device_input_ports() const
{
return INPUT_PORTS_NAME(mface);
}
//-------------------------------------------------
// ROM( mface1 )
//-------------------------------------------------
ROM_START(mface1)
ROM_REGION(0x2000, "rom", 0)
ROM_DEFAULT_BIOS("mu21e7")
ROM_SYSTEM_BIOS(0, "mu20fe", "MU 2.0 FE")
ROMX_LOAD("mf1_20_fe.rom", 0x0000, 0x2000, CRC(fa1b8b0d) SHA1(20cd508b0143166558a7238c7a9ccfbe37b90b0d), ROM_BIOS(0))
ROM_SYSTEM_BIOS(1, "mu2167", "MU 2.1 67")
ROMX_LOAD("mf1_21_67.rom", 0x0000, 0x2000, CRC(d720ec1b) SHA1(91a40d8f503ef825df3e2ed712897dbf4ca3671d), ROM_BIOS(1))
ROM_SYSTEM_BIOS(2, "mu21e4", "MU 2.1 E4")
ROMX_LOAD("mf1_21_e4.rom", 0x0000, 0x2000, CRC(4b31a971) SHA1(ba28754a3cc31a4ca579829ed4310c313409cf5d), ROM_BIOS(2))
ROM_SYSTEM_BIOS(3, "mu21e7", "MU 2.1 E7")
ROMX_LOAD("mf1_21_e7.rom", 0x0000, 0x2000, CRC(670f0ec2) SHA1(50fba2d628f3a2e9219f72980e4efd62fc9ec1f8), ROM_BIOS(3))
ROM_END
ROM_START(mface128)
ROM_REGION(0x2000, "rom", 0)
ROM_DEFAULT_BIOS("v36")
ROM_SYSTEM_BIOS(0, "v36", "v36")
ROMX_LOAD("mf128_36_3c.rom", 0x0000, 0x2000, CRC(78ec8cfd) SHA1(8df204ab490b87c389971ce0c7fb5f9cbd281f14), ROM_BIOS(0))
ROM_END
ROM_START(mface3)
ROM_REGION(0x2000, "rom", 0)
ROM_DEFAULT_BIOS("v50fe")
ROM_SYSTEM_BIOS(0, "v5013", "v50.13")
ROMX_LOAD("mf3_50_13.rom", 0x0000, 0x2000, CRC(2d594640) SHA1(5d74d2e2e5a537639da92ff120f8a6d86f474495), ROM_BIOS(0))
ROM_SYSTEM_BIOS(1, "v50fe", "v50.fe")
ROMX_LOAD("mf3_50_fe.rom", 0x0000, 0x2000, CRC(b5c00f28) SHA1(983699a07665186f498f5827f9b35c442c2178ba), ROM_BIOS(1))
ROM_END
ROM_START(mprint)
ROM_REGION(0x2000, "rom", 0)
ROM_DEFAULT_BIOS("mpa8")
ROM_SYSTEM_BIOS(0, "mp5a", "5A")
ROMX_LOAD("mprint_5a.rom", 0x0000, 0x2000, CRC(3a26e84b) SHA1(4714469bf25f69291f61188f52bfb11fbb8d0b33), ROM_BIOS(0))
ROM_SYSTEM_BIOS(1, "mpa8", "A8")
ROMX_LOAD("mprint_a8.rom", 0x0000, 0x2000, CRC(a5c58022) SHA1(1356bfae3264b952f83a33e25af536c0f13f50e7), ROM_BIOS(1))
ROM_END
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void spectrum_mface1_device::device_add_mconfig(machine_config &config)
{
/* passthru */
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
}
const tiny_rom_entry *spectrum_mface1_device::device_rom_region() const
{
return ROM_NAME(mface1);
}
const tiny_rom_entry *spectrum_mface128_device::device_rom_region() const
{
return ROM_NAME(mface128);
}
const tiny_rom_entry *spectrum_mface3_device::device_rom_region() const
{
return ROM_NAME(mface3);
}
const tiny_rom_entry *spectrum_mprint_device::device_rom_region() const
{
return ROM_NAME(mprint);
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// spectrum_opus_device - constructor
//-------------------------------------------------
spectrum_mface1_device::spectrum_mface1_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_spectrum_expansion_interface(mconfig, *this)
, m_rom(*this, "rom")
, m_exp(*this, "exp")
{
}
spectrum_mface1_device::spectrum_mface1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: spectrum_mface1_device(mconfig, SPECTRUM_MFACE1, tag, owner, clock)
{
}
spectrum_mface128_device::spectrum_mface128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: spectrum_mface1_device(mconfig, SPECTRUM_MFACE128, tag, owner, clock)
{
}
spectrum_mface3_device::spectrum_mface3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: spectrum_mface1_device(mconfig, SPECTRUM_MFACE3, tag, owner, clock)
{
}
spectrum_mprint_device::spectrum_mprint_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: spectrum_mface1_device(mconfig, SPECTRUM_MPRINT, tag, owner, clock)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void spectrum_mface1_device::device_start()
{
save_item(NAME(m_romcs));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void spectrum_mface1_device::device_reset()
{
m_romcs = 0;
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
READ_LINE_MEMBER(spectrum_mface1_device::romcs)
{
return m_romcs | m_exp->romcs();
}
void spectrum_mface1_device::opcode_fetch(offs_t offset)
{
m_exp->opcode_fetch(offset);
if (!machine().side_effects_disabled())
{
if (offset == 0x0066)
m_romcs = 1;
}
}
uint8_t spectrum_mface1_device::iorq_r(offs_t offset)
{
uint8_t data = m_exp->iorq_r(offset);
if (!machine().side_effects_disabled())
{
switch (offset & 0xff)
{
case 0x1f:
m_romcs = 0;
break;
case 0x9f:
m_romcs = 1;
break;
}
}
return data;
}
uint8_t spectrum_mface128_device::iorq_r(offs_t offset)
{
uint8_t data = m_exp->iorq_r(offset);
if (!machine().side_effects_disabled())
{
switch (offset & 0xff)
{
case 0xbf:
m_romcs = 1;
break;
case 0x3f:
m_romcs = 0;
break;
}
}
return data;
}
uint8_t spectrum_mface3_device::iorq_r(offs_t offset)
{
uint8_t data = m_exp->iorq_r(offset);
if (!machine().side_effects_disabled())
{
switch (offset & 0xff)
{
case 0x3f:
m_romcs = 1;
break;
case 0xbf:
m_romcs = 0;
break;
}
}
return data;
}
uint8_t spectrum_mprint_device::iorq_r(offs_t offset)
{
uint8_t data = m_exp->iorq_r(offset);
if (!machine().side_effects_disabled())
{
switch (offset & 0xff)
{
case 0xbb:
m_romcs = 1;
break;
case 0xbf:
m_romcs = 0;
break;
}
}
return data;
}
void spectrum_mface1_device::iorq_w(offs_t offset, uint8_t data)
{
m_exp->iorq_w(offset, data);
}
uint8_t spectrum_mface1_device::mreq_r(offs_t offset)
{
uint8_t data = 0xff;
if (m_romcs)
{
switch (offset & 0xe000)
{
case 0x0000:
data = m_rom->base()[offset & 0x1fff];
break;
case 0x2000:
data = m_ram[offset & 0x1fff];
break;
}
}
if (m_exp->romcs())
data &= m_exp->mreq_r(offset);
return data;
}
void spectrum_mface1_device::mreq_w(offs_t offset, uint8_t data)
{
if (m_romcs)
{
switch (offset & 0xe000)
{
case 0x2000:
m_ram[offset & 0x1fff] = data;
break;
}
}
if (m_exp->romcs())
m_exp->mreq_w(offset, data);
}
INPUT_CHANGED_MEMBER(spectrum_mface1_device::magic_button)
{
if (newval && !oldval)
{
m_slot->nmi_w(ASSERT_LINE);
}
else
{
m_slot->nmi_w(CLEAR_LINE);
}
}

View File

@ -0,0 +1,100 @@
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/*********************************************************************
Romantic Robot Multiface One/128/3
*********************************************************************/
#ifndef MAME_BUS_SPECTRUM_MFACE_H
#define MAME_BUS_SPECTRUM_MFACE_H
#include "exp.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class spectrum_mface1_device :
public device_t,
public device_spectrum_expansion_interface
{
public:
// construction/destruction
spectrum_mface1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
DECLARE_INPUT_CHANGED_MEMBER(magic_button);
protected:
spectrum_mface1_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;
// optional information overrides
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
virtual ioport_constructor device_input_ports() const override;
virtual void opcode_fetch(offs_t offset) override;
virtual uint8_t mreq_r(offs_t offset) override;
virtual void mreq_w(offs_t offset, uint8_t data) override;
virtual uint8_t iorq_r(offs_t offset) override;
virtual void iorq_w(offs_t offset, uint8_t data) override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
required_memory_region m_rom;
required_device<spectrum_expansion_slot_device> m_exp;
uint8_t m_ram[8 * 1024];
int m_romcs;
};
class spectrum_mface128_device : public spectrum_mface1_device
{
public:
spectrum_mface128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
// optional information overrides
virtual const tiny_rom_entry *device_rom_region() const override;
virtual uint8_t iorq_r(offs_t offset) override;
};
class spectrum_mface3_device : public spectrum_mface1_device
{
public:
spectrum_mface3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
// optional information overrides
virtual const tiny_rom_entry *device_rom_region() const override;
virtual uint8_t iorq_r(offs_t offset) override;
};
class spectrum_mprint_device : public spectrum_mface1_device
{
public:
spectrum_mprint_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
// optional information overrides
virtual const tiny_rom_entry *device_rom_region() const override;
virtual uint8_t iorq_r(offs_t offset) override;
};
// device type definition
DECLARE_DEVICE_TYPE(SPECTRUM_MFACE1, spectrum_mface1_device)
DECLARE_DEVICE_TYPE(SPECTRUM_MFACE128, spectrum_mface128_device)
DECLARE_DEVICE_TYPE(SPECTRUM_MFACE3, spectrum_mface3_device)
DECLARE_DEVICE_TYPE(SPECTRUM_MPRINT, spectrum_mprint_device)
#endif // MAME_BUS_SPECTRUM_MFACE_H

View File

@ -85,23 +85,19 @@ void spectrum_mikroplus_device::device_start()
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void spectrum_mikroplus_device::device_reset()
{
io_space().install_read_handler(0xdf, 0xdf, 0, 0xff00, 0, read8smo_delegate(FUNC(spectrum_mikroplus_device::joystick_r), this));
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
uint8_t spectrum_mikroplus_device::joystick_r()
uint8_t spectrum_mikroplus_device::iorq_r(offs_t offset)
{
return m_joy->read() | (0xff ^ 0x1f);
uint8_t data = 0xff;
if (offset == 0xdf)
{
data = m_joy->read() | (0xff ^ 0x1f);
}
return data;
}
READ_LINE_MEMBER(spectrum_mikroplus_device::romcs)

View File

@ -31,7 +31,6 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// optional information overrides
virtual const tiny_rom_entry *device_rom_region() const override;
@ -39,10 +38,9 @@ protected:
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
virtual uint8_t mreq_r(offs_t offset) override;
virtual uint8_t iorq_r(offs_t offset) override;
private:
uint8_t joystick_r();
required_memory_region m_rom;
required_ioport m_joy;
};

View File

@ -72,17 +72,20 @@ void spectrum_protek_device::device_start()
// IMPLEMENTATION
//**************************************************************************
uint8_t spectrum_protek_device::port_fe_r(offs_t offset)
uint8_t spectrum_protek_device::iorq_r(offs_t offset)
{
uint8_t data = 0xff;
uint8_t lines = offset >> 8;
switch (offset & 0xff)
{
case 0xfe:
if (((offset >> 8) & 8) == 0)
data = m_exp_line3->read() | (0xff ^ 0x10);
if ((lines & 8) == 0)
data = m_exp_line3->read() | (0xff ^ 0x10);
if ((lines & 16) == 0)
data = m_exp_line4->read() | (0xff ^ 0x1d);
if (((offset >> 8) & 16) == 0)
data = m_exp_line4->read() | (0xff ^ 0x1d);
break;
}
return data;
}

View File

@ -35,7 +35,7 @@ protected:
// optional information overrides
virtual ioport_constructor device_input_ports() const override;
virtual uint8_t port_fe_r(offs_t offset) override;
virtual uint8_t iorq_r(offs_t offset) override;
private:
required_ioport m_exp_line3;

View File

@ -76,19 +76,21 @@ READ_LINE_MEMBER(spectrum_uslot_device::romcs)
return m_exp1->romcs() | m_exp2->romcs();
}
void spectrum_uslot_device::opcode_fetch(offs_t offset)
{
m_exp1->opcode_fetch(offset);
m_exp2->opcode_fetch(offset);
}
uint8_t spectrum_uslot_device::mreq_r(offs_t offset)
{
uint8_t temp;
uint8_t data = 0xff;
temp = m_exp1->mreq_r(offset);
if (m_exp1->romcs())
data &= temp;
data &= m_exp1->mreq_r(offset);
temp = m_exp2->mreq_r(offset);
if (m_exp2->romcs())
data &= temp;
data &= m_exp2->mreq_r(offset);
return data;
}
@ -102,15 +104,13 @@ void spectrum_uslot_device::mreq_w(offs_t offset, uint8_t data)
m_exp2->mreq_w(offset, data);
}
uint8_t spectrum_uslot_device::port_fe_r(offs_t offset)
uint8_t spectrum_uslot_device::iorq_r(offs_t offset)
{
uint8_t data = 0xff;
if (m_exp1->romcs())
data &= m_exp1->port_fe_r(offset);
if (m_exp2->romcs())
data &= m_exp2->port_fe_r(offset);
return data;
return m_exp1->iorq_r(offset) & m_exp2->iorq_r(offset);
}
void spectrum_uslot_device::iorq_w(offs_t offset, uint8_t data)
{
m_exp1->iorq_w(offset, data);
m_exp2->iorq_w(offset, data);
}

View File

@ -36,9 +36,11 @@ protected:
// optional information overrides
virtual void device_add_mconfig(machine_config &config) override;
virtual void opcode_fetch(offs_t offset) override;
virtual uint8_t mreq_r(offs_t offset) override;
virtual void mreq_w(offs_t offset, uint8_t data) override;
virtual uint8_t port_fe_r(offs_t offset) override;
virtual uint8_t iorq_r(offs_t offset) override;
virtual void iorq_w(offs_t offset, uint8_t data) override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
private:

View File

@ -60,6 +60,7 @@ spectrum_usource_device::spectrum_usource_device(const machine_config &mconfig,
void spectrum_usource_device::device_start()
{
save_item(NAME(m_romcs));
}
@ -82,17 +83,15 @@ READ_LINE_MEMBER(spectrum_usource_device::romcs)
return m_romcs;
}
uint8_t spectrum_usource_device::mreq_r(offs_t offset)
void spectrum_usource_device::opcode_fetch(offs_t offset)
{
uint8_t data;
if (!machine().side_effects_disabled() && (offset == 0x2bae))
{
m_romcs = !m_romcs;
}
data = m_rom->base()[offset & 0x1fff];
return data;
}
uint8_t spectrum_usource_device::mreq_r(offs_t offset)
{
return m_rom->base()[offset & 0x1fff];
}

View File

@ -38,6 +38,7 @@ protected:
// optional information overrides
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void opcode_fetch(offs_t offset) override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
virtual uint8_t mreq_r(offs_t offset) override;

View File

@ -76,6 +76,7 @@ spectrum_uspeech_device::spectrum_uspeech_device(const machine_config &mconfig,
void spectrum_uspeech_device::device_start()
{
save_item(NAME(m_romcs));
}
@ -98,24 +99,26 @@ READ_LINE_MEMBER(spectrum_uspeech_device::romcs)
return m_romcs;
}
uint8_t spectrum_uspeech_device::mreq_r(offs_t offset)
void spectrum_uspeech_device::opcode_fetch(offs_t offset)
{
uint8_t data;
if (!machine().side_effects_disabled() && (offset == 0x38))
if (!machine().side_effects_disabled() && (offset == 0x0038))
{
m_romcs = !m_romcs;
}
}
switch (offset)
uint8_t spectrum_uspeech_device::mreq_r(offs_t offset)
{
uint8_t data = 0xff;
switch (offset & 0xf000)
{
case 0x0000:
data = m_rom->base()[offset & 0x7ff];
break;
case 0x1000:
data = !m_nsp->lrq_r(); // (m_nsp->lrq_r() && (m_nsp->sby_r() != 0)) ? 0x00 : 0x01;
break;
default:
data = m_rom->base()[offset & 0x7ff];
break;
}
return data;
@ -123,7 +126,7 @@ uint8_t spectrum_uspeech_device::mreq_r(offs_t offset)
void spectrum_uspeech_device::mreq_w(offs_t offset, uint8_t data)
{
switch (offset)
switch (offset & 0xf001)
{
case 0x1000:
// allophone

View File

@ -40,6 +40,7 @@ protected:
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
virtual void opcode_fetch(offs_t offset) override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
virtual uint8_t mreq_r(offs_t offset) override;
virtual void mreq_w(offs_t offset, uint8_t data) override;

View File

@ -235,11 +235,12 @@ READ8_MEMBER( spectrum_state::spectrum_128_ula_r )
void spectrum_state::spectrum_128_io(address_map &map)
{
map(0x0000, 0xffff).rw(m_exp, FUNC(spectrum_expansion_slot_device::iorq_r), FUNC(spectrum_expansion_slot_device::iorq_w));
map(0x0000, 0x0000).rw(FUNC(spectrum_state::spectrum_port_fe_r), FUNC(spectrum_state::spectrum_port_fe_w)).select(0xfffe);
map(0x0001, 0x0001).w(FUNC(spectrum_state::spectrum_128_port_7ffd_w)).mirror(0x7ffc); // (A15 | A1) == 0, note: reading from this port does write to it by value from data bus
map(0x8000, 0x8000).w("ay8912", FUNC(ay8910_device::data_w)).mirror(0x3ffd);
map(0xc000, 0xc000).rw("ay8912", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w)).mirror(0x3ffd);
map(0x0001, 0x0001).r(FUNC(spectrum_state::spectrum_128_ula_r)).mirror(0xfffe);
map(0x0001, 0x0001).r(FUNC(spectrum_state::spectrum_128_ula_r)); // .mirror(0xfffe);
}
void spectrum_state::spectrum_128_mem(address_map &map)
@ -297,6 +298,7 @@ void spectrum_state::spectrum_128(machine_config &config)
Z80(config.replace(), m_maincpu, X1_128_SINCLAIR / 5);
m_maincpu->set_addrmap(AS_PROGRAM, &spectrum_state::spectrum_128_mem);
m_maincpu->set_addrmap(AS_IO, &spectrum_state::spectrum_128_io);
m_maincpu->set_addrmap(AS_OPCODES, &spectrum_state::spectrum_fetch);
m_maincpu->set_vblank_int("screen", FUNC(spectrum_state::spec_interrupt));
config.m_minimum_quantum = attotime::from_hz(60);
@ -313,7 +315,6 @@ void spectrum_state::spectrum_128(machine_config &config)
/* expansion port */
SPECTRUM_EXPANSION_SLOT(config.replace(), m_exp, spec128_expansion_devices, nullptr);
m_exp->set_io_space(m_maincpu, AS_IO);
m_exp->irq_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_exp->nmi_handler().set_inputline(m_maincpu, INPUT_LINE_NMI);

View File

@ -198,65 +198,47 @@ READ8_MEMBER( spectrum_state::spectrum_plus3_port_2ffd_r )
void spectrum_state::spectrum_plus3_update_memory()
{
address_space &space = m_maincpu->space(AS_PROGRAM);
uint8_t *messram = m_ram->pointer();
if (m_port_7ffd_data & 8)
{
logerror("+3 SCREEN 1: BLOCK 7\n");
m_screen_location = messram + (7 << 14);
m_screen_location = m_ram->pointer() + (7 << 14);
}
else
{
logerror("+3 SCREEN 0: BLOCK 5\n");
m_screen_location = messram + (5 << 14);
m_screen_location = m_ram->pointer() + (5 << 14);
}
if ((m_port_1ffd_data & 0x01) == 0)
{
/* select ram at 0x0c000-0x0ffff */
int ram_page = m_port_7ffd_data & 0x07;
unsigned char *ram_data = messram + (ram_page<<14);
unsigned char *ram_data = m_ram->pointer() + (ram_page<<14);
membank("bank4")->set_base(ram_data);
logerror("RAM at 0xc000: %02x\n", ram_page);
/* Reset memory between 0x4000 - 0xbfff in case extended paging was being used */
/* Bank 5 in 0x4000 - 0x7fff */
membank("bank2")->set_base(messram + (5 << 14));
membank("bank2")->set_base(m_ram->pointer() + (5 << 14));
/* Bank 2 in 0x8000 - 0xbfff */
membank("bank3")->set_base(messram + (2 << 14));
/* ROM switching */
int ROMSelection = BIT(m_port_7ffd_data, 4) | ((m_port_1ffd_data >> 1) & 0x02);
/* rom 0 is editor, rom 1 is syntax, rom 2 is DOS, rom 3 is 48 BASIC */
unsigned char *ChosenROM = memregion("maincpu")->base() + 0x010000 + (ROMSelection << 14);
membank("bank1")->set_base(ChosenROM);
space.unmap_write(0x0000, 0x3fff);
logerror("rom switch: %02x\n", ROMSelection);
membank("bank3")->set_base(m_ram->pointer() + (2 << 14));
}
else
{
/* Extended memory paging */
int MemorySelection = (m_port_1ffd_data >> 1) & 0x03;
const int *memory_selection = &spectrum_plus3_memory_selections[(MemorySelection << 2)];
unsigned char *ram_data = messram + (memory_selection[0] << 14);
unsigned char *ram_data = m_ram->pointer() + (memory_selection[0] << 14);
membank("bank1")->set_base(ram_data);
/* allow writes to 0x0000-0x03fff */
space.install_write_bank(0x0000, 0x3fff, "bank1");
ram_data = messram + (memory_selection[1] << 14);
ram_data = m_ram->pointer() + (memory_selection[1] << 14);
membank("bank2")->set_base(ram_data);
ram_data = messram + (memory_selection[2] << 14);
ram_data = m_ram->pointer() + (memory_selection[2] << 14);
membank("bank3")->set_base(ram_data);
ram_data = messram + (memory_selection[3] << 14);
ram_data = m_ram->pointer() + (memory_selection[3] << 14);
membank("bank4")->set_base(ram_data);
logerror("extended memory paging: %02x\n", MemorySelection);
@ -264,6 +246,49 @@ void spectrum_state::spectrum_plus3_update_memory()
}
WRITE8_MEMBER(spectrum_state::spectrum_plus3_bank1_w)
{
if (m_exp->romcs())
{
m_exp->mreq_w(offset, data);
}
else if ((m_port_1ffd_data & 0x01) != 0)
{
/* Extended memory paging */
int MemorySelection = (m_port_1ffd_data >> 1) & 0x03;
const int *memory_selection = &spectrum_plus3_memory_selections[(MemorySelection << 2)];
m_ram->pointer()[(memory_selection[0] << 14) + offset] = data;
}
}
READ8_MEMBER(spectrum_state::spectrum_plus3_bank1_r)
{
uint8_t data;
if (m_exp->romcs())
{
data = m_exp->mreq_r(offset);
}
else
{
if ((m_port_1ffd_data & 0x01) == 0)
{
/* ROM switching */
int ROMSelection = BIT(m_port_7ffd_data, 4) | ((m_port_1ffd_data >> 1) & 0x02);
/* rom 0 is editor, rom 1 is syntax, rom 2 is DOS, rom 3 is 48 BASIC */
data = memregion("maincpu")->base()[0x010000 + (ROMSelection << 14) + offset];
}
else
{
/* Extended memory paging */
int MemorySelection = (m_port_1ffd_data >> 1) & 0x03;
const int *memory_selection = &spectrum_plus3_memory_selections[(MemorySelection << 2)];
data = m_ram->pointer()[(memory_selection[0] << 14) + offset];
}
}
return data;
}
WRITE8_MEMBER( spectrum_state::spectrum_plus3_port_7ffd_w )
{
@ -307,7 +332,7 @@ WRITE8_MEMBER( spectrum_state::spectrum_plus3_port_1ffd_w )
The function decodes the ports appropriately */
void spectrum_state::spectrum_plus3_io(address_map &map)
{
map.unmap_value_high();
map(0x0000, 0xffff).rw(m_exp, FUNC(spectrum_expansion_slot_device::iorq_r), FUNC(spectrum_expansion_slot_device::iorq_w));
map(0x0000, 0x0000).rw(FUNC(spectrum_state::spectrum_port_fe_r), FUNC(spectrum_state::spectrum_port_fe_w)).select(0xfffe);
map(0x4000, 0x4000).w(FUNC(spectrum_state::spectrum_plus3_port_7ffd_w)).mirror(0x3ffd);
map(0x8000, 0x8000).w("ay8912", FUNC(ay8910_device::data_w)).mirror(0x3ffd);
@ -319,7 +344,7 @@ void spectrum_state::spectrum_plus3_io(address_map &map)
void spectrum_state::spectrum_plus3_mem(address_map &map)
{
map(0x0000, 0x3fff).bankr("bank1");
map(0x0000, 0x3fff).rw(FUNC(spectrum_state::spectrum_plus3_bank1_r), FUNC(spectrum_state::spectrum_plus3_bank1_w)); //.bankr("bank1");
map(0x4000, 0x7fff).bankrw("bank2");
map(0x8000, 0xbfff).bankrw("bank3");
map(0xc000, 0xffff).bankrw("bank4");
@ -390,7 +415,6 @@ void spectrum_state::spectrum_plus3(machine_config &config)
FLOPPY_CONNECTOR(config, "upd765:1", specpls3_floppies, "3ssdd", floppy_image_device::default_floppy_formats);
SPECTRUM_EXPANSION_SLOT(config.replace(), m_exp, specpls3_expansion_devices, nullptr);
m_exp->set_io_space(m_maincpu, AS_IO);
m_exp->irq_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_exp->nmi_handler().set_inputline(m_maincpu, INPUT_LINE_NMI);

View File

@ -292,6 +292,14 @@ SamRam
/****************************************************************************************************/
/* Spectrum 48k functions */
READ8_MEMBER(spectrum_state::opcode_fetch_r)
{
/* this allows expansion devices to act upon opcode fetches from MEM addresses */
m_exp->opcode_fetch(offset);
return m_maincpu->space(AS_PROGRAM).read_byte(offset);
}
WRITE8_MEMBER(spectrum_state::spectrum_rom_w)
{
if (m_exp->romcs())
@ -302,9 +310,9 @@ READ8_MEMBER(spectrum_state::spectrum_rom_r)
{
uint8_t data;
data = m_exp->mreq_r(offset);
if (!m_exp->romcs())
if (m_exp->romcs())
data = m_exp->mreq_r(offset);
else
data = memregion("maincpu")->base()[offset];
return data;
@ -360,6 +368,10 @@ READ8_MEMBER(spectrum_state::spectrum_port_fe_r)
int joy1 = m_io_joy1.read_safe(0x1f) & 0x1f;
int joy2 = m_io_joy2.read_safe(0x1f) & 0x1f;
/* expansion port */
if (m_exp)
data = m_exp->iorq_r(offset);
/* Caps - V */
if ((lines & 1) == 0)
{
@ -410,10 +422,6 @@ READ8_MEMBER(spectrum_state::spectrum_port_fe_r)
data &= ~0x40;
}
/* expansion port */
if (m_exp)
data &= m_exp->port_fe_r(offset);
/* Issue 2 Spectrums default to having bits 5, 6 & 7 set.
Issue 3 Spectrums default to having bits 5 & 7 set and bit 6 reset. */
if (m_io_config->read() & 0x80)
@ -439,12 +447,18 @@ void spectrum_state::spectrum_mem(address_map &map)
// AM_RANGE(0x8000, 0xffff) AM_RAM
}
void spectrum_state::spectrum_fetch(address_map &map)
{
map(0x0000, 0xffff).r(FUNC(spectrum_state::opcode_fetch_r));
}
/* ports are not decoded full.
The function decodes the ports appropriately */
void spectrum_state::spectrum_io(address_map &map)
{
map(0x0000, 0xffff).rw(m_exp, FUNC(spectrum_expansion_slot_device::iorq_r), FUNC(spectrum_expansion_slot_device::iorq_w));
map(0x00, 0x00).rw(FUNC(spectrum_state::spectrum_port_fe_r), FUNC(spectrum_state::spectrum_port_fe_w)).select(0xfffe);
map(0x01, 0x01).r(FUNC(spectrum_state::spectrum_port_ula_r)).mirror(0xfffe);
map(0x01, 0x01).r(FUNC(spectrum_state::spectrum_port_ula_r)); // .mirror(0xfffe);
}
/* Input ports */
@ -671,6 +685,7 @@ void spectrum_state::spectrum_common(machine_config &config)
Z80(config, m_maincpu, X1 / 4); /* This is verified only for the ZX Spectrum. Other clones are reported to have different clocks */
m_maincpu->set_addrmap(AS_PROGRAM, &spectrum_state::spectrum_mem);
m_maincpu->set_addrmap(AS_IO, &spectrum_state::spectrum_io);
m_maincpu->set_addrmap(AS_OPCODES, &spectrum_state::spectrum_fetch);
m_maincpu->set_vblank_int("screen", FUNC(spectrum_state::spec_interrupt));
config.m_minimum_quantum = attotime::from_hz(60);
@ -696,7 +711,6 @@ void spectrum_state::spectrum_common(machine_config &config)
/* expansion port */
SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, "kempjoy");
m_exp->set_io_space(m_maincpu, AS_IO);
m_exp->irq_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_exp->nmi_handler().set_inputline(m_maincpu, INPUT_LINE_NMI);

View File

@ -151,6 +151,7 @@ protected:
uint8_t *m_ram_0000;
uint8_t m_ram_disabled_by_beta;
DECLARE_READ8_MEMBER(opcode_fetch_r);
DECLARE_WRITE8_MEMBER(spectrum_rom_w);
DECLARE_READ8_MEMBER(spectrum_rom_r);
DECLARE_WRITE8_MEMBER(spectrum_port_fe_w);
@ -217,6 +218,7 @@ protected:
void spectrum_128_mem(address_map &map);
void spectrum_io(address_map &map);
void spectrum_mem(address_map &map);
void spectrum_fetch(address_map &map);
void spectrum_plus3_io(address_map &map);
void spectrum_plus3_mem(address_map &map);
void tc2048_io(address_map &map);