mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
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:
parent
d62970843f
commit
09f698ddc8
@ -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",
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
@ -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:
|
||||
|
321
src/devices/bus/spectrum/mface.cpp
Normal file
321
src/devices/bus/spectrum/mface.cpp
Normal 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);
|
||||
}
|
||||
}
|
100
src/devices/bus/spectrum/mface.h
Normal file
100
src/devices/bus/spectrum/mface.h
Normal 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
|
@ -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)
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user