From 82b7fb4eceae20982e9c2695691957d8475c364d Mon Sep 17 00:00:00 2001 From: Michael Zapf Date: Wed, 2 Sep 2020 00:03:04 +0200 Subject: [PATCH] ti99: Added SID Master expansion card. --- scripts/src/bus.lua | 2 + src/devices/bus/ti99/peb/peribox.cpp | 8 ++- src/devices/bus/ti99/peb/sidmaster.cpp | 98 ++++++++++++++++++++++++++ src/devices/bus/ti99/peb/sidmaster.h | 47 ++++++++++++ src/mame/drivers/ti99_4p.cpp | 14 +++- src/mame/drivers/ti99_4x.cpp | 17 ++++- 6 files changed, 181 insertions(+), 5 deletions(-) create mode 100644 src/devices/bus/ti99/peb/sidmaster.cpp create mode 100644 src/devices/bus/ti99/peb/sidmaster.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 88b73e56729..125e69e982e 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -3252,6 +3252,8 @@ if (BUSES["TI99"]~=null) then MAME_DIR .. "src/devices/bus/ti99/peb/pgram.h", MAME_DIR .. "src/devices/bus/ti99/peb/samsmem.cpp", MAME_DIR .. "src/devices/bus/ti99/peb/samsmem.h", + MAME_DIR .. "src/devices/bus/ti99/peb/sidmaster.cpp", + MAME_DIR .. "src/devices/bus/ti99/peb/sidmaster.h", MAME_DIR .. "src/devices/bus/ti99/peb/spchsyn.cpp", MAME_DIR .. "src/devices/bus/ti99/peb/spchsyn.h", MAME_DIR .. "src/devices/bus/ti99/peb/ti_32kmem.cpp", diff --git a/src/devices/bus/ti99/peb/peribox.cpp b/src/devices/bus/ti99/peb/peribox.cpp index 773aa0723f4..17460dea555 100644 --- a/src/devices/bus/ti99/peb/peribox.cpp +++ b/src/devices/bus/ti99/peb/peribox.cpp @@ -197,6 +197,7 @@ CRUCLK* 51||52 DBIN #include "horizon.h" #include "forti.h" #include "pgram.h" +#include "sidmaster.h" #define LOG_WARN (1U<<1) // Warnings #define LOG_CONFIG (1U<<2) // Configuration @@ -499,6 +500,7 @@ void ti99_peribox_slot_standard(device_slot_interface &device) device.option_add("ccfdc", TI99_CCFDC); device.option_add("ddcc1", TI99_DDCC1); device.option_add("forti", TI99_FORTI); + device.option_add("sidmaster", TI99_SIDMASTER); } void peribox_device::device_add_mconfig(machine_config &config) @@ -543,6 +545,7 @@ void ti99_peribox_slot_evpc(device_slot_interface &device) device.option_add("ccfdc", TI99_CCFDC); device.option_add("ddcc1", TI99_DDCC1); device.option_add("forti", TI99_FORTI); + device.option_add("sidmaster", TI99_SIDMASTER); } void peribox_ev_device::device_add_mconfig(machine_config &config) @@ -580,7 +583,9 @@ peribox_genmod_device::peribox_genmod_device(const machine_config &mconfig, cons } // The BwG controller will not run with the Geneve due to its wait state -// logic (see bwg.c) +// logic (see bwg.cpp) +// The SID master card may have trouble with the Geneve because of its CRU +// handling (see sidmaster.cpp) void ti99_peribox_slot_geneve(device_slot_interface &device) { @@ -651,6 +656,7 @@ void ti99_peribox_slot_sgcpu(device_slot_interface &device) device.option_add("ccfdc", TI99_CCFDC); device.option_add("ddcc1", TI99_DDCC1); device.option_add("forti", TI99_FORTI); + device.option_add("sidmaster", TI99_SIDMASTER); } void peribox_sg_device::device_add_mconfig(machine_config &config) diff --git a/src/devices/bus/ti99/peb/sidmaster.cpp b/src/devices/bus/ti99/peb/sidmaster.cpp new file mode 100644 index 00000000000..426b3f00346 --- /dev/null +++ b/src/devices/bus/ti99/peb/sidmaster.cpp @@ -0,0 +1,98 @@ +// license:LGPL-2.1+ +// copyright-holders:Michael Zapf +/**************************************************************************** + + SID Master 99 + Original circuit copyright 2010 by Marc Hull + Board layout and board artwork copyright 2010 by Jim Fetzner + + This expansion card adds a SID sound generator chip to the TI system. + + The circuitry has an unconventional selection mechanism: It assumes to be + active at all times, unless a CRU address 1xxx and higher appears on the + bus. This requires that the 9901 addresses be visible on the bus. Also, it + has to be verified whether the real Geneve works with the SID Master. + + The SID is mapped to addresses 5800-5836 (even addresses only), incompletely + decoded (5800-5FFF). + + Michael Zapf + September 2020 + +*****************************************************************************/ + +#include "emu.h" +#include "sidmaster.h" + +#define LOG_WARN (1U<<1) +#define LOG_WRITE (1U<<2) + +#define VERBOSE ( LOG_GENERAL | LOG_WARN ) + +#include "logmacro.h" + +DEFINE_DEVICE_TYPE_NS(TI99_SIDMASTER, bus::ti99::peb, sidmaster_device, "ti99_sidmaster", "SID Master 99") + +namespace bus { namespace ti99 { namespace peb { + +sidmaster_device::sidmaster_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, TI99_SIDMASTER, tag, owner, clock), + device_ti99_peribox_card_interface(mconfig, *this), + m_sid(*this, "sid") +{ +} + +void sidmaster_device::write(offs_t offset, uint8_t data) +{ + if (m_selected && ((offset & 0xf800)==0x5800)) + { + LOGMASKED(LOG_WRITE, "%04x <- %02x\n", offset, data); + m_sid->write((offset >> 1)& 0x1f, data); + } +} + +/* + CRU read access + There is actually no CRU access; the card is deselected when CRU devices + 0x1000 and higher are accessed. +*/ +void sidmaster_device::crureadz(offs_t offset, uint8_t *value) +{ + bool prevsel = m_selected; + m_selected = ((offset & 0xf000) == 0x0000); + if (prevsel && !m_selected) + m_sid->reset(); +} + +/* + CRU write access + There is actually no CRU access; the card is deselected when CRU devices + 0x1000 and higher are accessed. +*/ +void sidmaster_device::cruwrite(offs_t offset, uint8_t data) +{ + bool prevsel = m_selected; + m_selected = ((offset & 0xf000) == 0x0000); + if (prevsel && !m_selected) + m_sid->reset(); +} + +void sidmaster_device::device_add_mconfig(machine_config &config) +{ + // sound hardware + SPEAKER(config, "mono").front_center(); + MOS6581(config, m_sid, XTAL(17'734'472)/18); + m_sid->add_route(ALL_OUTPUTS, "mono", 1.00); +} + +void sidmaster_device::device_start() +{ +} + +void sidmaster_device::device_reset() +{ + m_sid->reset(); +} + + +} } } // end namespace bus::ti99::peb diff --git a/src/devices/bus/ti99/peb/sidmaster.h b/src/devices/bus/ti99/peb/sidmaster.h new file mode 100644 index 00000000000..fb31384571f --- /dev/null +++ b/src/devices/bus/ti99/peb/sidmaster.h @@ -0,0 +1,47 @@ +// license:LGPL-2.1+ +// copyright-holders:Michael Zapf +/**************************************************************************** + + SID Master 99 + See sidmaster.cpp for documentation + + Michael Zapf + September 2020 + +*****************************************************************************/ + +#ifndef MAME_BUS_TI99_PEB_SIDMASTER_H +#define MAME_BUS_TI99_PEB_SIDMASTER_H + +#pragma once + +#include "peribox.h" +#include "sound/mos6581.h" +#include "speaker.h" + +namespace bus { namespace ti99 { namespace peb { + +class sidmaster_device : public device_t, public device_ti99_peribox_card_interface +{ +public: + sidmaster_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + void readz(offs_t offset, uint8_t *value) override { }; // No read + void write(offs_t offset, uint8_t data) override; + + // Only for selection/deselection + void crureadz(offs_t offset, uint8_t *value) override; + void cruwrite(offs_t offset, uint8_t data) override; + +private: + void device_start() override; + void device_reset() override; + void device_add_mconfig(machine_config &config) override; + + required_device m_sid; +}; + +} } } // end namespace bus::ti99::peb + +DECLARE_DEVICE_TYPE_NS(TI99_SIDMASTER, bus::ti99::peb, sidmaster_device) + +#endif // MAME_BUS_TI99_PEB_SIDMASTER_H diff --git a/src/mame/drivers/ti99_4p.cpp b/src/mame/drivers/ti99_4p.cpp index d049932255d..e44e9c54b1c 100644 --- a/src/mame/drivers/ti99_4p.cpp +++ b/src/mame/drivers/ti99_4p.cpp @@ -302,7 +302,6 @@ void ti99_4p_state::memmap_setaddress(address_map &map) void ti99_4p_state::crumap(address_map &map) { map(0x0000, 0x1fff).rw(FUNC(ti99_4p_state::cruread), FUNC(ti99_4p_state::cruwrite)); - map(0x0000, 0x03ff).rw(m_tms9901, FUNC(tms9901_device::read), FUNC(tms9901_device::write)); } /* @@ -692,6 +691,12 @@ WRITE_LINE_MEMBER( ti99_4p_state::datamux_clock_in ) */ void ti99_4p_state::cruwrite(offs_t offset, uint8_t data) { + // Internal 9901 + // We cannot use the map because device in the Peribox may want to see the + // CRU address on the bus (see sidmaster) + if ((offset & 0xfc00)==0) + m_tms9901->write(offset & 0x3f, data); + int addroff = offset<<1; if ((addroff & 0xff00)==MAP_CRU_BASE) @@ -717,6 +722,13 @@ void ti99_4p_state::cruwrite(offs_t offset, uint8_t data) uint8_t ti99_4p_state::cruread(offs_t offset) { uint8_t value = 0; + + // Internal 9901 + // We cannot use the map because devices in the Peribox may want to see the + // CRU address on the bus (see sidmaster) + if ((offset & 0xfc00)==0) + value = m_tms9901->read(offset & 0x3f); + m_peribox->crureadz(offset<<1, &value); return value; } diff --git a/src/mame/drivers/ti99_4x.cpp b/src/mame/drivers/ti99_4x.cpp index b5426fc89ec..1a432d6542c 100644 --- a/src/mame/drivers/ti99_4x.cpp +++ b/src/mame/drivers/ti99_4x.cpp @@ -256,7 +256,6 @@ void ti99_4x_state::memmap_setaddress(address_map &map) void ti99_4x_state::crumap(address_map &map) { map(0x0000, 0x1fff).rw(FUNC(ti99_4x_state::cruread), FUNC(ti99_4x_state::cruwrite)); - map(0x0000, 0x003f).mirror(0x03c0).rw(m_tms9901, FUNC(tms9901_device::read), FUNC(tms9901_device::write)); } @@ -408,12 +407,17 @@ INPUT_PORTS_END uint8_t ti99_4x_state::cruread(offs_t offset) { - LOGMASKED(LOG_CRUREAD, "read access to CRU address %04x\n", offset << 1); uint8_t value = 0; + LOGMASKED(LOG_CRUREAD, "read access to CRU address %04x\n", offset << 1); + + // Internal 9901 + // We cannot use the map because devices in the Peribox may want to see the + // CRU address on the bus (see sidmaster) + if ((offset & 0xfc00)==0) + value = m_tms9901->read(offset & 0x3f); // Let the gromport (not in the QI version) and the p-box behind the I/O port // decide whether they want to change the value at the CRU address - if (m_model != MODEL_4QI) m_gromport->crureadz(offset<<1, &value); m_ioport->crureadz(offset<<1, &value); @@ -423,6 +427,13 @@ uint8_t ti99_4x_state::cruread(offs_t offset) void ti99_4x_state::cruwrite(offs_t offset, uint8_t data) { LOGMASKED(LOG_CRU, "Write access to CRU address %04x\n", offset << 1); + + // Internal 9901 + // We cannot use the map because device in the Peribox may want to see the + // CRU address on the bus (see sidmaster) + if ((offset & 0xfc00)==0) + m_tms9901->write(offset & 0x3f, data); + // The QI version does not propagate the CRU signals to the cartridge slot if (m_model != MODEL_4QI) m_gromport->cruwrite(offset<<1, data); m_ioport->cruwrite(offset<<1, data);