Converted discrete subsystem into "new-style" device. Still quite some work to do to remove legacy design, but working. No whatsnew.

This commit is contained in:
Couriersud 2011-01-05 02:16:29 +00:00
parent aceca7f753
commit bf5874a23b
3 changed files with 471 additions and 78 deletions

View File

@ -44,86 +44,26 @@ struct dss_input_context
sound_stream *buffer_stream; sound_stream *buffer_stream;
}; };
#if 0
INLINE discrete_info *get_safe_token(device_t *device) INLINE discrete_info *get_safe_token(device_t *device)
{ {
assert(device != NULL); assert(device != NULL);
assert(device->type() == DISCRETE); assert(device->type() == DISCRETE);
return (discrete_info *)downcast<legacy_device_base *>(device)->token(); return (discrete_info *)downcast<legacy_device_base *>(device)->token();
} }
#endif
READ8_DEVICE_HANDLER(discrete_sound_r) READ8_DEVICE_HANDLER(discrete_sound_r)
{ {
discrete_info *info = get_safe_token(device); discrete_device *disc_device = downcast<discrete_device *>(device);
node_description *node = discrete_find_node(info, offset); return disc_device->read( *disc_device->machine->firstcpu->space(), offset, 0xff);
UINT8 data = 0;
/* Read the node input value if allowed */
if (node)
{
/* Bring the system up to now */
stream_update(info->discrete_stream);
data = (UINT8) node->output[NODE_CHILD_NODE_NUM(offset)];
}
else
fatalerror("discrete_sound_r read from non-existent NODE_%02d\n", offset-NODE_00);
return data;
} }
WRITE8_DEVICE_HANDLER(discrete_sound_w) WRITE8_DEVICE_HANDLER(discrete_sound_w)
{ {
discrete_info *info = get_safe_token(device); discrete_device *disc_device = downcast<discrete_device *>(device);
node_description *node = discrete_find_node(info, offset); disc_device->write(*disc_device->machine->firstcpu->space(), offset, data, 0xff);
/* Update the node input value if it's a proper input node */
if (node)
{
struct dss_input_context *context = (struct dss_input_context *)node->context;
UINT8 new_data = 0;
switch (node->module->type)
{
case DSS_INPUT_DATA:
case DSS_INPUT_BUFFER:
new_data = data;
break;
case DSS_INPUT_LOGIC:
case DSS_INPUT_PULSE:
new_data = data ? 1 : 0;
break;
case DSS_INPUT_NOT:
new_data = data ? 0 : 1;
break;
}
if (context->data != new_data)
{
if (context->is_buffered)
{
/* Bring the system up to now */
stream_update(context->buffer_stream);
context->data = new_data;
}
else
{
/* Bring the system up to now */
stream_update(info->discrete_stream);
context->data = new_data;
/* Update the node output here so we don't have to do it each step */
node->output[0] = new_data * context->gain + context->offset;
}
}
}
else
{
discrete_log(info, "discrete_sound_w write to non-existent NODE_%02d\n", offset-NODE_00);
}
} }
/************************************************************************ /************************************************************************

View File

@ -83,8 +83,8 @@
static void init_nodes(discrete_info *info, const linked_list_entry *block_list, device_t *device); static void init_nodes(discrete_info *info, const linked_list_entry *block_list, device_t *device);
static node_description *discrete_find_node(const discrete_info *info, int node); static node_description *discrete_find_node(const discrete_info *info, int node);
static DEVICE_RESET( discrete ); //static DEVICE_RESET( discrete );
static STREAM_UPDATE( discrete_stream_update ); //static STREAM_UPDATE( discrete_stream_update );
static STREAM_UPDATE( buffer_stream_update ); static STREAM_UPDATE( buffer_stream_update );
static int profiling = 0; static int profiling = 0;
@ -455,7 +455,7 @@ static void discrete_sanity_check(const discrete_info *info)
* Master discrete system start * Master discrete system start
* *
*************************************/ *************************************/
#if 0
static DEVICE_START( discrete ) static DEVICE_START( discrete )
{ {
linked_list_entry **intf; linked_list_entry **intf;
@ -526,7 +526,7 @@ static DEVICE_START( discrete )
} }
} }
#endif
/************************************* /*************************************
@ -577,6 +577,7 @@ static void display_profiling(const discrete_info *info)
printf("Average samples/stream_update: %8.2f\n", (double) info->total_samples / (double) info->total_stream_updates); printf("Average samples/stream_update: %8.2f\n", (double) info->total_samples / (double) info->total_stream_updates);
} }
#if 0
static DEVICE_STOP( discrete ) static DEVICE_STOP( discrete )
{ {
discrete_info *info = get_safe_token(device); discrete_info *info = get_safe_token(device);
@ -604,7 +605,7 @@ static DEVICE_STOP( discrete )
info->disclogfile = NULL; info->disclogfile = NULL;
} }
} }
#endif
/************************************* /*************************************
@ -612,7 +613,7 @@ static DEVICE_STOP( discrete )
* Master reset of all nodes * Master reset of all nodes
* *
*************************************/ *************************************/
#if 0
static DEVICE_RESET( discrete ) static DEVICE_RESET( discrete )
{ {
const discrete_info *info = get_safe_token(device); const discrete_info *info = get_safe_token(device);
@ -631,6 +632,7 @@ static DEVICE_RESET( discrete )
(*node.item()->step)(node.item()); (*node.item()->step)(node.item());
} }
} }
#endif
/************************************* /*************************************
* *
@ -697,7 +699,7 @@ static STREAM_UPDATE( buffer_stream_update )
*(ptr++) = data; *(ptr++) = data;
} }
#if 0
static STREAM_UPDATE( discrete_stream_update ) static STREAM_UPDATE( discrete_stream_update )
{ {
discrete_info *info = (discrete_info *)param; discrete_info *info = (discrete_info *)param;
@ -756,7 +758,7 @@ static STREAM_UPDATE( discrete_stream_update )
} }
} }
#endif
/************************************* /*************************************
@ -1007,6 +1009,7 @@ int node_description::same_module_index(const node_list_t &list)
return -1; return -1;
} }
#if 0
/************************************************************************** /**************************************************************************
* Generic get_info * Generic get_info
**************************************************************************/ **************************************************************************/
@ -1034,4 +1037,364 @@ DEVICE_GET_INFO( discrete )
DEFINE_LEGACY_SOUND_DEVICE(DISCRETE, discrete); DEFINE_LEGACY_SOUND_DEVICE(DISCRETE, discrete);
#endif
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
const device_type DISCRETE = discrete_device_config::static_alloc_device_config;
//**************************************************************************
// DEVICE CONFIGURATION
//**************************************************************************
#if 0
//-------------------------------------------------
// static_set_type - configuration helper to set
// the chip type
//-------------------------------------------------
void discrete_device_config::static_set_type(device_config *device, int type)
{
discrete_device_config *asc = downcast<discrete_device_config *>(device);
asc->m_type = type;
}
//-------------------------------------------------
// static_set_type - configuration helper to set
// the IRQ callback
//-------------------------------------------------
void discrete_device_config::static_set_irqf(device_config *device, void (*irqf)(device_t *device, int state))
{
discrete_device_config *asc = downcast<discrete_device_config *>(device);
asc->m_irq_func = irqf;
}
#endif
//-------------------------------------------------
// discrete_device_config - constructor
//-------------------------------------------------
discrete_device_config::discrete_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
: device_config(mconfig, static_alloc_device_config, "DISCRETE", tag, owner, clock),
device_config_sound_interface(mconfig, *this)
{
}
//-------------------------------------------------
// static_alloc_device_config - allocate a new
// configuration object
//-------------------------------------------------
device_config *discrete_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
{
return global_alloc(discrete_device_config(mconfig, tag, owner, clock));
}
//-------------------------------------------------
// alloc_device - allocate a new device object
//-------------------------------------------------
device_t *discrete_device_config::alloc_device(running_machine &machine) const
{
return auto_alloc(&machine, discrete_device(machine, *this));
}
//-------------------------------------------------
// discrete_device - constructor
//-------------------------------------------------
discrete_device::discrete_device(running_machine &_machine, const discrete_device_config &config)
: device_t(_machine, config),
device_sound_interface(_machine, config, *this),
m_config(config)
{
//memset(&m_info, 0, sizeof(m_info));
}
discrete_device::~discrete_device(void)
{
discrete_info *info = &m_info;
osd_work_queue_free(info->queue);
if (profiling)
{
display_profiling(info);
}
/* Process nodes which have a stop func */
for_each(node_description *, node, &info->node_list)
{
if (node.item()->module->stop)
(*node.item()->module->stop)(node.item());
}
if (DISCRETE_DEBUGLOG)
{
/* close the debug log */
if (info->disclogfile)
fclose(info->disclogfile);
info->disclogfile = NULL;
}
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void discrete_device::device_start()
{
// create the stream
//m_stream = stream_create(this, 0, 2, 22257, this, static_stream_generate);
linked_list_entry **intf;
const discrete_sound_block *intf_start = (discrete_sound_block *) baseconfig().static_config();
discrete_info *info = &m_info;
char name[32];
info->device = this;
/* If a clock is specified we will use it, otherwise run at the audio sample rate. */
if (this->clock())
info->sample_rate = this->clock();
else
info->sample_rate = this->machine->sample_rate;
info->sample_time = 1.0 / info->sample_rate;
info->neg_sample_time = - info->sample_time;
info->total_samples = 0;
info->total_stream_updates = 0;
/* create the logfile */
sprintf(name, "discrete%s.log", this->tag());
if (DISCRETE_DEBUGLOG)
info->disclogfile = fopen(name, "w");
/* enable profiling */
if (getenv("DISCRETE_PROFILING"))
profiling = atoi(getenv("DISCRETE_PROFILING"));
/* Build the final block list */
info->block_list = NULL;
intf = &info->block_list;
discrete_build_list(info, intf_start, &intf);
/* first pass through the nodes: sanity check, fill in the indexed_nodes, and make a total count */
discrete_sanity_check(info);
/* Start with empty lists */
info->node_list.reset();
info->output_list.reset();
info->input_list.reset();
/* allocate memory to hold pointers to nodes by index */
info->indexed_node = auto_alloc_array_clear(this->machine, node_description *, DISCRETE_MAX_NODES);
/* initialize the node data */
init_nodes(info, info->block_list, this);
/* now go back and find pointers to all input nodes */
for_each(node_description *, node, &info->node_list)
{
node.item()->find_input_nodes();
}
/* initialize the stream(s) */
info->discrete_stream = stream_create(this,info->input_list.count(), info->output_list.count(), info->sample_rate, this, static_stream_generate);
/* allocate a queue */
info->queue = osd_work_queue_alloc(WORK_QUEUE_FLAG_MULTI | WORK_QUEUE_FLAG_HIGH_FREQ);
/* Process nodes which have a start func */
for_each(node_description *, node, &info->node_list)
{
if (node.item()->module->start)
(*node.item()->module->start)(node.item());
}
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void discrete_device::device_reset()
{
const discrete_info *info = &m_info;
stream_update(info->discrete_stream);
/* loop over all nodes */
for_each (node_description *, node, &info->node_list)
{
node.item()->output[0] = 0;
/* if the node has a reset function, call it */
if (node.item()->module->reset)
(*node.item()->module->reset)(node.item());
/* otherwise, just step it */
else if (node.item()->step)
(*node.item()->step)(node.item());
}
}
//-------------------------------------------------
// stream_generate - handle update requests for
// our sound stream
//-------------------------------------------------
STREAM_UPDATE( discrete_device::static_stream_generate )
{
reinterpret_cast<discrete_device *>(param)->stream_generate(inputs, outputs, samples);
}
void discrete_device::stream_generate(stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
discrete_info *info = &m_info;
int outputnum;
//, task_group;
if (samples == 0)
return;
/* Setup any output streams */
outputnum = 0;
for_each(node_description *, node, &info->output_list)
{
node.item()->context = (void *) outputs[outputnum];
outputnum++;
}
/* Setup any input streams */
for_each(node_description *, node, &info->input_list)
{
struct dss_input_context *context = (struct dss_input_context *) node.item()->context;
context->ptr = (stream_sample_t *) inputs[context->stream_in_number];
}
/* Setup tasks */
for_each(discrete_task *, task, &info->task_list)
{
int i;
task.item()->samples = samples;
/* unlock the thread */
task.item()->unlock();
/* set up task buffers */
for (i = 0; i < task.item()->numbuffered; i++)
task.item()->ptr[i] = task.item()->node_buf[i];
/* initialize sources */
for_each(discrete_source_node *, sn, &task.item()->source_list)
{
sn.item()->ptr = sn.item()->task->node_buf[sn.item()->output_node];
}
}
for_each(discrete_task *, task, &info->task_list)
{
/* Fire a work item for each task */
osd_work_item_queue(info->queue, task_callback, (void *) &info->task_list, WORK_ITEM_FLAG_AUTO_RELEASE);
}
osd_work_queue_wait(info->queue, osd_ticks_per_second()*10);
if (profiling)
{
info->total_samples += samples;
info->total_stream_updates++;
}
}
//-------------------------------------------------
// read - read from the chip's registers and internal RAM
//-------------------------------------------------
READ8_MEMBER( discrete_device::read )
{
discrete_info *info = &m_info;
node_description *node = discrete_find_node(info, offset);
UINT8 data = 0;
/* Read the node input value if allowed */
if (node)
{
/* Bring the system up to now */
stream_update(info->discrete_stream);
data = (UINT8) node->output[NODE_CHILD_NODE_NUM(offset)];
}
else
fatalerror("discrete_sound_r read from non-existent NODE_%02d\n", offset-NODE_00);
return data;
}
//-------------------------------------------------
// write - write to the chip's registers and internal RAM
//-------------------------------------------------
WRITE8_MEMBER( discrete_device::write )
{
discrete_info *info = &m_info;
node_description *node = discrete_find_node(info, offset);
/* Update the node input value if it's a proper input node */
if (node)
{
struct dss_input_context *context = (struct dss_input_context *)node->context;
UINT8 new_data = 0;
switch (node->module->type)
{
case DSS_INPUT_DATA:
case DSS_INPUT_BUFFER:
new_data = data;
break;
case DSS_INPUT_LOGIC:
case DSS_INPUT_PULSE:
new_data = data ? 1 : 0;
break;
case DSS_INPUT_NOT:
new_data = data ? 0 : 1;
break;
}
if (context->data != new_data)
{
if (context->is_buffered)
{
/* Bring the system up to now */
stream_update(context->buffer_stream);
context->data = new_data;
}
else
{
/* Bring the system up to now */
stream_update(info->discrete_stream);
context->data = new_data;
/* Update the node output here so we don't have to do it each step */
node->output[0] = new_data * context->gain + context->offset;
}
}
}
else
{
discrete_log(info, "discrete_sound_w write to non-existent NODE_%02d\n", offset-NODE_00);
}
}

View File

@ -3,7 +3,7 @@
#ifndef __DISCRETE_H__ #ifndef __DISCRETE_H__
#define __DISCRETE_H__ #define __DISCRETE_H__
#include "devlegcy.h" //#include "devlegcy.h"
#include "machine/rescap.h" #include "machine/rescap.h"
/*********************************************************************** /***********************************************************************
@ -3469,8 +3469,6 @@
#include "streams.h" #include "streams.h"
#include "wavwrite.h" #include "wavwrite.h"
/************************************* /*************************************
* *
* macros * macros
@ -4777,6 +4775,98 @@ enum
WRITE8_DEVICE_HANDLER( discrete_sound_w ); WRITE8_DEVICE_HANDLER( discrete_sound_w );
READ8_DEVICE_HANDLER( discrete_sound_r ); READ8_DEVICE_HANDLER( discrete_sound_r );
DECLARE_LEGACY_SOUND_DEVICE(DISCRETE, discrete); //**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
//FIXME: Later
#if 0
#define MCFG_DISCRETE_ADD(_tag, _clock, _type, _irqf) \
MCFG_DEVICE_ADD(_tag, ASC, _clock) \
MCFG_DISCRETE_TYPE(_type) \
MCFG_IRQ_FUNC(_irqf)
#define MCFG_DISCRETE_REPLACE(_tag, _clock, _type, _irqf) \
MCFG_DEVICE_REPLACE(_tag, ASC, _clock) \
MCFG_DISCRETE_TYPE(_type) \
MCFG_IRQ_FUNC(_irqf)
#define MCFG_DISCRETE_TYPE(_type) \
DISCRETE_device_config::static_set_type(device, _type); \
#define MCFG_IRQ_FUNC(_irqf) \
DISCRETE_device_config::static_set_irqf(device, _irqf); \
#endif
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> discrete_device_config
class discrete_device_config : public device_config, public device_config_sound_interface
{
friend class discrete_device;
// construction/destruction
discrete_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;
// inline configuration helpers
//static void static_set_type(device_config *device, int type);
//static void static_set_irqf(device_config *device, void (*irqf)(device_t *device, int state));
protected:
// inline data
};
// ======================> discrete_device
class discrete_device : public device_t, public device_sound_interface
{
friend class discrete_device_config;
// construction/destruction
discrete_device(running_machine &_machine, const discrete_device_config &config);
public:
DECLARE_READ8_MEMBER(read);
DECLARE_WRITE8_MEMBER(write);
//sound_stream *m_stream;
virtual ~discrete_device(void);
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
// internal callbacks
static STREAM_UPDATE( static_stream_generate );
virtual void stream_generate(stream_sample_t **inputs, stream_sample_t **outputs, int samples);
// internal state
const discrete_device_config &m_config;
/* all for now */
discrete_info m_info;
private:
};
// device type definition
extern const device_type DISCRETE;
//DECLARE_LEGACY_SOUND_DEVICE(DISCRETE, discrete);
#endif /* __DISCRETE_H__ */ #endif /* __DISCRETE_H__ */