mirror of
https://github.com/holub/mame
synced 2025-05-25 23:35:26 +03:00
Updated the 74123 device to no longer be legacy. [Harmony]
This commit is contained in:
parent
3c0ef980fb
commit
86342429fd
@ -14,228 +14,287 @@
|
||||
#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)
|
||||
{
|
||||
double duration;
|
||||
|
||||
switch (chip->intf->connection_type)
|
||||
{
|
||||
case TTL74123_NOT_GROUNDED_NO_DIODE:
|
||||
duration = 0.28 * chip->intf->res * chip->intf->cap * (1.0 + (700.0 / chip->intf->res));
|
||||
break;
|
||||
|
||||
case TTL74123_NOT_GROUNDED_DIODE:
|
||||
duration = 0.25 * chip->intf->res * chip->intf->cap * (1.0 + (700.0 / chip->intf->res));
|
||||
break;
|
||||
|
||||
case TTL74123_GROUNDED:
|
||||
default:
|
||||
if (chip->intf->cap < CAP_U(0.1))
|
||||
/* this is really a curve - a very flat one in the 0.1uF-.01uF range */
|
||||
duration = 0.32 * chip->intf->res * chip->intf->cap;
|
||||
else
|
||||
duration = 0.33 * chip->intf->res * chip->intf->cap;
|
||||
break;
|
||||
}
|
||||
|
||||
return double_to_attotime(duration);
|
||||
return global_alloc(ttl74123_device_config(mconfig, tag, owner, clock));
|
||||
}
|
||||
|
||||
|
||||
static int timer_running(ttl74123_t *chip)
|
||||
//-------------------------------------------------
|
||||
// alloc_device - allocate a new device object
|
||||
//-------------------------------------------------
|
||||
|
||||
device_t *ttl74123_device_config::alloc_device(running_machine &machine) const
|
||||
{
|
||||
return (attotime_compare(timer_timeleft(chip->timer), attotime_zero) > 0) &&
|
||||
(attotime_compare(timer_timeleft(chip->timer), attotime_never) != 0);
|
||||
return auto_alloc(&machine, ttl74123_device(machine, *this));
|
||||
}
|
||||
|
||||
|
||||
static TIMER_CALLBACK( output_callback )
|
||||
//-------------------------------------------------
|
||||
// device_config_complete - perform any
|
||||
// operations now that the configuration is
|
||||
// complete
|
||||
//-------------------------------------------------
|
||||
|
||||
void ttl74123_device_config::device_config_complete()
|
||||
{
|
||||
running_device *device = (running_device *)ptr;
|
||||
ttl74123_t *chip = get_safe_token(device);
|
||||
|
||||
chip->intf->output_changed_cb(device, 0, param);
|
||||
}
|
||||
|
||||
|
||||
static void set_output(running_device *device)
|
||||
{
|
||||
ttl74123_t *chip = get_safe_token(device);
|
||||
int output = timer_running(chip);
|
||||
|
||||
timer_set( device->machine, attotime_zero, (void *) device, output, output_callback );
|
||||
|
||||
if (LOG) logerror("74123 %s: Output: %d\n", device->tag(), output);
|
||||
}
|
||||
|
||||
|
||||
static TIMER_CALLBACK( clear_callback )
|
||||
{
|
||||
running_device *device = (running_device *)ptr;
|
||||
ttl74123_t *chip = get_safe_token(device);
|
||||
int output = timer_running(chip);
|
||||
|
||||
chip->intf->output_changed_cb(device, 0, output);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
static void start_pulse(running_device *device)
|
||||
//-------------------------------------------------
|
||||
// ttl74123_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
ttl74123_device::ttl74123_device(running_machine &_machine, const ttl74123_device_config &config)
|
||||
: device_t(_machine, config),
|
||||
m_config(config)
|
||||
{
|
||||
ttl74123_t *chip = get_safe_token(device);
|
||||
|
||||
attotime duration = compute_duration(chip);
|
||||
}
|
||||
|
||||
if (timer_running(chip))
|
||||
{
|
||||
/* retriggering, but not if we are called to quickly */
|
||||
attotime delay_time = attotime_make(0, ATTOSECONDS_PER_SECOND * chip->intf->cap * 220);
|
||||
|
||||
if (attotime_compare(timer_timeelapsed(chip->timer), delay_time) >= 0)
|
||||
{
|
||||
timer_adjust_oneshot(chip->timer, duration, 0);
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
if (LOG) logerror("74123 %s: Retriggering pulse. Duration: %f\n", device->tag(), attotime_to_double(duration));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LOG) logerror("74123 %s: Retriggering failed.\n", device->tag());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* starting */
|
||||
timer_adjust_oneshot(chip->timer, duration, 0);
|
||||
void ttl74123_device::device_start()
|
||||
{
|
||||
m_timer = timer_alloc(&m_machine, clear_callback, (void *)this);
|
||||
|
||||
set_output(device);
|
||||
/* start with the defaults */
|
||||
m_a = m_config.m_a;
|
||||
m_b = m_config.m_b;
|
||||
m_clear = m_config.m_clear;
|
||||
|
||||
if (LOG) logerror("74123 %s: Starting pulse. Duration: %f\n", device->tag(), attotime_to_double(duration));
|
||||
}
|
||||
/* 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;
|
||||
|
||||
switch (m_config.m_connection_type)
|
||||
{
|
||||
case TTL74123_NOT_GROUNDED_NO_DIODE:
|
||||
duration = 0.28 * m_config.m_res * m_config.m_cap * (1.0 + (700.0 / m_config.m_res));
|
||||
break;
|
||||
|
||||
case TTL74123_NOT_GROUNDED_DIODE:
|
||||
duration = 0.25 * m_config.m_res * m_config.m_cap * (1.0 + (700.0 / m_config.m_res));
|
||||
break;
|
||||
|
||||
case TTL74123_GROUNDED:
|
||||
default:
|
||||
if (m_config.m_cap < CAP_U(0.1))
|
||||
{
|
||||
/* this is really a curve - a very flat one in the 0.1uF-.01uF range */
|
||||
duration = 0.32 * m_config.m_res * m_config.m_cap;
|
||||
}
|
||||
else
|
||||
{
|
||||
duration = 0.33 * m_config.m_res * m_config.m_cap;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return double_to_attotime(duration);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
timer_running
|
||||
-------------------------------------------------*/
|
||||
|
||||
int ttl74123_device::timer_running()
|
||||
{
|
||||
return (attotime_compare(timer_timeleft(m_timer), attotime_zero) > 0) &&
|
||||
(attotime_compare(timer_timeleft(m_timer), attotime_never) != 0);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
TIMER_CALLBACK( output_callback )
|
||||
-------------------------------------------------*/
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
void ttl74123_device::set_output()
|
||||
{
|
||||
int output = timer_running();
|
||||
|
||||
timer_set( &m_machine, attotime_zero, (void *)this, output, output_callback );
|
||||
|
||||
if (LOG) logerror("74123 %s: Output: %d\n", tag(), output);
|
||||
}
|
||||
|
||||
|
||||
TIMER_CALLBACK( ttl74123_device::clear_callback )
|
||||
{
|
||||
ttl74123_device *dev = reinterpret_cast<ttl74123_device*>(ptr);
|
||||
dev->clear();
|
||||
}
|
||||
|
||||
void ttl74123_device::clear()
|
||||
{
|
||||
int output = timer_running();
|
||||
|
||||
m_config.m_output_changed_cb(this, 0, output);
|
||||
}
|
||||
|
||||
|
||||
void ttl74123_device::start_pulse()
|
||||
{
|
||||
attotime duration = compute_duration();
|
||||
|
||||
if(timer_running())
|
||||
{
|
||||
/* retriggering, but not if we are called to quickly */
|
||||
attotime delay_time = attotime_make(0, ATTOSECONDS_PER_SECOND * m_config.m_cap * 220);
|
||||
|
||||
if(attotime_compare(timer_timeelapsed(m_timer), delay_time) >= 0)
|
||||
{
|
||||
timer_adjust_oneshot(m_timer, duration, 0);
|
||||
|
||||
if (LOG) logerror("74123 %s: Retriggering pulse. Duration: %f\n", tag(), attotime_to_double(duration));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LOG) logerror("74123 %s: Retriggering failed.\n", tag());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* starting */
|
||||
timer_adjust_oneshot(m_timer, duration, 0);
|
||||
|
||||
set_output();
|
||||
|
||||
if (LOG) logerror("74123 %s: Starting pulse. Duration: %f\n", tag(), attotime_to_double(duration));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* start/regtrigger pulse if B=HI and falling edge on A (while clear is HI) */
|
||||
if (!data && chip->a && chip->b && chip->clear)
|
||||
start_pulse(device);
|
||||
void ttl74123_device::a_w(UINT8 data)
|
||||
{
|
||||
/* start/regtrigger pulse if B=HI and falling edge on A (while clear is HI) */
|
||||
if (!data && m_a && m_b && m_clear)
|
||||
{
|
||||
start_pulse();
|
||||
}
|
||||
|
||||
chip->a = data;
|
||||
m_a = data;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* start/regtrigger pulse if A=LO and rising edge on B (while clear is HI) */
|
||||
if (data && !chip->b && !chip->a && chip->clear)
|
||||
start_pulse(device);
|
||||
void ttl74123_device::b_w(UINT8 data)
|
||||
{
|
||||
/* start/regtrigger pulse if A=LO and rising edge on B (while clear is HI) */
|
||||
if (data && !m_b && !m_a && m_clear)
|
||||
{
|
||||
start_pulse();
|
||||
}
|
||||
|
||||
chip->b = data;
|
||||
m_b = data;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* start/regtrigger pulse if B=HI and A=LO and rising edge on clear */
|
||||
if (data && !chip->a && chip->b && !chip->clear)
|
||||
start_pulse(device);
|
||||
else if (!data) /* clear the output */
|
||||
{
|
||||
timer_adjust_oneshot(chip->timer, attotime_zero, 0);
|
||||
void ttl74123_device::clear_w(UINT8 data)
|
||||
{
|
||||
/* start/regtrigger pulse if B=HI and A=LO and rising edge on clear */
|
||||
if (data && !m_a && m_b && !m_clear)
|
||||
{
|
||||
start_pulse();
|
||||
}
|
||||
else if (!data) /* clear the output */
|
||||
{
|
||||
timer_adjust_oneshot(m_timer, attotime_zero, 0);
|
||||
|
||||
if (LOG) logerror("74123 #%s: Cleared\n", device->tag() );
|
||||
}
|
||||
chip->clear = data;
|
||||
if (LOG) logerror("74123 #%s: Cleared\n", tag() );
|
||||
}
|
||||
m_clear = data;
|
||||
}
|
||||
|
||||
WRITE8_DEVICE_HANDLER( ttl74123_reset_w )
|
||||
{
|
||||
set_output(device);
|
||||
ttl74123_device *dev = reinterpret_cast<ttl74123_device *>(device);
|
||||
dev->reset_w();
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/* device interface */
|
||||
|
||||
static DEVICE_START( ttl74123 )
|
||||
void ttl74123_device::reset_w()
|
||||
{
|
||||
ttl74123_t *chip = get_safe_token(device);
|
||||
|
||||
/* 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);
|
||||
set_output();
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
const device_type TTL74123 = ttl74123_device_config::static_alloc_device_config;
|
||||
|
@ -43,18 +43,23 @@
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef TTL74123_H
|
||||
#define TTL74123_H
|
||||
#pragma once
|
||||
|
||||
#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) \
|
||||
MDRV_DEVICE_ADD(_tag, TTL74123, 0) \
|
||||
MDRV_DEVICE_CONFIG(_config)
|
||||
|
||||
|
||||
/* constants for the different ways the cap/res can be connected.
|
||||
This determines the formula for calculating the pulse width */
|
||||
#define TTL74123_NOT_GROUNDED_NO_DIODE (1)
|
||||
@ -62,26 +67,104 @@ DECLARE_LEGACY_DEVICE(TTL74123, ttl74123);
|
||||
#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 */
|
||||
double res; /* resistor connected to RCext */
|
||||
double cap; /* capacitor connected to Cext and RCext */
|
||||
int a; /* initial/constant value of the A pin */
|
||||
int b; /* initial/constant value of the B pin */
|
||||
int clear; /* initial/constant value of the Clear pin */
|
||||
write8_device_func output_changed_cb;
|
||||
int m_connection_type; /* the hook up type - one of the constants above */
|
||||
double m_res; /* resistor connected to RCext */
|
||||
double m_cap; /* capacitor connected to Cext and RCext */
|
||||
int m_a; /* initial/constant value of the A pin */
|
||||
int m_b; /* initial/constant value of the B pin */
|
||||
int m_clear; /* initial/constant value of the Clear pin */
|
||||
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_b_w );
|
||||
WRITE8_DEVICE_HANDLER( ttl74123_clear_w );
|
||||
|
||||
/* reset the latch */
|
||||
|
||||
WRITE8_DEVICE_HANDLER( ttl74123_reset_w );
|
||||
WRITE8_DEVICE_HANDLER( ttl74123_reset_w ); /* reset the latch */
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user