summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Dirk Best <mail@dirk-best.de>2017-10-31 11:46:15 +0100
committer Dirk Best <mail@dirk-best.de>2017-10-31 11:46:53 +0100
commit908529aa32a9b620535ee3604b210f80fdc761a0 (patch)
tree70e7d87564e8abc26bd94f10e3f52914651bccd4
parent4ee376d98959b1da2dcbedc13bffe086f949d499 (diff)
einstein: Add bus interface for the user port and emulate speech cart
-rw-r--r--scripts/src/bus.lua14
-rw-r--r--scripts/target/mame/mess.lua1
-rw-r--r--src/devices/bus/einstein/pipe/pipe.h6
-rw-r--r--src/devices/bus/einstein/userport/speech.cpp88
-rw-r--r--src/devices/bus/einstein/userport/speech.h45
-rw-r--r--src/devices/bus/einstein/userport/userport.cpp122
-rw-r--r--src/devices/bus/einstein/userport/userport.h96
-rw-r--r--src/mame/drivers/einstein.cpp12
8 files changed, 379 insertions, 5 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index 36dc17f43e0..def3cf2ef0e 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -3294,3 +3294,17 @@ if (BUSES["TATUNG_PIPE"]~=null) then
MAME_DIR .. "src/devices/bus/einstein/pipe/tk02.h",
}
end
+
+---------------------------------------------------
+--
+--@src/devices/bus/einstein/userport/userport.h,BUSES["EINSTEIN_USERPORT"] = true
+---------------------------------------------------
+
+if (BUSES["EINSTEIN_USERPORT"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/bus/einstein/userport/userport.cpp",
+ MAME_DIR .. "src/devices/bus/einstein/userport/userport.h",
+ MAME_DIR .. "src/devices/bus/einstein/userport/speech.cpp",
+ MAME_DIR .. "src/devices/bus/einstein/userport/speech.h",
+ }
+end
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index b0cdb00f6f5..c10eb0da4cb 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -663,6 +663,7 @@ BUSES["CRVISION"] = true
BUSES["DMV"] = true
BUSES["ECBBUS"] = true
BUSES["ECONET"] = true
+BUSES["EINSTEIN_USERPORT"] = true
BUSES["ELECTRON"] = true
BUSES["EP64"] = true
BUSES["EPSON_SIO"] = true
diff --git a/src/devices/bus/einstein/pipe/pipe.h b/src/devices/bus/einstein/pipe/pipe.h
index d9911ff94d7..759103595c6 100644
--- a/src/devices/bus/einstein/pipe/pipe.h
+++ b/src/devices/bus/einstein/pipe/pipe.h
@@ -39,8 +39,8 @@
***************************************************************************/
-#ifndef MAME_BUS_EINSTEIN_PIPE_H
-#define MAME_BUS_EINSTEIN_PIPE_H
+#ifndef MAME_BUS_EINSTEIN_PIPE_PIPE_H
+#define MAME_BUS_EINSTEIN_PIPE_PIPE_H
#pragma once
@@ -132,4 +132,4 @@ DECLARE_DEVICE_TYPE(TATUNG_PIPE, tatung_pipe_device)
// supported devices
SLOT_INTERFACE_EXTERN(tatung_pipe_cards);
-#endif // MAME_BUS_EINSTEIN_PIPE_H
+#endif // MAME_BUS_EINSTEIN_PIPE_PIPE_H
diff --git a/src/devices/bus/einstein/userport/speech.cpp b/src/devices/bus/einstein/userport/speech.cpp
new file mode 100644
index 00000000000..b98e5d5513e
--- /dev/null
+++ b/src/devices/bus/einstein/userport/speech.cpp
@@ -0,0 +1,88 @@
+// license: GPL-2.0+
+// copyright-holders: Dirk Best
+/***************************************************************************
+
+ Einstein Speech Synthesiser (J&K Software)
+
+ TODO: Verify implementation
+
+***************************************************************************/
+
+#include "emu.h"
+#include "speech.h"
+#include "speaker.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(EINSTEIN_SPEECH, einstein_speech_device, "einstein_speech", "Einstein Speech Synthesiser")
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+ROM_START( sp0256 )
+ ROM_REGION(0x10000, "sp0256", 0)
+ ROM_LOAD("sp0256a-al2.bin", 0x1000, 0x0800, CRC(b504ac15) SHA1(e60fcb5fa16ff3f3b69d36c7a6e955744d3feafc))
+ROM_END
+
+const tiny_rom_entry *einstein_speech_device::device_rom_region() const
+{
+ return ROM_NAME( sp0256 );
+}
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+MACHINE_CONFIG_MEMBER( einstein_speech_device::device_add_mconfig )
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD("sp0256", SP0256, 3120000) // ???
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
+MACHINE_CONFIG_END
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// einstein_speech_device - constructor
+//-------------------------------------------------
+
+einstein_speech_device::einstein_speech_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, EINSTEIN_SPEECH, tag, owner, clock),
+ device_einstein_userport_interface(mconfig, *this),
+ m_sp0256(*this, "sp0256")
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void einstein_speech_device::device_start()
+{
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+// 7------- reset?
+// -6------ sp0256 lrq
+// --543210 sp0256 ald
+
+uint8_t einstein_speech_device::read()
+{
+ return m_sp0256->lrq_r() ? 0x00 : 0x40;
+}
+
+void einstein_speech_device::write(uint8_t data)
+{
+ if (BIT(data, 7) == 0)
+ m_sp0256->ald_w(machine().dummy_space(), 0, data & 0x3f);
+}
diff --git a/src/devices/bus/einstein/userport/speech.h b/src/devices/bus/einstein/userport/speech.h
new file mode 100644
index 00000000000..4c62b24e842
--- /dev/null
+++ b/src/devices/bus/einstein/userport/speech.h
@@ -0,0 +1,45 @@
+// license: GPL-2.0+
+// copyright-holders: Dirk Best
+/***************************************************************************
+
+ Einstein Speech Synthesiser (J&K Software)
+
+***************************************************************************/
+
+#ifndef MAME_BUS_EINSTEIN_USERPORT_SPEECH_H
+#define MAME_BUS_EINSTEIN_USERPORT_SPEECH_H
+
+#pragma once
+
+#include "userport.h"
+#include "sound/sp0256.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> einstein_speech_device
+
+class einstein_speech_device : public device_t, public device_einstein_userport_interface
+{
+public:
+ // construction/destruction
+ einstein_speech_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual void device_start() override;
+
+ virtual uint8_t read() override;
+ virtual void write(uint8_t data) override;
+
+private:
+ required_device<sp0256_device> m_sp0256;
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(EINSTEIN_SPEECH, einstein_speech_device)
+
+#endif // MAME_BUS_EINSTEIN_USERPORT_SPEECH_H
diff --git a/src/devices/bus/einstein/userport/userport.cpp b/src/devices/bus/einstein/userport/userport.cpp
new file mode 100644
index 00000000000..853fbd8777a
--- /dev/null
+++ b/src/devices/bus/einstein/userport/userport.cpp
@@ -0,0 +1,122 @@
+// license: GPL-2.0+
+// copyright-holders: Dirk Best
+/***************************************************************************
+
+ Einstein User Port
+
+***************************************************************************/
+
+#include "emu.h"
+#include "userport.h"
+
+// supported devices
+#include "speech.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(EINSTEIN_USERPORT, einstein_userport_device, "einstein_userport", "Einstein User Port")
+
+
+//**************************************************************************
+// SLOT DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// einstein_userport_device - constructor
+//-------------------------------------------------
+
+einstein_userport_device::einstein_userport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, EINSTEIN_USERPORT, tag, owner, clock),
+ device_slot_interface(mconfig, *this),
+ m_card(nullptr),
+ m_bstb_handler(*this)
+{
+}
+
+//-------------------------------------------------
+// einstein_userport_device - destructor
+//-------------------------------------------------
+
+einstein_userport_device::~einstein_userport_device()
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void einstein_userport_device::device_start()
+{
+ // resolve callbacks
+ m_bstb_handler.resolve_safe();
+
+ m_card = dynamic_cast<device_einstein_userport_interface *>(get_card_device());
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void einstein_userport_device::device_reset()
+{
+}
+
+
+//**************************************************************************
+// I/O PORTS
+//**************************************************************************
+
+READ8_MEMBER( einstein_userport_device::read )
+{
+ if (m_card)
+ return m_card->read();
+ else
+ return 0xff;
+}
+
+WRITE8_MEMBER( einstein_userport_device::write )
+{
+ if (m_card)
+ m_card->write(data);
+}
+
+WRITE_LINE_MEMBER( einstein_userport_device::brdy_w )
+{
+ if (m_card)
+ m_card->brdy_w(state);
+}
+
+
+//**************************************************************************
+// CARTRIDGE INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_einstein_userport_interface - constructor
+//-------------------------------------------------
+
+device_einstein_userport_interface::device_einstein_userport_interface(const machine_config &mconfig, device_t &device) :
+ device_slot_card_interface(mconfig, device)
+{
+ m_slot = dynamic_cast<einstein_userport_device *>(device.owner());
+}
+
+//-------------------------------------------------
+// ~device_einstein_userport_interface - destructor
+//-------------------------------------------------
+
+device_einstein_userport_interface::~device_einstein_userport_interface()
+{
+}
+
+
+//**************************************************************************
+// SLOT INTERFACE
+//**************************************************************************
+
+SLOT_INTERFACE_START( einstein_userport_cards )
+ SLOT_INTERFACE("speech", EINSTEIN_SPEECH)
+SLOT_INTERFACE_END
diff --git a/src/devices/bus/einstein/userport/userport.h b/src/devices/bus/einstein/userport/userport.h
new file mode 100644
index 00000000000..59301644aa3
--- /dev/null
+++ b/src/devices/bus/einstein/userport/userport.h
@@ -0,0 +1,96 @@
+// license: GPL-2.0+
+// copyright-holders: Dirk Best
+/***************************************************************************
+
+ Einstein User Port
+
+ 16-pin slot
+
+ +5V 1 2 D0
+ GND 3 4 D1
+ BRDY 5 6 D2
+ GND 7 8 D3
+ GND 9 10 D4
+ /BSTB 11 12 D5
+ GND 13 14 D6
+ +5V 15 16 D7
+
+***************************************************************************/
+
+#ifndef MAME_BUS_EINSTEIN_USERPORT_USERPORT_H
+#define MAME_BUS_EINSTEIN_USERPORT_USERPORT_H
+
+#pragma once
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_EINSTEIN_USERPORT_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, EINSTEIN_USERPORT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(einstein_userport_cards, nullptr, false)
+
+#define MCFG_EINSTEIN_USERPORT_BSTB_HANDLER(_devcb) \
+ devcb = &einstein_userport_device::set_bstb_handler(*device, DEVCB_##_devcb);
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class device_einstein_userport_interface;
+
+class einstein_userport_device : public device_t, public device_slot_interface
+{
+public:
+ // construction/destruction
+ einstein_userport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ virtual ~einstein_userport_device();
+
+ // callbacks
+ template <class Object> static devcb_base &set_bstb_handler(device_t &device, Object &&cb)
+ { return downcast<einstein_userport_device &>(device).m_bstb_handler.set_callback(std::forward<Object>(cb)); }
+
+ // called from card device
+ DECLARE_WRITE_LINE_MEMBER( bstb_w ) { m_bstb_handler(state); }
+
+ DECLARE_READ8_MEMBER( read );
+ DECLARE_WRITE8_MEMBER (write );
+ DECLARE_WRITE_LINE_MEMBER( brdy_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ device_einstein_userport_interface *m_card;
+
+private:
+ devcb_write_line m_bstb_handler;
+};
+
+// class representing interface-specific live userport device
+class device_einstein_userport_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ virtual ~device_einstein_userport_interface();
+
+ virtual uint8_t read() { return 0xff; }
+ virtual void write(uint8_t data) { }
+ virtual void brdy_w(int state) { }
+
+protected:
+ device_einstein_userport_interface(const machine_config &mconfig, device_t &device);
+
+ einstein_userport_device *m_slot;
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(EINSTEIN_USERPORT, einstein_userport_device)
+
+// supported devices
+SLOT_INTERFACE_EXTERN(einstein_userport_cards);
+
+#endif // MAME_BUS_EINSTEIN_USERPORT_USERPORT_H
diff --git a/src/mame/drivers/einstein.cpp b/src/mame/drivers/einstein.cpp
index 4a333745f5b..19c7266b44f 100644
--- a/src/mame/drivers/einstein.cpp
+++ b/src/mame/drivers/einstein.cpp
@@ -59,6 +59,7 @@
#include "cpu/z80/z80.h"
#include "cpu/z80/z80daisy.h"
+#include "bus/einstein/userport/userport.h"
#include "machine/clock.h"
#include "machine/z80pio.h"
#include "sound/ay8910.h"
@@ -363,7 +364,7 @@ static ADDRESS_MAP_START( einstein_io, AS_IO, 8, einstein_state )
/* block 5, z80ctc */
AM_RANGE(0x28, 0x2b) AM_MIRROR(0xff04) AM_DEVREADWRITE(IC_I058, z80ctc_device, read, write)
/* block 6, z80pio */
- AM_RANGE(0x30, 0x33) AM_MIRROR(0xff04) AM_DEVREADWRITE(IC_I063, z80pio_device, read, write)
+ AM_RANGE(0x30, 0x33) AM_MIRROR(0xff04) AM_DEVREADWRITE(IC_I063, z80pio_device, read_alt, write_alt)
#if 0
/* block 7, adc */
AM_RANGE(0x38, 0x38) AM_MIRROR(0xff07) AM_DEVREADWRITE_LEGACY(IC_I050, adc0844_r, adc0844_w)
@@ -522,7 +523,10 @@ static MACHINE_CONFIG_START( einstein )
MCFG_DEVICE_ADD(IC_I063, Z80PIO, XTAL_X002 / 2)
MCFG_Z80PIO_OUT_INT_CB(INPUTLINE(IC_I001, INPUT_LINE_IRQ0))
MCFG_Z80PIO_OUT_PA_CB(DEVWRITE8("cent_data_out", output_latch_device, write))
- MCFG_Z80PIO_OUT_PB_CB(DEVWRITELINE("centronics", centronics_device, write_strobe))
+ MCFG_Z80PIO_OUT_ARDY_CB(DEVWRITELINE("centronics", centronics_device, write_strobe))
+ MCFG_Z80PIO_IN_PB_CB(DEVREAD8("user", einstein_userport_device, read))
+ MCFG_Z80PIO_OUT_PB_CB(DEVWRITE8("user", einstein_userport_device, write))
+ MCFG_Z80PIO_OUT_BRDY_CB(DEVWRITELINE("user", einstein_userport_device, brdy_w))
MCFG_DEVICE_ADD(IC_I058, Z80CTC, XTAL_X002 / 2)
MCFG_Z80CTC_INTR_CB(INPUTLINE(IC_I001, INPUT_LINE_IRQ0))
@@ -583,6 +587,10 @@ static MACHINE_CONFIG_START( einstein )
// tatung pipe connector
MCFG_TATUNG_PIPE_ADD("pipe")
+
+ // user port
+ MCFG_EINSTEIN_USERPORT_ADD("user")
+ MCFG_EINSTEIN_USERPORT_BSTB_HANDLER(DEVWRITELINE(IC_I063, z80pio_device, strobe_b))
MACHINE_CONFIG_END