Updated the 74123 device to no longer be legacy. [Harmony]

This commit is contained in:
Ryan Holtz 2010-08-23 05:42:12 +00:00
parent 3c0ef980fb
commit 86342429fd
2 changed files with 329 additions and 187 deletions

View File

@ -14,48 +14,130 @@
#define LOG (0) #define LOG (0)
typedef struct _ttl74123_t ttl74123_t; //**************************************************************************
// DEVICE CONFIGURATION
//**************************************************************************
struct _ttl74123_t //-------------------------------------------------
// ttl74123_device_config - constructor
//-------------------------------------------------
ttl74123_device_config::ttl74123_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
: device_config(mconfig, static_alloc_device_config, "TTL74123", tag, owner, clock)
{ {
const ttl74123_config *intf;
UINT8 a; /* pin 1/9 */
UINT8 b; /* pin 2/10 */
UINT8 clear; /* pin 3/11 */
emu_timer *timer;
};
/* ----------------------------------------------------------------------- */
INLINE ttl74123_t *get_safe_token(running_device *device) {
assert( device != NULL );
assert( device->type() == TTL74123 );
return ( ttl74123_t * ) downcast<legacy_device_base *>(device)->token();
} }
static attotime compute_duration(ttl74123_t *chip) //-------------------------------------------------
// static_alloc_device_config - allocate a new
// configuration object
//-------------------------------------------------
device_config *ttl74123_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
{
return global_alloc(ttl74123_device_config(mconfig, tag, owner, clock));
}
//-------------------------------------------------
// alloc_device - allocate a new device object
//-------------------------------------------------
device_t *ttl74123_device_config::alloc_device(running_machine &machine) const
{
return auto_alloc(&machine, ttl74123_device(machine, *this));
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void ttl74123_device_config::device_config_complete()
{
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// ttl74123_device - constructor
//-------------------------------------------------
ttl74123_device::ttl74123_device(running_machine &_machine, const ttl74123_device_config &config)
: device_t(_machine, config),
m_config(config)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void ttl74123_device::device_start()
{
m_timer = timer_alloc(&m_machine, clear_callback, (void *)this);
/* start with the defaults */
m_a = m_config.m_a;
m_b = m_config.m_b;
m_clear = m_config.m_clear;
/* register for state saving */
state_save_register_device_item(this, 0, m_a);
state_save_register_device_item(this, 0, m_b);
state_save_register_device_item(this, 0, m_clear);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void ttl74123_device::device_reset()
{
set_output();
}
/*-------------------------------------------------
compute_duration
-------------------------------------------------*/
attotime ttl74123_device::compute_duration()
{ {
double duration; double duration;
switch (chip->intf->connection_type) switch (m_config.m_connection_type)
{ {
case TTL74123_NOT_GROUNDED_NO_DIODE: case TTL74123_NOT_GROUNDED_NO_DIODE:
duration = 0.28 * chip->intf->res * chip->intf->cap * (1.0 + (700.0 / chip->intf->res)); duration = 0.28 * m_config.m_res * m_config.m_cap * (1.0 + (700.0 / m_config.m_res));
break; break;
case TTL74123_NOT_GROUNDED_DIODE: case TTL74123_NOT_GROUNDED_DIODE:
duration = 0.25 * chip->intf->res * chip->intf->cap * (1.0 + (700.0 / chip->intf->res)); duration = 0.25 * m_config.m_res * m_config.m_cap * (1.0 + (700.0 / m_config.m_res));
break; break;
case TTL74123_GROUNDED: case TTL74123_GROUNDED:
default: default:
if (chip->intf->cap < CAP_U(0.1)) if (m_config.m_cap < CAP_U(0.1))
{
/* this is really a curve - a very flat one in the 0.1uF-.01uF range */ /* this is really a curve - a very flat one in the 0.1uF-.01uF range */
duration = 0.32 * chip->intf->res * chip->intf->cap; duration = 0.32 * m_config.m_res * m_config.m_cap;
}
else else
duration = 0.33 * chip->intf->res * chip->intf->cap; {
duration = 0.33 * m_config.m_res * m_config.m_cap;
}
break; break;
} }
@ -63,179 +145,156 @@ static attotime compute_duration(ttl74123_t *chip)
} }
static int timer_running(ttl74123_t *chip) /*-------------------------------------------------
timer_running
-------------------------------------------------*/
int ttl74123_device::timer_running()
{ {
return (attotime_compare(timer_timeleft(chip->timer), attotime_zero) > 0) && return (attotime_compare(timer_timeleft(m_timer), attotime_zero) > 0) &&
(attotime_compare(timer_timeleft(chip->timer), attotime_never) != 0); (attotime_compare(timer_timeleft(m_timer), attotime_never) != 0);
} }
static TIMER_CALLBACK( output_callback ) /*-------------------------------------------------
{ TIMER_CALLBACK( output_callback )
running_device *device = (running_device *)ptr; -------------------------------------------------*/
ttl74123_t *chip = get_safe_token(device);
chip->intf->output_changed_cb(device, 0, param); TIMER_CALLBACK( ttl74123_device::output_callback )
{
ttl74123_device *dev = reinterpret_cast<ttl74123_device*>(ptr);
dev->output(param);
}
void ttl74123_device::output(INT32 param)
{
m_config.m_output_changed_cb(this, 0, param);
} }
static void set_output(running_device *device) void ttl74123_device::set_output()
{ {
ttl74123_t *chip = get_safe_token(device); int output = timer_running();
int output = timer_running(chip);
timer_set( device->machine, attotime_zero, (void *) device, output, output_callback ); timer_set( &m_machine, attotime_zero, (void *)this, output, output_callback );
if (LOG) logerror("74123 %s: Output: %d\n", device->tag(), output); if (LOG) logerror("74123 %s: Output: %d\n", tag(), output);
} }
static TIMER_CALLBACK( clear_callback ) TIMER_CALLBACK( ttl74123_device::clear_callback )
{ {
running_device *device = (running_device *)ptr; ttl74123_device *dev = reinterpret_cast<ttl74123_device*>(ptr);
ttl74123_t *chip = get_safe_token(device); dev->clear();
int output = timer_running(chip); }
chip->intf->output_changed_cb(device, 0, output); void ttl74123_device::clear()
{
int output = timer_running();
m_config.m_output_changed_cb(this, 0, output);
} }
void ttl74123_device::start_pulse()
static void start_pulse(running_device *device)
{ {
ttl74123_t *chip = get_safe_token(device); attotime duration = compute_duration();
attotime duration = compute_duration(chip); if(timer_running())
if (timer_running(chip))
{ {
/* retriggering, but not if we are called to quickly */ /* retriggering, but not if we are called to quickly */
attotime delay_time = attotime_make(0, ATTOSECONDS_PER_SECOND * chip->intf->cap * 220); attotime delay_time = attotime_make(0, ATTOSECONDS_PER_SECOND * m_config.m_cap * 220);
if (attotime_compare(timer_timeelapsed(chip->timer), delay_time) >= 0) if(attotime_compare(timer_timeelapsed(m_timer), delay_time) >= 0)
{ {
timer_adjust_oneshot(chip->timer, duration, 0); timer_adjust_oneshot(m_timer, duration, 0);
if (LOG) logerror("74123 %s: Retriggering pulse. Duration: %f\n", device->tag(), attotime_to_double(duration)); if (LOG) logerror("74123 %s: Retriggering pulse. Duration: %f\n", tag(), attotime_to_double(duration));
} }
else else
{ {
if (LOG) logerror("74123 %s: Retriggering failed.\n", device->tag()); if (LOG) logerror("74123 %s: Retriggering failed.\n", tag());
} }
} }
else else
{ {
/* starting */ /* starting */
timer_adjust_oneshot(chip->timer, duration, 0); timer_adjust_oneshot(m_timer, duration, 0);
set_output(device); set_output();
if (LOG) logerror("74123 %s: Starting pulse. Duration: %f\n", device->tag(), attotime_to_double(duration)); if (LOG) logerror("74123 %s: Starting pulse. Duration: %f\n", tag(), attotime_to_double(duration));
} }
} }
WRITE8_DEVICE_HANDLER( ttl74123_a_w ) WRITE8_DEVICE_HANDLER( ttl74123_a_w )
{ {
ttl74123_t *chip = get_safe_token(device); ttl74123_device *dev = reinterpret_cast<ttl74123_device *>(device);
dev->a_w(data);
}
void ttl74123_device::a_w(UINT8 data)
{
/* start/regtrigger pulse if B=HI and falling edge on A (while clear is HI) */ /* start/regtrigger pulse if B=HI and falling edge on A (while clear is HI) */
if (!data && chip->a && chip->b && chip->clear) if (!data && m_a && m_b && m_clear)
start_pulse(device); {
start_pulse();
}
chip->a = data; m_a = data;
} }
WRITE8_DEVICE_HANDLER( ttl74123_b_w ) WRITE8_DEVICE_HANDLER( ttl74123_b_w )
{ {
ttl74123_t *chip = get_safe_token(device); ttl74123_device *dev = reinterpret_cast<ttl74123_device *>(device);
dev->b_w(data);
}
void ttl74123_device::b_w(UINT8 data)
{
/* start/regtrigger pulse if A=LO and rising edge on B (while clear is HI) */ /* start/regtrigger pulse if A=LO and rising edge on B (while clear is HI) */
if (data && !chip->b && !chip->a && chip->clear) if (data && !m_b && !m_a && m_clear)
start_pulse(device); {
start_pulse();
}
chip->b = data; m_b = data;
} }
WRITE8_DEVICE_HANDLER( ttl74123_clear_w ) WRITE8_DEVICE_HANDLER( ttl74123_clear_w )
{ {
ttl74123_t *chip = get_safe_token(device); ttl74123_device *dev = reinterpret_cast<ttl74123_device *>(device);
dev->clear_w(data);
}
void ttl74123_device::clear_w(UINT8 data)
{
/* start/regtrigger pulse if B=HI and A=LO and rising edge on clear */ /* start/regtrigger pulse if B=HI and A=LO and rising edge on clear */
if (data && !chip->a && chip->b && !chip->clear) if (data && !m_a && m_b && !m_clear)
start_pulse(device); {
start_pulse();
}
else if (!data) /* clear the output */ else if (!data) /* clear the output */
{ {
timer_adjust_oneshot(chip->timer, attotime_zero, 0); timer_adjust_oneshot(m_timer, attotime_zero, 0);
if (LOG) logerror("74123 #%s: Cleared\n", device->tag() ); if (LOG) logerror("74123 #%s: Cleared\n", tag() );
} }
chip->clear = data; m_clear = data;
} }
WRITE8_DEVICE_HANDLER( ttl74123_reset_w ) WRITE8_DEVICE_HANDLER( ttl74123_reset_w )
{ {
set_output(device); ttl74123_device *dev = reinterpret_cast<ttl74123_device *>(device);
dev->reset_w();
} }
/* ----------------------------------------------------------------------- */ void ttl74123_device::reset_w()
/* device interface */
static DEVICE_START( ttl74123 )
{ {
ttl74123_t *chip = get_safe_token(device); set_output();
/* validate arguments */
chip->intf = (ttl74123_config *)device->baseconfig().static_config();
assert_always(chip->intf, "No interface specified");
assert_always((chip->intf->connection_type != TTL74123_GROUNDED) || (chip->intf->cap >= CAP_U(0.01)), "Only capacitors >= 0.01uF supported for GROUNDED type");
assert_always(chip->intf->cap >= CAP_P(1000), "Only capacitors >= 1000pF supported ");
chip->timer = timer_alloc(device->machine, clear_callback, (void *) device);
/* start with the defaults */
chip->a = chip->intf->a;
chip->b = chip->intf->b;
chip->clear = chip->intf->clear;
/* register for state saving */
state_save_register_device_item(device, 0, chip->a);
state_save_register_device_item(device, 0, chip->b);
state_save_register_device_item(device, 0, chip->clear);
} }
const device_type TTL74123 = ttl74123_device_config::static_alloc_device_config;
static DEVICE_RESET( ttl74123 )
{
set_output(device);
}
DEVICE_GET_INFO( ttl74123 )
{
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(ttl74123_t); break;
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ttl74123); break;
case DEVINFO_FCT_STOP: /* Nothing */ break;
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(ttl74123); break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: strcpy(info->s, "74123"); break;
case DEVINFO_STR_FAMILY: strcpy(info->s, "TTL"); break;
case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
}
}
DEFINE_LEGACY_DEVICE(TTL74123, ttl74123);

View File

@ -43,18 +43,23 @@
*****************************************************************************/ *****************************************************************************/
#ifndef TTL74123_H #pragma once
#define TTL74123_H
#include "devlegcy.h" #ifndef __TTL74123_H__
#define __TTL74123_H__
DECLARE_LEGACY_DEVICE(TTL74123, ttl74123); #include "emu.h"
/***************************************************************************
DEVICE CONFIGURATION MACROS
***************************************************************************/
#define MDRV_TTL74123_ADD(_tag, _config) \ #define MDRV_TTL74123_ADD(_tag, _config) \
MDRV_DEVICE_ADD(_tag, TTL74123, 0) \ MDRV_DEVICE_ADD(_tag, TTL74123, 0) \
MDRV_DEVICE_CONFIG(_config) MDRV_DEVICE_CONFIG(_config)
/* constants for the different ways the cap/res can be connected. /* constants for the different ways the cap/res can be connected.
This determines the formula for calculating the pulse width */ This determines the formula for calculating the pulse width */
#define TTL74123_NOT_GROUNDED_NO_DIODE (1) #define TTL74123_NOT_GROUNDED_NO_DIODE (1)
@ -62,26 +67,104 @@ DECLARE_LEGACY_DEVICE(TTL74123, ttl74123);
#define TTL74123_GROUNDED (3) #define TTL74123_GROUNDED (3)
typedef struct _ttl74123_config ttl74123_config; /***************************************************************************
struct _ttl74123_config TYPE DEFINITIONS
***************************************************************************/
// ======================> ttl74123_interface
struct ttl74123_interface
{ {
int connection_type; /* the hook up type - one of the constants above */ int m_connection_type; /* the hook up type - one of the constants above */
double res; /* resistor connected to RCext */ double m_res; /* resistor connected to RCext */
double cap; /* capacitor connected to Cext and RCext */ double m_cap; /* capacitor connected to Cext and RCext */
int a; /* initial/constant value of the A pin */ int m_a; /* initial/constant value of the A pin */
int b; /* initial/constant value of the B pin */ int m_b; /* initial/constant value of the B pin */
int clear; /* initial/constant value of the Clear pin */ int m_clear; /* initial/constant value of the Clear pin */
write8_device_func output_changed_cb; write8_device_func m_output_changed_cb;
}; };
/* write inputs */
// ======================> ttl74123_device_config
class ttl74123_device_config : public device_config,
public ttl74123_interface
{
friend class ttl74123_device;
// construction/destruction
ttl74123_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
public:
// allocators
static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
virtual device_t *alloc_device(running_machine &machine) const;
protected:
// device_config overrides
virtual void device_config_complete();
};
// ======================> ttl74123_device
class ttl74123_device : public device_t
{
friend class ttl74123_device_config;
// construction/destruction
ttl74123_device(running_machine &_machine, const ttl74123_device_config &_config);
public:
void a_w(UINT8 data);
void b_w(UINT8 data);
void clear_w(UINT8 data);
void reset_w();
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
virtual void device_post_load() { }
virtual void device_clock_changed() { }
static TIMER_CALLBACK( output_callback );
static TIMER_CALLBACK( clear_callback );
private:
int timer_running();
void start_pulse();
void output(INT32 param);
void set_output();
attotime compute_duration();
void clear();
UINT8 m_a; /* pin 1/9 */
UINT8 m_b; /* pin 2/10 */
UINT8 m_clear; /* pin 3/11 */
emu_timer *m_timer;
const ttl74123_device_config &m_config;
};
// device type definition
extern const device_type TTL74123;
/***************************************************************************
PROTOTYPES
***************************************************************************/
WRITE8_DEVICE_HANDLER( ttl74123_a_w ); WRITE8_DEVICE_HANDLER( ttl74123_a_w );
WRITE8_DEVICE_HANDLER( ttl74123_b_w ); WRITE8_DEVICE_HANDLER( ttl74123_b_w );
WRITE8_DEVICE_HANDLER( ttl74123_clear_w ); WRITE8_DEVICE_HANDLER( ttl74123_clear_w );
WRITE8_DEVICE_HANDLER( ttl74123_reset_w ); /* reset the latch */
/* reset the latch */
WRITE8_DEVICE_HANDLER( ttl74123_reset_w );
#endif #endif