SS-30: add support for the MP-T timer / counter card.

E.g. this can be used SWTPC FLEX for a timer tick.
This commit is contained in:
68bit 2019-08-13 11:51:28 +10:00
parent 6bf8519cf5
commit d041a264de
4 changed files with 248 additions and 32 deletions

View File

@ -1732,6 +1732,8 @@ if (BUSES["SS50"]~=null) then
MAME_DIR .. "src/devices/bus/ss50/mpc.h",
MAME_DIR .. "src/devices/bus/ss50/mps.cpp",
MAME_DIR .. "src/devices/bus/ss50/mps.h",
MAME_DIR .. "src/devices/bus/ss50/mpt.cpp",
MAME_DIR .. "src/devices/bus/ss50/mpt.h",
}
end

View File

@ -42,36 +42,36 @@
***********************************************************************
+-+
|o| RS2 (originally UD3)
|o| RS3 (originally UD4)
|o| -16V (originally -12V)
|o| +16V (originally +12V)
|o| GND
|o| GND
|o| INDEX
|o| /FIRQ (6800: /NMI)
|o| /IRQ
|o| RS0
|o| RS1
|o| D0
|o| D1
|o| D2
|o| D3
|o| D4
|o| D5
|o| D6
|o| D7
|o| E (6800: ϕ2)
|o| R/W
|o| +8V (unregulated)
|o| +8V (unregulated)
|o| 600b/1200b (originally 1200b)
|o| 4800b (originally 600b)
|o| 300b
|o| 150b/9600b (originally 150b)
|o| 110b
|o| /RESET
|o| I/O #
30 |o| RS2 (originally UD3)
29 |o| RS3 (originally UD4)
28 |o| -16V (originally -12V)
27 |o| +16V (originally +12V)
26 |o| GND
25 |o| GND
24 |o| INDEX
23 |o| /FIRQ (6800: /NMI)
22 |o| /IRQ
21 |o| RS0
20 |o| RS1
19 |o| D0
18 |o| D1
17 |o| D2
16 |o| D3
15 |o| D4
14 |o| D5
13 |o| D6
12 |o| D7
11 |o| E (6800: ϕ2)
10 |o| R/W
9 |o| +8V (unregulated)
8 |o| +8V (unregulated)
7 |o| 600b/1200b (originally 1200b)
6 |o| 4800b (originally 600b)
5 |o| 300b
4 |o| 150b/9600b (originally 150b)
3 |o| 110b
2 |o| /RESET
1 |o| I/O #
+-+
**********************************************************************/
@ -83,7 +83,7 @@
//#include "bus/ss50/mpl.h"
//#include "bus/ss50/mpr.h"
#include "bus/ss50/mps.h"
//#include "bus/ss50/mpt.h"
#include "bus/ss50/mpt.h"
//**************************************************************************
// GLOBAL VARIABLES
@ -222,5 +222,5 @@ void ss50_default_2rs_devices(device_slot_interface &device)
//device.option_add("mpl", SS50_MPL);
//device.option_add("mpn", SS50_MPN);
device.option_add("mps", SS50_MPS);
//device.option_add("mpt", SS50_MPT);
device.option_add("mpt", SS50_MPT);
}

View File

@ -0,0 +1,199 @@
// license:BSD-3-Clause
// copyright-holders:68bit
/**********************************************************************
SWTPC MP-T Timer / counter
MC6821 PIA + MK5009 timer/counter
**********************************************************************/
#include "emu.h"
#include "mpt.h"
#include "machine/6821pia.h"
#include "machine/mc14411.h"
class ss50_mpt_device : public device_t, public ss50_card_interface
{
public:
ss50_mpt_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, SS50_MPT, tag, owner, clock)
, ss50_card_interface(mconfig, *this)
, m_pia(*this, "pia")
, m_irqa_jumper(*this, "irqa")
, m_irqb_jumper(*this, "irqb")
{
}
protected:
virtual ioport_constructor device_input_ports() const override;
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
virtual u8 register_read(offs_t offset) override;
virtual void register_write(offs_t offset, u8 data) override;
private:
DECLARE_WRITE8_MEMBER(pia_b_w);
DECLARE_READ8_MEMBER(pia_cb1_r);
DECLARE_WRITE_LINE_MEMBER(pia_irq_b);
TIMER_CALLBACK_MEMBER(mpt_timer_callback);
DECLARE_WRITE_LINE_MEMBER(pia_irqa_w);
DECLARE_WRITE_LINE_MEMBER(pia_irqb_w);
required_device<pia6821_device> m_pia;
required_ioport m_irqa_jumper;
required_ioport m_irqb_jumper;
emu_timer *m_mpt_timer;
attotime m_mpt_duration;
uint8_t m_mpt_timer_state;
};
static INPUT_PORTS_START( mpt )
PORT_START("irqa")
PORT_DIPNAME(1, 0, "IRQ-A")
PORT_DIPSETTING(0, DEF_STR(Off))
PORT_DIPSETTING(1, DEF_STR(On))
PORT_START("irqb")
PORT_DIPNAME(1, 1, "IRQ-B")
PORT_DIPSETTING(0, DEF_STR(Off))
PORT_DIPSETTING(1, DEF_STR(On))
INPUT_PORTS_END
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
ioport_constructor ss50_mpt_device::device_input_ports() const
{
return INPUT_PORTS_NAME(mpt);
}
//-------------------------------------------------
// device_add_mconfig - add device-specific
// machine configuration
//-------------------------------------------------
void ss50_mpt_device::device_add_mconfig(machine_config &config)
{
PIA6821(config, m_pia, 0);
m_pia->writepb_handler().set(FUNC(ss50_mpt_device::pia_b_w));
m_pia->readcb1_handler().set(FUNC(ss50_mpt_device::pia_cb1_r));
m_pia->irqa_handler().set(FUNC(ss50_mpt_device::pia_irqa_w));
m_pia->irqb_handler().set(FUNC(ss50_mpt_device::pia_irqb_w));
}
void ss50_mpt_device::device_start()
{
m_mpt_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ss50_mpt_device::mpt_timer_callback),this));
m_mpt_timer_state = 0;
}
//-------------------------------------------------
// register_read - read from a port register
//-------------------------------------------------
u8 ss50_mpt_device::register_read(offs_t offset)
{
return m_pia->read(offset & 3);
}
//-------------------------------------------------
// register_write - write to a port register
//-------------------------------------------------
void ss50_mpt_device::register_write(offs_t offset, u8 data)
{
m_pia->write(offset & 3, data);
}
WRITE8_MEMBER(ss50_mpt_device::pia_b_w)
{
if (data & 0x80)
{
// Reset state.
m_mpt_timer->enable(false);
return;
}
data &= 0x0f;
if (data == 0x0c || data == 0x0d || data == 0x0f)
{
// No output for these input settings.
m_mpt_timer->enable(false);
return;
}
if (data == 0x00)
{
// Hack: could not keep up with this 1us period
// anyway, and this is the initial state and it blocks
// progress, so just give up on this setting.
m_mpt_timer->enable(false);
return;
}
attotime duration;
// Set the duration for half the period, the time that the next
// transition of state will occur.
switch (data & 0x0f)
{
case 0: duration = attotime::from_nsec(500); break;
case 1: duration = attotime::from_usec(5); break;
case 2: duration = attotime::from_usec(50); break;
case 3: duration = attotime::from_usec(500); break;
case 4: duration = attotime::from_msec(5); break;
case 5: duration = attotime::from_msec(50); break;
case 6: duration = attotime::from_msec(500); break;
case 7: duration = attotime::from_seconds(5); break;
case 8: duration = attotime::from_seconds(50); break;
case 9: duration = attotime::from_seconds(30); break;
case 10: duration = attotime::from_seconds(30 * 60); break;
case 11: duration = attotime::from_seconds(5 * 60); break;
case 14: duration = attotime::from_msec(10); break;
}
if (duration != m_mpt_duration)
{
// TODO when would a change be latched?
m_mpt_timer->adjust(duration);
m_mpt_duration = duration;
}
m_mpt_timer->enable(true);
}
READ8_MEMBER(ss50_mpt_device::pia_cb1_r)
{
return m_mpt_timer_state;
}
TIMER_CALLBACK_MEMBER(ss50_mpt_device::mpt_timer_callback)
{
m_mpt_timer_state = !m_mpt_timer_state;
m_pia->cb1_w(m_mpt_timer_state);
m_mpt_timer->adjust(m_mpt_duration);
m_mpt_timer->enable(true);
}
WRITE_LINE_MEMBER(ss50_mpt_device::pia_irqa_w)
{
if (m_irqa_jumper->read())
write_irq(state);
}
WRITE_LINE_MEMBER(ss50_mpt_device::pia_irqb_w)
{
if (m_irqb_jumper->read())
write_irq(state);
}
// device type definition
DEFINE_DEVICE_TYPE_PRIVATE(SS50_MPT, ss50_card_interface, ss50_mpt_device, "ss50_mpt", "MP-T Timer / Counter")

View File

@ -0,0 +1,15 @@
// license:BSD-3-Clause
// copyright-holders:68bit
/**********************************************************************
SWTPC MP-T Timer / counter
**********************************************************************/
#ifndef MAME_DEVICE_BUS_SS50_MPT_H
#define MAME_DEVICE_BUS_SS50_MPT_H
#include "interface.h"
DECLARE_DEVICE_TYPE(SS50_MPT, ss50_card_interface)
#endif // MAME_DEVICE_BUS_SS50_MPT_H