summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/einstein/pipe
diff options
context:
space:
mode:
author Dirk Best <mail@dirk-best.de>2017-11-20 01:37:08 +0100
committer Dirk Best <mail@dirk-best.de>2017-11-20 01:37:42 +0100
commita5a8e0cbdb29b256d08497ea122b40eff241d471 (patch)
tree89b82c8dc02c53cf929b0a58b0d4bf8a975fe47c /src/devices/bus/einstein/pipe
parent4a211c8443f71271f163b85d1db9606da5904898 (diff)
einstein: Improve interrupts, add WIP Speculator support
Also removes a bogus character in the initial centronics output.
Diffstat (limited to 'src/devices/bus/einstein/pipe')
-rw-r--r--src/devices/bus/einstein/pipe/pipe.cpp15
-rw-r--r--src/devices/bus/einstein/pipe/pipe.h6
-rw-r--r--src/devices/bus/einstein/pipe/speculator.cpp206
-rw-r--r--src/devices/bus/einstein/pipe/speculator.h66
4 files changed, 293 insertions, 0 deletions
diff --git a/src/devices/bus/einstein/pipe/pipe.cpp b/src/devices/bus/einstein/pipe/pipe.cpp
index 106dbe0f8ec..51169544ba7 100644
--- a/src/devices/bus/einstein/pipe/pipe.cpp
+++ b/src/devices/bus/einstein/pipe/pipe.cpp
@@ -11,6 +11,7 @@
// supported devices
#include "silicon_disc.h"
+#include "speculator.h"
#include "tk02.h"
@@ -55,6 +56,9 @@ tatung_pipe_device::~tatung_pipe_device()
void tatung_pipe_device::device_start()
{
+ // get inserted module
+ m_card = dynamic_cast<device_tatung_pipe_interface *>(get_card_device());
+
// resolve callbacks
m_int_handler.resolve_safe();
m_nmi_handler.resolve_safe();
@@ -70,6 +74,16 @@ void tatung_pipe_device::device_reset()
}
//-------------------------------------------------
+// host to module interface
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( tatung_pipe_device::host_int_w )
+{
+ if (m_card)
+ m_card->int_w(state);
+}
+
+//-------------------------------------------------
// set_program_space - set address space we are attached to
//-------------------------------------------------
@@ -117,5 +131,6 @@ device_tatung_pipe_interface::~device_tatung_pipe_interface()
SLOT_INTERFACE_START( tatung_pipe_cards )
SLOT_INTERFACE("silicon_disc", EINSTEIN_SILICON_DISC)
+ SLOT_INTERFACE("speculator", EINSTEIN_SPECULATOR)
SLOT_INTERFACE("tk02", TK02_80COL)
SLOT_INTERFACE_END
diff --git a/src/devices/bus/einstein/pipe/pipe.h b/src/devices/bus/einstein/pipe/pipe.h
index 759103595c6..02be494cb2e 100644
--- a/src/devices/bus/einstein/pipe/pipe.h
+++ b/src/devices/bus/einstein/pipe/pipe.h
@@ -90,6 +90,9 @@ public:
template <class Object> static devcb_base &set_reset_handler(device_t &device, Object &&cb)
{ return downcast<tatung_pipe_device &>(device).m_reset_handler.set_callback(std::forward<Object>(cb)); }
+ // called from host
+ DECLARE_WRITE_LINE_MEMBER( host_int_w );
+
// called from card device
DECLARE_WRITE_LINE_MEMBER( int_w ) { m_int_handler(state); }
DECLARE_WRITE_LINE_MEMBER( nmi_w ) { m_nmi_handler(state); }
@@ -119,6 +122,9 @@ public:
device_tatung_pipe_interface(const machine_config &mconfig, device_t &device);
virtual ~device_tatung_pipe_interface();
+ // host to card
+ virtual void int_w(int state) { }
+
protected:
address_space &program_space() { return *m_slot->m_program; }
address_space &io_space() { return *m_slot->m_io; }
diff --git a/src/devices/bus/einstein/pipe/speculator.cpp b/src/devices/bus/einstein/pipe/speculator.cpp
new file mode 100644
index 00000000000..51918b018ca
--- /dev/null
+++ b/src/devices/bus/einstein/pipe/speculator.cpp
@@ -0,0 +1,206 @@
+// license: GPL-2.0+
+// copyright-holders: Dirk Best
+/***************************************************************************
+
+ Speculator
+
+ TODO: Not working, based on the schematics of the Memotech MTX version
+
+***************************************************************************/
+
+#include "emu.h"
+#include "speculator.h"
+#include "machine/rescap.h"
+#include "sound/wave.h"
+#include "formats/tzx_cas.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(EINSTEIN_SPECULATOR, einstein_speculator_device, "einstein_speculator", "Einstein Speculator")
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+MACHINE_CONFIG_MEMBER( einstein_speculator_device::device_add_mconfig )
+ MCFG_DEVICE_ADD("ic5a", TTL74123, 0)
+ MCFG_TTL74123_CONNECTION_TYPE(TTL74123_NOT_GROUNDED_NO_DIODE)
+ MCFG_TTL74123_RESISTOR_VALUE(RES_K(47))
+ MCFG_TTL74123_CAPACITOR_VALUE(CAP_P(560))
+ MCFG_TTL74123_A_PIN_VALUE(1)
+ MCFG_TTL74123_B_PIN_VALUE(1)
+ MCFG_TTL74123_CLEAR_PIN_VALUE(0)
+ MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITELINE(einstein_speculator_device, ic5a_q_w))
+
+ MCFG_DEVICE_ADD("ic5b", TTL74123, 0)
+ MCFG_TTL74123_CONNECTION_TYPE(TTL74123_NOT_GROUNDED_NO_DIODE)
+ MCFG_TTL74123_RESISTOR_VALUE(RES_K(47))
+ MCFG_TTL74123_CAPACITOR_VALUE(CAP_P(560))
+ MCFG_TTL74123_A_PIN_VALUE(1)
+ MCFG_TTL74123_B_PIN_VALUE(1)
+ MCFG_TTL74123_CLEAR_PIN_VALUE(0)
+ MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITELINE(einstein_speculator_device, ic5b_q_w))
+
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette")
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
+ MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
+
+ MCFG_CASSETTE_ADD("cassette")
+ MCFG_CASSETTE_FORMATS(tzx_cassette_formats)
+ MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_ENABLED)
+ MCFG_CASSETTE_INTERFACE("spectrum_cass")
+MACHINE_CONFIG_END
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// einstein_speculator_device - constructor
+//-------------------------------------------------
+
+einstein_speculator_device::einstein_speculator_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, EINSTEIN_SPECULATOR, tag, owner, clock),
+ device_tatung_pipe_interface(mconfig, *this),
+ m_ic5a(*this, "ic5a"), m_ic5b(*this, "ic5b"),
+ m_cassette(*this, "cassette"),
+ m_speaker(*this, "speaker"),
+ m_nmisel(0)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void einstein_speculator_device::device_start()
+{
+ // setup ram
+ m_ram = std::make_unique<uint8_t[]>(0x800);
+ memset(m_ram.get(), 0xff, 0x800);
+
+ // register for save states
+ save_pointer(NAME(m_ram.get()), 0x800);
+ save_item(NAME(m_nmisel));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void einstein_speculator_device::device_reset()
+{
+ // ram: range 0x1f, 0x3f, 0x5f, 0x7f, 0x9f, 0xbf, 0xdf, 0xff
+ io_space().install_readwrite_handler(0x1f, 0x1f, 0, 0, 0xffe0,
+ read8_delegate(FUNC(einstein_speculator_device::ram_r), this),
+ write8_delegate(FUNC(einstein_speculator_device::ram_w), this));
+
+ // ram: range 0x60 - 0xff
+ io_space().install_readwrite_handler(0x60, 0x60, 0, 0, 0xff9f,
+ read8_delegate(FUNC(einstein_speculator_device::ram_r), this),
+ write8_delegate(FUNC(einstein_speculator_device::ram_w), this));
+
+ // tape read/nmi write register: range 0xff
+ io_space().install_readwrite_handler(0xff, 0xff, 0, 0, 0xff00,
+ read8_delegate(FUNC(einstein_speculator_device::tape_r), this),
+ write8_delegate(FUNC(einstein_speculator_device::nmi_w), this));
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+WRITE_LINE_MEMBER( einstein_speculator_device::ic5a_q_w )
+{
+ m_ic5b->a_w(state);
+
+ if (m_nmisel == 1)
+ {
+ logerror("imm nmi: %d\n", state);
+ m_slot->nmi_w(state);
+ }
+}
+
+WRITE_LINE_MEMBER( einstein_speculator_device::ic5b_q_w )
+{
+ if (m_nmisel == 0)
+ {
+ logerror("del nmi: %d\n", state);
+ m_slot->nmi_w(state);
+ }
+}
+
+void einstein_speculator_device::int_w(int state)
+{
+ logerror("int_w: %d\n", state);
+ m_ic5a->a_w(!state);
+}
+
+// pal ic4
+offs_t einstein_speculator_device::address_translate(offs_t offset)
+{
+ int ra3, ra2, ra1, ra0;
+
+ ra3 = !BIT(offset, 7) && BIT(offset, 0);
+
+ ra2 = BIT(offset, 15) && BIT(offset, 14) && BIT(offset, 13) && BIT(offset, 12) && !BIT(offset, 11);
+ ra2 |= BIT(offset, 15) && BIT(offset, 14) && BIT(offset, 13) && BIT(offset, 12) && !BIT(offset, 10);
+ ra2 |= BIT(offset, 15) && BIT(offset, 14) && BIT(offset, 13) && BIT(offset, 12) && !BIT(offset, 9);
+ ra2 |= BIT(offset, 15) && BIT(offset, 14) && BIT(offset, 13) && BIT(offset, 12) && !BIT(offset, 8);
+
+ ra1 = BIT(offset, 15) && BIT(offset, 14) && !BIT(offset, 13);
+ ra1 |= BIT(offset, 15) && BIT(offset, 14) && !BIT(offset, 12);
+ ra1 |= BIT(offset, 15) && BIT(offset, 14) && BIT(offset, 11) && BIT(offset, 10) && !BIT(offset, 9);
+ ra1 |= BIT(offset, 15) && BIT(offset, 14) && BIT(offset, 11) && BIT(offset, 10) && !BIT(offset, 8);
+
+ ra0 = BIT(offset, 15) && !BIT(offset, 14);
+ ra0 |= BIT(offset, 15) && BIT(offset, 13) && !BIT(offset, 12);
+ ra0 |= BIT(offset, 15) && BIT(offset, 13) && BIT(offset, 11) && !BIT(offset, 10);
+ ra0 |= BIT(offset, 15) && BIT(offset, 13) && BIT(offset, 11) && BIT(offset, 9) && !BIT(offset, 8);
+
+ return (ra3 << 3) | (ra2 << 2) | (ra1 << 1) | (ra0 << 0);
+}
+
+READ8_MEMBER( einstein_speculator_device::ram_r )
+{
+ offs_t addr = ((offset << 4) & 0x7f) | address_translate(offset);
+ return m_ram[addr];
+}
+
+WRITE8_MEMBER( einstein_speculator_device::ram_w )
+{
+ offs_t addr = ((offset << 4) & 0x7f) | address_translate(offset);
+ m_ram[addr] = data;
+}
+
+READ8_MEMBER( einstein_speculator_device::tape_r )
+{
+ // 7654321- unknown
+ // -------0 cassette input
+
+ return m_cassette->input() > 0.0038 ? 1 : 0;
+}
+
+WRITE8_MEMBER( einstein_speculator_device::nmi_w )
+{
+ logerror("nmi_w offset %04x data %02x\n", offset, data);
+
+ // 76543--- unknown
+ // -----2-- nmi enable?
+ // ------1- nmi select?
+ // -------0 speaker?
+
+ m_ic5a->clear_w(BIT(data, 2));
+ m_ic5b->clear_w(BIT(data, 2));
+
+ m_nmisel = BIT(data, 1);
+
+ m_speaker->level_w(BIT(data, 0));
+}
diff --git a/src/devices/bus/einstein/pipe/speculator.h b/src/devices/bus/einstein/pipe/speculator.h
new file mode 100644
index 00000000000..348187012c5
--- /dev/null
+++ b/src/devices/bus/einstein/pipe/speculator.h
@@ -0,0 +1,66 @@
+// license: GPL-2.0+
+// copyright-holders: Dirk Best
+/***************************************************************************
+
+ Speculator
+
+ A Spectrum emulator
+
+***************************************************************************/
+
+#ifndef MAME_BUS_EINSTEIN_PIPE_SPECULATOR_H
+#define MAME_BUS_EINSTEIN_PIPE_SPECULATOR_H
+
+#pragma once
+
+#include "pipe.h"
+#include "machine/74123.h"
+#include "imagedev/cassette.h"
+#include "sound/spkrdev.h"
+#include "speaker.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> einstein_speculator_device
+
+class einstein_speculator_device : public device_t, public device_tatung_pipe_interface
+{
+public:
+ // construction/destruction
+ einstein_speculator_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual void int_w(int state) override;
+
+ DECLARE_READ8_MEMBER(ram_r);
+ DECLARE_WRITE8_MEMBER(ram_w);
+ DECLARE_READ8_MEMBER(tape_r);
+ DECLARE_WRITE8_MEMBER(nmi_w);
+
+ DECLARE_WRITE_LINE_MEMBER(ic5a_q_w);
+ DECLARE_WRITE_LINE_MEMBER(ic5b_q_w);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ offs_t address_translate(offs_t offset);
+
+ required_device<ttl74123_device> m_ic5a;
+ required_device<ttl74123_device> m_ic5b;
+ required_device<cassette_image_device> m_cassette;
+ required_device<speaker_sound_device> m_speaker;
+
+ std::unique_ptr<uint8_t[]> m_ram;
+
+ int m_nmisel;
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(EINSTEIN_SPECULATOR, einstein_speculator_device)
+
+#endif // MAME_BUS_EINSTEIN_PIPE_SPECULATOR_H