einstein: Add bus interface for the user port and emulate speech cart

This commit is contained in:
Dirk Best 2017-10-31 11:46:15 +01:00
parent 4ee376d989
commit 908529aa32
8 changed files with 379 additions and 5 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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