tms1024/tbreakup update

This commit is contained in:
hap 2015-05-29 21:29:16 +02:00
parent abadd747f0
commit f9eb5e92b8
3 changed files with 248 additions and 39 deletions

View File

@ -1,36 +1,75 @@
// license:BSD-3-Clause // license:BSD-3-Clause
// copyright-holders:hap // copyright-holders:hap
/********************************************************************** /*
Texas Instruments TMS1024, TMS1025 I/O expander emulation Texas Instruments TMS1024/TMS1025 I/O expander
**********************************************************************/ No documentation was available, just a pinout.
Other than more port pins, TMS1025 is assumed to be same as TMS1024.
TODO:
- writes to port 0
- what's the MS pin?
- strobe is on rising edge? or falling edge?
*/
#include "machine/tms1024.h" #include "machine/tms1024.h"
const device_type TMS1024 = &device_creator<tms1024_device>; const device_type TMS1024 = &device_creator<tms1024_device>;
const device_type TMS1025 = &device_creator<tms1025_device>;
//------------------------------------------------- //-------------------------------------------------
// tms1024_device - constructor // constructor
//------------------------------------------------- //-------------------------------------------------
tms1024_device::tms1024_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) tms1024_device::tms1024_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, TMS1024, "TMS1024", tag, owner, clock, "tms1024", __FILE__) : device_t(mconfig, TMS1024, "TMS1024 I/O Expander", tag, owner, clock, "tms1024", __FILE__),
m_write_port1(*this), m_write_port2(*this), m_write_port3(*this), m_write_port4(*this), m_write_port5(*this), m_write_port6(*this), m_write_port7(*this)
{ {
} }
tms1024_device::tms1024_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
m_write_port1(*this), m_write_port2(*this), m_write_port3(*this), m_write_port4(*this), m_write_port5(*this), m_write_port6(*this), m_write_port7(*this)
{
}
tms1025_device::tms1025_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: tms1024_device(mconfig, TMS1025, "TMS1025 I/O Expander", tag, owner, clock, "tms1025", __FILE__)
{
}
//------------------------------------------------- //-------------------------------------------------
// device_start - device-specific startup // device_start - device-specific startup
//------------------------------------------------- //-------------------------------------------------
void tms1024_device::device_start() void tms1024_device::device_start()
{ {
// resolve callbacks // resolve callbacks (there is no port 0)
m_write_port1.resolve_safe(); m_write_port[0] = &m_write_port1;
m_write_port2.resolve_safe(); m_write_port[1] = &m_write_port2;
m_write_port3.resolve_safe(); m_write_port[2] = &m_write_port3;
m_write_port4.resolve_safe(); m_write_port[3] = &m_write_port4;
m_write_port5.resolve_safe(); m_write_port[4] = &m_write_port5;
m_write_port6.resolve_safe(); m_write_port[5] = &m_write_port6;
m_write_port7.resolve_safe(); m_write_port[6] = &m_write_port7;
// zerofill
m_h = 0;
m_s = 0;
m_std = 0;
// register for savestates // register for savestates
save_item(NAME(m_h));
save_item(NAME(m_s));
save_item(NAME(m_std));
} }
//------------------------------------------------- //-------------------------------------------------
// device_reset - device-specific reset // device_reset - device-specific reset
//------------------------------------------------- //-------------------------------------------------
@ -40,4 +79,33 @@ void tms1024_device::device_reset()
} }
//-------------------------------------------------
// handlers // handlers
//-------------------------------------------------
WRITE8_MEMBER(tms1024_device::write_h)
{
// H1,2,3,4: data for outputs A,B,C,D
m_h = data & 0xf;
}
WRITE8_MEMBER(tms1024_device::write_s)
{
// S0,1,2: select port
m_s = data & 7;
}
WRITE_LINE_MEMBER(tms1024_device::write_std)
{
state = (state) ? 1 : 0;
// output on rising edge
if (state && !m_std)
{
if (m_s != 0)
(*m_write_port[m_s-1])((offs_t)(m_s-1), m_h);
}
m_std = state;
}

View File

@ -1,10 +1,39 @@
// license:BSD-3-Clause // license:BSD-3-Clause
// copyright-holders:hap // copyright-holders:hap
/********************************************************************** /*
Texas Instruments TMS1024, TMS1025 I/O expander emulation Texas Instruments TMS1024/TMS1025 I/O expander
********************************************************************** */
#ifndef _TMS1024_H_
#define _TMS1024_H_
#include "emu.h"
// ports setup
// 4-bit ports (3210 = DCBA)
// valid ports: 4-7 for TMS1024, 1-7 for TMS1025
#define MCFG_TMS1024_WRITE_PORT_CB(X, _devcb) \
tms1024_device::set_write_port##X##_callback(*device, DEVCB_##_devcb);
enum
{
TMS1024_PORT1 = 0,
TMS1024_PORT2,
TMS1024_PORT3,
TMS1024_PORT4,
TMS1024_PORT5,
TMS1024_PORT6,
TMS1024_PORT7
};
// pinout reference
/*
____ ____ ____ ____ ____ ____ ____ ____
Vss 1 |* \_/ | 28 H2 Vss 1 |* \_/ | 40 H2 Vss 1 |* \_/ | 28 H2 Vss 1 |* \_/ | 40 H2
@ -23,48 +52,59 @@
D5 14 |___________| 15 A6 D4 14 | | 27 A7 D5 14 |___________| 15 A6 D4 14 | | 27 A7
A5 15 | | 26 D6 A5 15 | | 26 D6
B5 16 | | 25 C6 B5 16 | | 25 C6
C5 17 | | 24 B6 CE: Chip Enable C5 17 | | 24 B6
D5 18 | | 23 A6 MS: Master S.? D5 18 | | 23 A6
A2 19 | | 22 D2 STD: STrobe Data? A2 19 | | 22 D2
B2 20 |___________| 21 C2 S: Select B2 20 |___________| 21 C2
H: Hold?
**********************************************************************/ */
#ifndef _TMS1024_H_
#define _TMS1024_H_
#include "emu.h"
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_TMS1024_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, TMS1024, 0)
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> tms1024_device
class tms1024_device : public device_t class tms1024_device : public device_t
{ {
public: public:
tms1024_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); tms1024_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
tms1024_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
// static configuration helpers // static configuration helpers
template<class _Object> static devcb_base &set_write_port1_callback(device_t &device, _Object object) { return downcast<tms1024_device &>(device).m_write_port1.set_callback(object); }
template<class _Object> static devcb_base &set_write_port2_callback(device_t &device, _Object object) { return downcast<tms1024_device &>(device).m_write_port2.set_callback(object); }
template<class _Object> static devcb_base &set_write_port3_callback(device_t &device, _Object object) { return downcast<tms1024_device &>(device).m_write_port3.set_callback(object); }
template<class _Object> static devcb_base &set_write_port4_callback(device_t &device, _Object object) { return downcast<tms1024_device &>(device).m_write_port4.set_callback(object); }
template<class _Object> static devcb_base &set_write_port5_callback(device_t &device, _Object object) { return downcast<tms1024_device &>(device).m_write_port5.set_callback(object); }
template<class _Object> static devcb_base &set_write_port6_callback(device_t &device, _Object object) { return downcast<tms1024_device &>(device).m_write_port6.set_callback(object); }
template<class _Object> static devcb_base &set_write_port7_callback(device_t &device, _Object object) { return downcast<tms1024_device &>(device).m_write_port7.set_callback(object); }
DECLARE_WRITE8_MEMBER(write_h);
DECLARE_WRITE8_MEMBER(write_s);
DECLARE_WRITE_LINE_MEMBER(write_std);
protected: protected:
// device-level overrides // device-level overrides
virtual void device_start(); virtual void device_start();
virtual void device_reset(); virtual void device_reset();
UINT8 m_h; // 4-bit data latch
UINT8 m_s; // 3-bit port select
UINT8 m_std; // strobe pin
// callbacks
devcb_write8 m_write_port1, m_write_port2, m_write_port3, m_write_port4, m_write_port5, m_write_port6, m_write_port7;
devcb_write8 *m_write_port[7];
}; };
// device type definition
class tms1025_device : public tms1024_device
{
public:
tms1025_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
extern const device_type TMS1024; extern const device_type TMS1024;
extern const device_type TMS1025;
#endif /* _TMS1024_H_ */ #endif /* _TMS1024_H_ */

View File

@ -118,6 +118,7 @@
#include "starwbc.lh" #include "starwbc.lh"
#include "stopthie.lh" #include "stopthie.lh"
#include "tandy12.lh" // clickable #include "tandy12.lh" // clickable
//#include "tbreakup.lh"
#include "tc4.lh" #include "tc4.lh"
#include "einvader.lh" // test-layout(but still playable) #include "einvader.lh" // test-layout(but still playable)
@ -3992,7 +3993,8 @@ MACHINE_CONFIG_END
/*************************************************************************** /***************************************************************************
Tomy(tronics) Break Up Tomy(tronics) Break Up (manufactured in Japan)
* PCB label TOMY B.O.
* TMS1040 MP2726 TOMY WIPE (die labeled MP2726A) * TMS1040 MP2726 TOMY WIPE (die labeled MP2726A)
* TMS1025N2LL I/O expander * TMS1025N2LL I/O expander
* 2-digit 7seg display, 46 other leds, 1bit sound * 2-digit 7seg display, 46 other leds, 1bit sound
@ -4002,15 +4004,40 @@ MACHINE_CONFIG_END
- Japan: Block Attack - Japan: Block Attack
- UK: Break-In - UK: Break-In
lamp translation table: led zz from game PCB = MESS lampyx:
00 = - 10 = lamp25 20 = lamp44
01 = lamp27 11 = lamp35 21 = lamp53
02 = lamp37 12 = lamp45 22 = lamp42
03 = lamp47 13 = lamp55
04 = lamp57 14 = lamp54
05 = lamp26 15 = lamp33
06 = lamp36 16 = lamp43
07 = lamp46 17 = lamp23
08 = lamp56 18 = lamp34
09 = lamp24 19 = lamp32
the 7seg panel is lamp0x and lamp1x(aka digit0/1), and the
8(2*4) * 3 rectangular leds panel, where x=0,1,2,3:
lamp7x lamp6x
lamp9x lamp8x
lamp11x lamp10x
***************************************************************************/ ***************************************************************************/
class tbreakup_state : public hh_tms1k_state class tbreakup_state : public hh_tms1k_state
{ {
public: public:
tbreakup_state(const machine_config &mconfig, device_type type, const char *tag) tbreakup_state(const machine_config &mconfig, device_type type, const char *tag)
: hh_tms1k_state(mconfig, type, tag) : hh_tms1k_state(mconfig, type, tag),
m_expander(*this, "expander")
{ } { }
required_device<tms1024_device> m_expander;
UINT8 m_exp_port[7];
DECLARE_WRITE8_MEMBER(expander_w);
void prepare_display(); void prepare_display();
DECLARE_WRITE16_MEMBER(write_r); DECLARE_WRITE16_MEMBER(write_r);
DECLARE_WRITE16_MEMBER(write_o); DECLARE_WRITE16_MEMBER(write_o);
@ -4021,33 +4048,89 @@ public:
protected: protected:
virtual void machine_reset(); virtual void machine_reset();
virtual void machine_start();
}; };
// handlers // handlers
void tbreakup_state::prepare_display() void tbreakup_state::prepare_display()
{ {
// 7seg leds from R0,R1 and O0-O6
for (int y = 0; y < 2; y++)
{
m_display_segmask[y] = 0x7f;
m_display_state[y] = (m_r >> y & 1) ? (m_o & 0x7f) : 0;
}
// 22 round leds from expander port 7 and O2-O7
for (int y = 0; y < 4; y++)
m_display_state[y+2] = (m_exp_port[6] >> y & 1) ? (m_o & 0xfc) : 0;
// 24 rectangular leds from expander ports 1-6 (not strobed)
for (int y = 0; y < 6; y++)
m_display_state[y+6] = m_exp_port[y];
set_display_size(8, 12);
display_update();
}
WRITE8_MEMBER(tbreakup_state::expander_w)
{
// TMS1025 port 1-7 data
m_exp_port[offset] = data;
prepare_display();
} }
WRITE16_MEMBER(tbreakup_state::write_r) WRITE16_MEMBER(tbreakup_state::write_r)
{ {
// R6: speaker out
m_speaker->level_w(data >> 6 & 1);
// R7,R8: input mux
m_inp_mux = data >> 7 & 3;
// R3-R5: TMS1025 port S
// R2: TMS1025 STD pin
m_expander->write_s(space, 0, data >> 3 & 7);
m_expander->write_std(data >> 2 & 1);
// R0,R1: select digit
m_r = ~data;
prepare_display(); prepare_display();
} }
WRITE16_MEMBER(tbreakup_state::write_o) WRITE16_MEMBER(tbreakup_state::write_o)
{ {
// O0-O3: TMS1025 port H
m_expander->write_h(space, 0, data & 0xf);
// O0-O7: led state
m_o = data;
prepare_display(); prepare_display();
} }
READ8_MEMBER(tbreakup_state::read_k) READ8_MEMBER(tbreakup_state::read_k)
{ {
return 0; // K4: fixed input
// K8: multiplexed inputs
return (m_inp_matrix[2]->read() & 4) | (read_inputs(2) & 8);
} }
// config // config
static INPUT_PORTS_START( tbreakup ) static INPUT_PORTS_START( tbreakup )
PORT_START("IN.0") // R7 K8
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Ball")
PORT_START("IN.1") // R8 K8
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Hit")
PORT_START("IN.2") // K4
PORT_CONFNAME( 0x04, 0x00, DEF_STR( Lives ) )
PORT_CONFSETTING( 0x00, "3" )
PORT_CONFSETTING( 0x04, "5" )
PORT_START("IN.3") // fake PORT_START("IN.3") // fake
PORT_CONFNAME( 0x01, 0x00, "Skill Level" ) PORT_CHANGED_MEMBER(DEVICE_SELF, tbreakup_state, skill_switch, NULL) PORT_CONFNAME( 0x01, 0x00, "Skill Level" ) PORT_CHANGED_MEMBER(DEVICE_SELF, tbreakup_state, skill_switch, NULL)
PORT_CONFSETTING( 0x00, "Pro 1" ) PORT_CONFSETTING( 0x00, "Pro 1" )
@ -4072,6 +4155,15 @@ void tbreakup_state::machine_reset()
set_clock(); set_clock();
} }
void tbreakup_state::machine_start()
{
hh_tms1k_state::machine_start();
// zerofill/register for savestates
memset(m_exp_port, 0, sizeof(m_exp_port));
save_item(NAME(m_exp_port));
}
static MACHINE_CONFIG_START( tbreakup, tbreakup_state ) static MACHINE_CONFIG_START( tbreakup, tbreakup_state )
/* basic machine hardware */ /* basic machine hardware */
@ -4080,6 +4172,15 @@ static MACHINE_CONFIG_START( tbreakup, tbreakup_state )
MCFG_TMS1XXX_WRITE_R_CB(WRITE16(tbreakup_state, write_r)) MCFG_TMS1XXX_WRITE_R_CB(WRITE16(tbreakup_state, write_r))
MCFG_TMS1XXX_WRITE_O_CB(WRITE16(tbreakup_state, write_o)) MCFG_TMS1XXX_WRITE_O_CB(WRITE16(tbreakup_state, write_o))
MCFG_DEVICE_ADD("expander", TMS1025, 0)
MCFG_TMS1024_WRITE_PORT_CB(1, WRITE8(tbreakup_state, expander_w))
MCFG_TMS1024_WRITE_PORT_CB(2, WRITE8(tbreakup_state, expander_w))
MCFG_TMS1024_WRITE_PORT_CB(3, WRITE8(tbreakup_state, expander_w))
MCFG_TMS1024_WRITE_PORT_CB(4, WRITE8(tbreakup_state, expander_w))
MCFG_TMS1024_WRITE_PORT_CB(5, WRITE8(tbreakup_state, expander_w))
MCFG_TMS1024_WRITE_PORT_CB(6, WRITE8(tbreakup_state, expander_w))
MCFG_TMS1024_WRITE_PORT_CB(7, WRITE8(tbreakup_state, expander_w))
MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1))
// MCFG_DEFAULT_LAYOUT(layout_tbreakup) // MCFG_DEFAULT_LAYOUT(layout_tbreakup)
MCFG_DEFAULT_LAYOUT(layout_hh_tms1k_test) MCFG_DEFAULT_LAYOUT(layout_hh_tms1k_test)