From 908529aa32a9b620535ee3604b210f80fdc761a0 Mon Sep 17 00:00:00 2001 From: Dirk Best Date: Tue, 31 Oct 2017 11:46:15 +0100 Subject: einstein: Add bus interface for the user port and emulate speech cart --- scripts/src/bus.lua | 14 +++ scripts/target/mame/mess.lua | 1 + src/devices/bus/einstein/pipe/pipe.h | 6 +- src/devices/bus/einstein/userport/speech.cpp | 88 ++++++++++++++++++ src/devices/bus/einstein/userport/speech.h | 45 +++++++++ src/devices/bus/einstein/userport/userport.cpp | 122 +++++++++++++++++++++++++ src/devices/bus/einstein/userport/userport.h | 96 +++++++++++++++++++ src/mame/drivers/einstein.cpp | 12 ++- 8 files changed, 379 insertions(+), 5 deletions(-) create mode 100644 src/devices/bus/einstein/userport/speech.cpp create mode 100644 src/devices/bus/einstein/userport/speech.h create mode 100644 src/devices/bus/einstein/userport/userport.cpp create mode 100644 src/devices/bus/einstein/userport/userport.h 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 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(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(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 static devcb_base &set_bstb_handler(device_t &device, Object &&cb) + { return downcast(device).m_bstb_handler.set_callback(std::forward(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 -- cgit v1.2.3