ti99: Added SID Master expansion card.

This commit is contained in:
Michael Zapf 2020-09-02 00:03:04 +02:00
parent 63a89f22da
commit 82b7fb4ece
6 changed files with 181 additions and 5 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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