From 035380ca97d175450f6e32f3d6549912ed691993 Mon Sep 17 00:00:00 2001 From: Nigel Barnes Date: Sat, 7 Sep 2019 17:38:58 +0100 Subject: dragon32: Added JCB Speech Synthesis cartridge. --- hash/dragon_cart.xml | 6 +- scripts/src/bus.lua | 2 + src/devices/bus/coco/dragon_jcbspch.cpp | 155 ++++++++++++++++++++++++++++++++ src/devices/bus/coco/dragon_jcbspch.h | 52 +++++++++++ src/emu/xtal.cpp | 1 + src/mame/drivers/dragon.cpp | 3 + 6 files changed, 216 insertions(+), 3 deletions(-) create mode 100644 src/devices/bus/coco/dragon_jcbspch.cpp create mode 100644 src/devices/bus/coco/dragon_jcbspch.h diff --git a/hash/dragon_cart.xml b/hash/dragon_cart.xml index 900b6298ac5..c01f395e09a 100644 --- a/hash/dragon_cart.xml +++ b/hash/dragon_cart.xml @@ -440,7 +440,7 @@ Compiled by K1W1 and Cowering (from GoodCoCo) 1983 <unknown;> - + @@ -459,12 +459,12 @@ Compiled by K1W1 and Cowering (from GoodCoCo) - + Speech Synthesis Module 1983 J.C.B. (Microsystems) - + diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 853b52dcf9d..60a2223cbf8 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -3093,6 +3093,8 @@ if (BUSES["COCO"]~=null) then MAME_DIR .. "src/devices/bus/coco/dragon_fdc.h", MAME_DIR .. "src/devices/bus/coco/dragon_jcbsnd.cpp", MAME_DIR .. "src/devices/bus/coco/dragon_jcbsnd.h", + MAME_DIR .. "src/devices/bus/coco/dragon_jcbspch.cpp", + MAME_DIR .. "src/devices/bus/coco/dragon_jcbspch.h", MAME_DIR .. "src/devices/bus/coco/dragon_sprites.cpp", MAME_DIR .. "src/devices/bus/coco/dragon_sprites.h", } diff --git a/src/devices/bus/coco/dragon_jcbspch.cpp b/src/devices/bus/coco/dragon_jcbspch.cpp new file mode 100644 index 00000000000..9d774934066 --- /dev/null +++ b/src/devices/bus/coco/dragon_jcbspch.cpp @@ -0,0 +1,155 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + JCB Speech Synthesis Module + + http://archive.worldofdragon.org/index.php?title=Dragon_Speech_Synthesis + + Speech synthesiser cartridge made by J.C.B. (Microsystems). It is based + on the General Instruments SP0256-AL2 speech synthesiser. The cartridge + provides extensions to BASIC for producing speech. + + TODO: verify everything + +***************************************************************************/ + +#include "emu.h" +#include "dragon_jcbspch.h" +#include "speaker.h" + + +ROM_START(dragon_jcbspch) + ROM_REGION(0x10000, "sp0256", 0) + ROM_LOAD("sp0256-al2.bin", 0x1000, 0x0800, CRC(b504ac15) SHA1(e60fcb5fa16ff3f3b69d36c7a6e955744d3feafc)) + + ROM_REGION(0x1000, "eprom", 0) + ROM_LOAD("cb-speech.rom", 0x0000, 0x1000, CRC(e88dfe36) SHA1(df3f64a7a3beeb91469932035af5e4f8a7872aad)) +ROM_END + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(DRAGON_JCBSPCH, dragon_jcbspch_device, "dragon_jcbspch", "Dragon Speech Synthesis Module") + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// dragon_jcbspch_device - constructor +//------------------------------------------------- + +dragon_jcbspch_device::dragon_jcbspch_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, DRAGON_JCBSPCH, tag, owner, clock) + , device_cococart_interface(mconfig, *this ) + , m_eprom(*this, "eprom") + , m_pia(*this, "pia") + , m_nsp(*this, "sp0256") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void dragon_jcbspch_device::device_start() +{ + set_line_value(line::CART, line_value::Q); +} + +//------------------------------------------------- +// dragon_jcbspch_device::get_cart_base +//------------------------------------------------- + +uint8_t* dragon_jcbspch_device::get_cart_base() +{ + return m_eprom->base(); +} + +//------------------------------------------------- +// dragon_jcbspch_device::get_cart_memregion +//------------------------------------------------- + +memory_region* dragon_jcbspch_device::get_cart_memregion() +{ + return m_eprom; +} + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void dragon_jcbspch_device::device_add_mconfig(machine_config &config) +{ + PIA6821(config, m_pia, 0); + m_pia->writepb_handler().set(m_nsp, FUNC(sp0256_device::ald_w)).mask(0x3f); + m_pia->cb2_handler().set(FUNC(dragon_jcbspch_device::pia_cb2_w)); + m_pia->irqb_handler().set(FUNC(dragon_jcbspch_device::nmi_w)); + + SPEAKER(config, "mono").front_center(); + SP0256(config, m_nsp, 3.2768_MHz_XTAL); + m_nsp->standby_callback().set(m_pia, FUNC(pia6821_device::cb1_w)); + m_nsp->add_route(ALL_OUTPUTS, "mono", 1.00); +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const tiny_rom_entry *dragon_jcbspch_device::device_rom_region() const +{ + return ROM_NAME( dragon_jcbspch ); +} + +//------------------------------------------------- +// cts_read +//------------------------------------------------- + +READ8_MEMBER(dragon_jcbspch_device::cts_read) +{ + return m_eprom->base()[offset & 0x0fff]; +} + +//------------------------------------------------- +// scs_read +//------------------------------------------------- + +READ8_MEMBER(dragon_jcbspch_device::scs_read) +{ + uint8_t result = 0x00; + + switch (offset) + { + case 0: case 1: case 2: case 3: + result = m_pia->read(offset); + break; + } + return result; +} + +//------------------------------------------------- +// scs_write +//------------------------------------------------- + +WRITE8_MEMBER(dragon_jcbspch_device::scs_write) +{ + switch (offset) + { + case 0: case 1: case 2: case 3: + m_pia->write(offset, data); + break; + } +} + +WRITE_LINE_MEMBER(dragon_jcbspch_device::pia_cb2_w) +{ + // TODO: what does this do? +} + +WRITE_LINE_MEMBER(dragon_jcbspch_device::nmi_w) +{ + // set the NMI line + set_line_value(line::NMI, state); +} diff --git a/src/devices/bus/coco/dragon_jcbspch.h b/src/devices/bus/coco/dragon_jcbspch.h new file mode 100644 index 00000000000..af11762c04a --- /dev/null +++ b/src/devices/bus/coco/dragon_jcbspch.h @@ -0,0 +1,52 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +#ifndef MAME_BUS_COCO_DRAGON_JCBSPCH_H +#define MAME_BUS_COCO_DRAGON_JCBSPCH_H + +#pragma once + +#include "cococart.h" +#include "machine/6821pia.h" +#include "sound/sp0256.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> dragon_jcbspch_device + +class dragon_jcbspch_device : + public device_t, + public device_cococart_interface +{ +public: + // construction/destruction + dragon_jcbspch_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; +protected: + // device-level overrides + virtual void device_start() override; + virtual uint8_t* get_cart_base() override; + virtual memory_region* get_cart_memregion() override; + + virtual DECLARE_READ8_MEMBER(cts_read) override; + virtual DECLARE_READ8_MEMBER(scs_read) override; + virtual DECLARE_WRITE8_MEMBER(scs_write) override; + +private: + DECLARE_WRITE_LINE_MEMBER(pia_cb2_w); + DECLARE_WRITE_LINE_MEMBER(nmi_w); + + required_memory_region m_eprom; + required_device m_pia; + required_device m_nsp; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(DRAGON_JCBSPCH, dragon_jcbspch_device) + +#endif // MAME_BUS_COCO_DRAGON_JCBSPCH_H diff --git a/src/emu/xtal.cpp b/src/emu/xtal.cpp index f86ab3be4cd..5a0f52b0819 100644 --- a/src/emu/xtal.cpp +++ b/src/emu/xtal.cpp @@ -84,6 +84,7 @@ const double XTAL::known_xtals[] = { 3'000'000, /* 3_MHz_XTAL Probably only used to drive 68705 or similar MCUs on 80's Taito PCBs */ 3'072'000, /* 3.072_MHz_XTAL INS 8520 input clock rate */ 3'120'000, /* 3.12_MHz_XTAL SP0250 clock on Gottlieb games */ + 3'276'800, /* 3.2768_MHz_XTAL SP0256 clock in Speech Synthesis for Dragon 32 */ 3'521'280, /* 3.52128_MHz_XTAL RCA COSMAC VIP */ 3'570'000, /* 3.57_MHz_XTAL Telmac TMC-600 */ 3'578'640, /* 3.57864_MHz_XTAL Atari Portfolio PCD3311T */ diff --git a/src/mame/drivers/dragon.cpp b/src/mame/drivers/dragon.cpp index 97bccd7bc45..abb3c86e18f 100644 --- a/src/mame/drivers/dragon.cpp +++ b/src/mame/drivers/dragon.cpp @@ -23,6 +23,7 @@ #include "bus/coco/dragon_amtor.h" #include "bus/coco/dragon_fdc.h" #include "bus/coco/dragon_jcbsnd.h" +#include "bus/coco/dragon_jcbspch.h" #include "bus/coco/dragon_sprites.h" #include "bus/coco/coco_pak.h" #include "bus/coco/coco_ssc.h" @@ -172,6 +173,7 @@ void dragon_cart(device_slot_interface &device) device.option_add("premier_fdc", PREMIER_FDC); device.option_add("sdtandy_fdc", SDTANDY_FDC); device.option_add("jcbsnd", DRAGON_JCBSND); + device.option_add("jcbspch", DRAGON_JCBSPCH); device.option_add("sprites", DRAGON_SPRITES); device.option_add("ssc", COCO_SSC); device.option_add("orch90", COCO_ORCH90); @@ -240,6 +242,7 @@ void dragon_state::dragon_base(machine_config &config) SAM6883(config, m_sam, 14.218_MHz_XTAL, m_maincpu); m_sam->res_rd_callback().set(FUNC(dragon_state::sam_read)); + CASSETTE(config, m_cassette); m_cassette->set_formats(coco_cassette_formats); m_cassette->set_default_state(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED); -- cgit v1.2.3