mirror of
https://github.com/holub/mame
synced 2025-05-22 21:58:57 +03:00
Discrete sound parallel tasks
Introduced DISCRETE_TASK_START, DISCRETE_TASK_END DISCRETE_TASK_START - Start a new task. A task is a set of nodes which only depend on input nodes and nodes in the set DISCRETE_TASK_END(task_output_node) - Marks the end of the task. task_output_node is the node whose output over time should be preserved. This node can be accessed by nodes in the main thread. Order of execution: a) All tasks in parallel b) All nodes not part of a task. These may only refer to nodes listed in DISCRETE_TASK_END Illustrated the concept in the dkong discrete emulation. This also has been enhanced to buffer DAC output. Further changes: - DISCRETE_OUTPUT now is a stepping node. - DISCRETE_STREAM_INPUT now advances input pointer in step. - More linked_list usage. I estimate that the rework without tasks leads to a 5% performance gain. For dkong, the usage of tasks adds another 15%. There are some features missing: - Multiple nodes in DISCRETE_TASK_END - More task consistency checks - Task identifiers for tasks
This commit is contained in:
parent
05730aa0a1
commit
dd836ed4d5
@ -1070,6 +1070,8 @@ static DISCRETE_STEP(dst_rcfilter_sw)
|
||||
int i,j ;
|
||||
int bits = (int)DST_RCFILTER_SW__SWITCH;
|
||||
double us = 0, rs = 0;
|
||||
double vd;
|
||||
double rt;
|
||||
|
||||
if (DST_RCFILTER_SW__ENABLE)
|
||||
{
|
||||
@ -1086,18 +1088,43 @@ static DISCRETE_STEP(dst_rcfilter_sw)
|
||||
context->vCap[1] += (DST_RCFILTER_SW__VIN - context->vCap[1]) * context->exp1;
|
||||
node->output[0] = context->vCap[1] + (DST_RCFILTER_SW__VIN - context->vCap[1]) * context->factor;
|
||||
break;
|
||||
default:
|
||||
case 3:
|
||||
rs = 2 * DST_RCFILTER_SW__R;
|
||||
vd = RES_VOLTAGE_DIVIDER(rs, CD4066_ON_RES) * DST_RCFILTER_SW__VIN;
|
||||
rt = DST_RCFILTER_SW__R / (CD4066_ON_RES + rs);
|
||||
|
||||
for (j = 0; j < DST_RCFILTER_SW_ITERATIONS; j++)
|
||||
{
|
||||
node->output[0] = vd + rt * (context->vCap[0] + context->vCap[1]);
|
||||
context->vCap[0] += (node->output[0] - context->vCap[0]) * context->exp[0];
|
||||
context->vCap[1] += (node->output[0] - context->vCap[1]) * context->exp[1];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rs = 0;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (( bits & (1 << i)) != 0)
|
||||
{
|
||||
rs += DST_RCFILTER_SW__R;
|
||||
}
|
||||
}
|
||||
|
||||
vd = RES_VOLTAGE_DIVIDER(rs, CD4066_ON_RES) * DST_RCFILTER_SW__VIN;
|
||||
rt = DST_RCFILTER_SW__R / (CD4066_ON_RES + rs);
|
||||
|
||||
for (j = 0; j < DST_RCFILTER_SW_ITERATIONS; j++)
|
||||
{
|
||||
us = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (( bits & (1 << i)) != 0)
|
||||
{
|
||||
us += context->vCap[i];
|
||||
rs += DST_RCFILTER_SW__R;
|
||||
}
|
||||
}
|
||||
node->output[0] = RES_VOLTAGE_DIVIDER(rs, CD4066_ON_RES) * DST_RCFILTER_SW__VIN + DST_RCFILTER_SW__R / (CD4066_ON_RES + rs) * us;
|
||||
node->output[0] = vd + rt * us;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (( bits & (1 << i)) != 0)
|
||||
|
@ -15,7 +15,6 @@
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#define EXPERIMENTAL_STREAM_PARALLEL (0)
|
||||
|
||||
#define DSS_INPUT__GAIN (*(node->input[0]))
|
||||
#define DSS_INPUT__OFFSET (*(node->input[1]))
|
||||
@ -67,14 +66,6 @@ READ8_DEVICE_HANDLER(discrete_sound_r)
|
||||
return data;
|
||||
}
|
||||
|
||||
#if EXPERIMENTAL_STREAM_PARALLEL
|
||||
static STREAM_BACKGROUND_CALLBACK( disc_cb )
|
||||
{
|
||||
node_description *node = (node_description *) ptr;
|
||||
|
||||
node->output[0] = param * DSS_INPUT__GAIN + DSS_INPUT__OFFSET;
|
||||
}
|
||||
#endif
|
||||
|
||||
WRITE8_DEVICE_HANDLER(discrete_sound_w)
|
||||
{
|
||||
@ -104,7 +95,6 @@ WRITE8_DEVICE_HANDLER(discrete_sound_w)
|
||||
|
||||
if (last_data != new_data)
|
||||
{
|
||||
#if !EXPERIMENTAL_STREAM_PARALLEL
|
||||
/* Bring the system up to now */
|
||||
stream_update(info->discrete_stream);
|
||||
|
||||
@ -112,12 +102,6 @@ WRITE8_DEVICE_HANDLER(discrete_sound_w)
|
||||
|
||||
/* Update the node output here so we don't have to do it each step */
|
||||
node->output[0] = *node_data * DSS_INPUT__GAIN + DSS_INPUT__OFFSET;
|
||||
#else
|
||||
*node_data = new_data;
|
||||
/* Bring the system up to now */
|
||||
stream_update_background(info->discrete_stream, disc_cb, (void *) node, *node_data);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "inptport.h"
|
||||
#include "wavwrite.h"
|
||||
#include "discrete.h"
|
||||
#include "eminline.h"
|
||||
|
||||
|
||||
/*************************************
|
||||
@ -65,11 +66,10 @@
|
||||
|
||||
static void init_nodes(discrete_info *info, linked_list_entry *block_list, const device_config *device);
|
||||
static void find_input_nodes(discrete_info *info);
|
||||
static void setup_output_nodes(const device_config *device, discrete_info *info);
|
||||
static void setup_disc_logs(discrete_info *info);
|
||||
static node_description *discrete_find_node(const discrete_info *info, int node);
|
||||
static DEVICE_RESET( discrete );
|
||||
|
||||
static STREAM_UPDATE( discrete_stream_update );
|
||||
|
||||
|
||||
/*************************************
|
||||
@ -95,7 +95,79 @@ static void CLIB_DECL ATTR_PRINTF(2,3) discrete_log(const discrete_info *disc_in
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct _task_info task_info;
|
||||
|
||||
struct _task_info
|
||||
{
|
||||
discrete_task_context *context;
|
||||
int samples;
|
||||
};
|
||||
|
||||
INLINE void step_nodes_in_list(linked_list_entry **list)
|
||||
{
|
||||
linked_list_entry *entry;
|
||||
for (entry = *list; entry != NULL; entry = entry->next)
|
||||
{
|
||||
node_description *node = (node_description *) entry->ptr;
|
||||
|
||||
/* Now step the node */
|
||||
if (DISCRETE_PROFILING)
|
||||
node->run_time -= osd_profiling_ticks();
|
||||
|
||||
(*node->module->step)(node);
|
||||
//bigselect(info->device, node);
|
||||
|
||||
if (DISCRETE_PROFILING)
|
||||
node->run_time += osd_profiling_ticks();
|
||||
}
|
||||
}
|
||||
|
||||
static void *task_callback(void *param, int threadid)
|
||||
{
|
||||
task_info *ti = (task_info *) param;
|
||||
int samples;
|
||||
|
||||
/* set up task buffer */
|
||||
ti->context->ptr = &ti->context->node_buf[0];
|
||||
samples = ti->samples;
|
||||
while (samples-- > 0)
|
||||
{
|
||||
step_nodes_in_list(&ti->context->list);
|
||||
}
|
||||
/* reset ptr */
|
||||
ti->context->ptr = &ti->context->node_buf[0];
|
||||
|
||||
free(param);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static DISCRETE_STEP( dso_task )
|
||||
{
|
||||
discrete_task_context *ctx = (discrete_task_context *) node->context;
|
||||
*(ctx->ptr++) = (double) *(node->input[0]);
|
||||
}
|
||||
|
||||
static DISCRETE_RESET( dso_task )
|
||||
{
|
||||
/* nothing to do - just avoid being stepped */
|
||||
}
|
||||
|
||||
static DISCRETE_STEP( dso_output )
|
||||
{
|
||||
stream_sample_t **output = (stream_sample_t **) &node->context;
|
||||
double val;
|
||||
|
||||
/* Add gain to the output and put into the buffers */
|
||||
/* Clipping will be handled by the main sound system */
|
||||
val = (*node->input[0]) * (*node->input[1]);
|
||||
**output = val;
|
||||
(*output)++;
|
||||
}
|
||||
|
||||
static DISCRETE_RESET( dso_output )
|
||||
{
|
||||
/* nothing to do - just avoid being stepped */
|
||||
}
|
||||
|
||||
/*************************************
|
||||
*
|
||||
@ -119,11 +191,16 @@ static void CLIB_DECL ATTR_PRINTF(2,3) discrete_log(const discrete_info *disc_in
|
||||
|
||||
static const discrete_module module_list[] =
|
||||
{
|
||||
{ DSO_OUTPUT ,"DSO_OUTPUT" , 0 ,0 ,NULL ,NULL },
|
||||
{ DSO_OUTPUT ,"DSO_OUTPUT" , 0 ,sizeof(0) ,dso_output_reset ,dso_output_step },
|
||||
{ DSO_CSVLOG ,"DSO_CSVLOG" , 0 ,0 ,NULL ,NULL },
|
||||
{ DSO_WAVELOG ,"DSO_WAVELOG" , 0 ,0 ,NULL ,NULL },
|
||||
{ DSO_IMPORT ,"DSO_IMPORT" , 0 ,0 ,NULL ,NULL },
|
||||
|
||||
/* parallel modules */
|
||||
{ DSO_TASK_START ,"DSO_TASK_START" , 0 ,0 ,NULL ,NULL },
|
||||
{ DSO_TASK_END ,"DSO_TASK_END" , 0 ,0 ,dso_task_reset ,dso_task_step },
|
||||
{ DSO_TASK_SYNC ,"DSO_TASK_SYNC" , 0 ,0 ,NULL ,NULL },
|
||||
|
||||
/* nop */
|
||||
{ DSS_NOP ,"DSS_NOP" , 0 ,0 ,NULL ,NULL },
|
||||
|
||||
@ -298,11 +375,8 @@ static void discrete_build_list(discrete_info *info, discrete_sound_block *intf,
|
||||
}
|
||||
else if (intf[node_count].type == DSO_DELETE)
|
||||
{
|
||||
int p,deleted;
|
||||
linked_list_entry *entry, *last;
|
||||
|
||||
p = 0;
|
||||
deleted = 0;
|
||||
last = NULL;
|
||||
for (entry = info->block_list; entry != NULL; last = entry, entry = entry->next)
|
||||
{
|
||||
@ -419,7 +493,12 @@ static DEVICE_START( discrete )
|
||||
find_input_nodes(info);
|
||||
|
||||
/* then set up the output nodes */
|
||||
setup_output_nodes(device, info);
|
||||
/* initialize the stream(s) */
|
||||
info->discrete_stream = stream_create(device, info->discrete_input_streams, info->discrete_outputs, info->sample_rate, info, discrete_stream_update);
|
||||
|
||||
/* allocate a queue */
|
||||
|
||||
info->queue = osd_work_queue_alloc(WORK_QUEUE_FLAG_MULTI | WORK_QUEUE_FLAG_HIGH_FREQ);
|
||||
|
||||
setup_disc_logs(info);
|
||||
}
|
||||
@ -437,6 +516,8 @@ static DEVICE_STOP( discrete )
|
||||
discrete_info *info = get_safe_token(device);
|
||||
int log_num;
|
||||
|
||||
osd_work_queue_free(info->queue);
|
||||
|
||||
if (DISCRETE_PROFILING)
|
||||
{
|
||||
int count = 0;
|
||||
@ -646,50 +727,39 @@ INLINE void discrete_stream_update_wave(discrete_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void discrete_stream_update_nodes(discrete_info *info, stream_sample_t **outputs)
|
||||
INLINE void discrete_stream_update_nodes(discrete_info *info)
|
||||
{
|
||||
int outputnum;
|
||||
double val;
|
||||
linked_list_entry *entry;
|
||||
|
||||
if (DISCRETE_PROFILING)
|
||||
info->total_samples++;
|
||||
|
||||
/* update task nodes */
|
||||
for (entry = info->task_list; entry != 0; entry = entry->next)
|
||||
{
|
||||
discrete_task_context *task = (discrete_task_context *) entry->ptr;
|
||||
**task->dest = *task->ptr++;
|
||||
}
|
||||
|
||||
/* loop over all nodes */
|
||||
for (entry = info->step_list; entry != NULL; entry = entry->next)
|
||||
{
|
||||
node_description *node = (node_description *) entry->ptr;
|
||||
|
||||
/* Now step the node */
|
||||
if (DISCRETE_PROFILING)
|
||||
node->run_time -= osd_profiling_ticks();
|
||||
|
||||
(*node->module->step)(node);
|
||||
//bigselect(info->device, node);
|
||||
|
||||
if (DISCRETE_PROFILING)
|
||||
node->run_time += osd_profiling_ticks();
|
||||
|
||||
}
|
||||
|
||||
/* Add gain to the output and put into the buffers */
|
||||
/* Clipping will be handled by the main sound system */
|
||||
for (outputnum = 0; outputnum < info->discrete_outputs; outputnum++)
|
||||
{
|
||||
val = (*info->output_node[outputnum]->input[0]) * (*info->output_node[outputnum]->input[1]);
|
||||
*(outputs[outputnum]++) = val;
|
||||
}
|
||||
step_nodes_in_list(&info->step_list);
|
||||
}
|
||||
|
||||
static STREAM_UPDATE( discrete_stream_update )
|
||||
{
|
||||
discrete_info *info = (discrete_info *)param;
|
||||
stream_sample_t *outptr[DISCRETE_MAX_OUTPUTS];
|
||||
linked_list_entry *entry;
|
||||
int samplenum, nodenum, outputnum;
|
||||
//int j; int left; int run;
|
||||
|
||||
if (samples == 0)
|
||||
return;
|
||||
|
||||
/* Setup any output streams */
|
||||
for (outputnum = 0; outputnum < info->discrete_outputs; outputnum++)
|
||||
outptr[outputnum] = outputs[outputnum];
|
||||
{
|
||||
info->output_node[outputnum]->context = (void *) outputs[outputnum];
|
||||
}
|
||||
|
||||
/* Setup any input streams */
|
||||
for (nodenum = 0; nodenum < info->discrete_input_streams; nodenum++)
|
||||
@ -697,20 +767,32 @@ static STREAM_UPDATE( discrete_stream_update )
|
||||
info->input_stream_data[nodenum] = inputs[nodenum];
|
||||
}
|
||||
|
||||
if ((info->num_csvlogs > 0) || (info->num_wavelogs > 0))
|
||||
for (entry = info->task_list; entry != 0; entry = entry->next)
|
||||
{
|
||||
task_info *ti = malloc(sizeof(task_info));
|
||||
discrete_task_context *task = (discrete_task_context *) entry->ptr;
|
||||
|
||||
/* Fire task */
|
||||
ti->context = task;
|
||||
ti->samples = samples;
|
||||
osd_work_item_queue(info->queue, task_callback, (void *) ti, WORK_ITEM_FLAG_AUTO_RELEASE);
|
||||
}
|
||||
|
||||
/* and wait for them */
|
||||
osd_work_queue_wait(info->queue, osd_ticks_per_second()*10);
|
||||
|
||||
if ((info->num_csvlogs == 0) && (info->num_wavelogs == 0))
|
||||
{
|
||||
/* Now we must do samples iterations of the node list, one output for each step */
|
||||
for (samplenum = 0; samplenum < samples; samplenum++)
|
||||
{
|
||||
discrete_stream_update_nodes(info, outptr);
|
||||
}
|
||||
discrete_stream_update_nodes(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Now we must do samples iterations of the node list, one output for each step */
|
||||
for (samplenum = 0; samplenum < samples; samplenum++)
|
||||
{
|
||||
discrete_stream_update_nodes(info, outptr);
|
||||
discrete_stream_update_nodes(info);
|
||||
discrete_stream_update_csv(info);
|
||||
discrete_stream_update_wave(info);
|
||||
|
||||
@ -732,9 +814,13 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
|
||||
{
|
||||
linked_list_entry **step_list = &info->step_list;
|
||||
linked_list_entry **node_list = &info->node_list;
|
||||
linked_list_entry **task_list = &info->task_list;
|
||||
linked_list_entry **cur_task_node = NULL;
|
||||
linked_list_entry *entry;
|
||||
discrete_task_context *task;
|
||||
|
||||
/* start with no outputs or input streams */
|
||||
|
||||
info->discrete_outputs = 0;
|
||||
info->discrete_input_streams = 0;
|
||||
|
||||
@ -745,6 +831,22 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
|
||||
node_description *node = auto_alloc_clear(info->device->machine, node_description);
|
||||
int inputnum, modulenum;
|
||||
|
||||
/* find the requested module */
|
||||
for (modulenum = 0; module_list[modulenum].type != DSS_NULL; modulenum++)
|
||||
if (module_list[modulenum].type == block->type)
|
||||
break;
|
||||
if (module_list[modulenum].type != block->type)
|
||||
fatalerror("init_nodes() - Unable to find discrete module type %d for NODE_%02d", block->type, NODE_INDEX(block->node));
|
||||
|
||||
/* static inits */
|
||||
node->context = NULL;
|
||||
node->info = info;
|
||||
node->node = block->node;
|
||||
node->module = &module_list[modulenum];
|
||||
node->output[0] = 0.0;
|
||||
node->block = block;
|
||||
node->custom = block->custom;
|
||||
|
||||
/* keep track of special nodes */
|
||||
if (block->node == NODE_SPECIAL)
|
||||
{
|
||||
@ -771,6 +873,23 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
|
||||
info->wavelog_node[info->num_wavelogs++] = node;
|
||||
break;
|
||||
|
||||
/* Task processing */
|
||||
case DSO_TASK_START:
|
||||
if (cur_task_node != NULL)
|
||||
fatalerror("init_nodes() - Nested DISCRETE_START_TASK.");
|
||||
task = auto_alloc_clear(info->device->machine, discrete_task_context);
|
||||
add_list(info, &task_list, task);
|
||||
cur_task_node = &task->list;
|
||||
break;
|
||||
|
||||
case DSO_TASK_END:
|
||||
if (cur_task_node == NULL)
|
||||
fatalerror("init_nodes() - NO DISCRETE_START_TASK.");
|
||||
node->context = task;
|
||||
task->dest = (double **) &node->input[0];
|
||||
task = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
fatalerror("init_nodes() - Failed, trying to create unknown special discrete node.");
|
||||
}
|
||||
@ -784,29 +903,12 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
|
||||
info->indexed_node[NODE_INDEX(block->node)] = node;
|
||||
}
|
||||
|
||||
/* find the requested module */
|
||||
for (modulenum = 0; module_list[modulenum].type != DSS_NULL; modulenum++)
|
||||
if (module_list[modulenum].type == block->type)
|
||||
break;
|
||||
if (module_list[modulenum].type != block->type)
|
||||
fatalerror("init_nodes() - Unable to find discrete module type %d for NODE_%02d", block->type, NODE_INDEX(block->node));
|
||||
|
||||
/* static inits */
|
||||
node->info = info;
|
||||
node->node = block->node;
|
||||
node->module = &module_list[modulenum];
|
||||
node->output[0] = 0.0;
|
||||
node->block = block;
|
||||
|
||||
node->active_inputs = block->active_inputs;
|
||||
for (inputnum = 0; inputnum < DISCRETE_MAX_INPUTS; inputnum++)
|
||||
{
|
||||
node->input[inputnum] = &(block->initial[inputnum]);
|
||||
}
|
||||
|
||||
node->context = NULL;
|
||||
node->custom = block->custom;
|
||||
|
||||
/* setup module if custom */
|
||||
if (block->type == DST_CUSTOM)
|
||||
{
|
||||
@ -835,7 +937,18 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
|
||||
/* our running order just follows the order specified */
|
||||
/* does the node step ? */
|
||||
if (node->module->step != NULL)
|
||||
{
|
||||
/* do we belong to a task? */
|
||||
if (cur_task_node == NULL)
|
||||
add_list(info, &step_list, node);
|
||||
else
|
||||
add_list(info, &cur_task_node, node);
|
||||
}
|
||||
|
||||
if (block->type == DSO_TASK_END)
|
||||
{
|
||||
cur_task_node = NULL;
|
||||
}
|
||||
|
||||
/* and register save state */
|
||||
if (node->node != NODE_SPECIAL)
|
||||
@ -899,21 +1012,6 @@ static void find_input_nodes(discrete_info *info)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Set up the output nodes
|
||||
*
|
||||
*************************************/
|
||||
|
||||
static void setup_output_nodes(const device_config *device, discrete_info *info)
|
||||
{
|
||||
/* initialize the stream(s) */
|
||||
info->discrete_stream = stream_create(device, info->discrete_input_streams, info->discrete_outputs, info->sample_rate, info, discrete_stream_update);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
*
|
||||
* Set up the logs
|
||||
|
@ -3659,6 +3659,17 @@ struct _linked_list_entry
|
||||
linked_list_entry *next;
|
||||
};
|
||||
|
||||
typedef struct _discrete_task_context discrete_task_context;
|
||||
struct _discrete_task_context
|
||||
{
|
||||
linked_list_entry *list;
|
||||
|
||||
double *ptr;
|
||||
double node_buf[2048];
|
||||
double **dest;
|
||||
volatile INT32 active;
|
||||
};
|
||||
|
||||
struct _discrete_info
|
||||
{
|
||||
const device_config *device;
|
||||
@ -3680,6 +3691,9 @@ struct _discrete_info
|
||||
/* list of discrete blocks after prescan (IMPORT, DELETE, REPLACE) */
|
||||
linked_list_entry *block_list; /* discrete_sound_block * */
|
||||
|
||||
/* tasks */
|
||||
linked_list_entry *task_list; /* discrete_task_context * */
|
||||
|
||||
/* the input streams */
|
||||
int discrete_input_streams;
|
||||
stream_sample_t *input_stream_data[DISCRETE_MAX_OUTPUTS];
|
||||
@ -3705,6 +3719,10 @@ struct _discrete_info
|
||||
wav_file *disc_wav_file[DISCRETE_MAX_WAVELOGS];
|
||||
node_description *wavelog_node[DISCRETE_MAX_WAVELOGS];
|
||||
|
||||
/* parallel tasks */
|
||||
|
||||
osd_work_queue *queue;
|
||||
|
||||
/* profiling */
|
||||
int total_samples;
|
||||
};
|
||||
@ -4190,6 +4208,11 @@ enum
|
||||
DSO_CSVLOG, /* Dump nodes as csv file */
|
||||
DSO_WAVELOG, /* Dump nodes as wav file */
|
||||
|
||||
/* Parallel execution */
|
||||
DSO_TASK_START, /* start of parallel task */
|
||||
DSO_TASK_END, /* end of parallel task */
|
||||
DSO_TASK_SYNC, /* wait for all parallel tasks to finish */
|
||||
|
||||
/* Output Node -- this must be the last entry in this enum! */
|
||||
DSO_OUTPUT, /* The final output node */
|
||||
|
||||
@ -4198,12 +4221,6 @@ enum
|
||||
DSO_REPLACE, /* replace next node */
|
||||
DSO_DELETE, /* delete nodes */
|
||||
|
||||
/* Parallel execution */
|
||||
|
||||
DSO_TASK_START, /* start of parallel task */
|
||||
DSO_TASK_END, /* end of parallel task */
|
||||
DSO_TASK_SYNC, /* wait for all parallel tasks to finish */
|
||||
|
||||
/* Marks end of this enum -- must be last entry ! */
|
||||
DSO_LAST
|
||||
};
|
||||
@ -4388,6 +4405,11 @@ enum
|
||||
#define DISCRETE_DELETE(NODE_FROM, NODE_TO) { NODE_SPECIAL, DSO_DELETE , 2, { NODE_FROM, NODE_TO }, { NODE_FROM, NODE_TO }, NULL, "DISCRETE_DELETE" },
|
||||
#define DISCRETE_REPLACE { NODE_SPECIAL, DSO_REPLACE , 0, { 0 }, { 0 }, NULL, "DISCRETE_REPLACE" },
|
||||
|
||||
/* parallel tasks */
|
||||
|
||||
#define DISCRETE_TASK_START() { NODE_SPECIAL, DSO_TASK_START, 0, { 0 }, { 0 }, NULL, "DISCRETE_TASK_START" },
|
||||
#define DISCRETE_TASK_END(BUF_NODE) { NODE_SPECIAL, DSO_TASK_END , 1, { BUF_NODE }, { BUF_NODE }, NULL, "DISCRETE_TASK_END" },
|
||||
//#define DISCRETE_TASK_SYNC() { NODE_SPECIAL, DSO_TASK_SYNC, 0, { 0 }, { 0 }, NULL, "DISCRETE_TASK_SYNC" },
|
||||
|
||||
/* output */
|
||||
#define DISCRETE_OUTPUT(OPNODE,GAIN) { NODE_SPECIAL, DSO_OUTPUT , 2, { OPNODE,NODE_NC }, { 0,GAIN }, NULL, "DISCRETE_OUTPUT" },
|
||||
|
@ -348,6 +348,12 @@ static const discrete_custom_info dkong_custom_mixer_info =
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static DISCRETE_SOUND_START(dkong2b_dac)
|
||||
DISCRETE_INPUT_DATA(DS_DAC)
|
||||
DISCRETE_OUTPUT(DS_DAC, 1)
|
||||
DISCRETE_SOUND_END
|
||||
|
||||
static DISCRETE_SOUND_START(dkong2b)
|
||||
|
||||
/************************************************/
|
||||
@ -359,7 +365,8 @@ static DISCRETE_SOUND_START(dkong2b)
|
||||
DISCRETE_INPUT_NOT(DS_SOUND1_INV) /* IC 6J, pin 12 */
|
||||
DISCRETE_INPUT_NOT(DS_SOUND0_INV) /* IC 6J, pin 2 */
|
||||
DISCRETE_INPUT_NOT(DS_DISCHARGE_INV)
|
||||
DISCRETE_INPUT_DATA(DS_DAC)
|
||||
//DISCRETE_INPUT_DATA(DS_DAC)
|
||||
|
||||
/* Mixing - DAC */
|
||||
DISCRETE_ADJUSTMENT_TAG(DS_ADJ_DAC, 0, 1, DISC_LINADJ, "VR2")
|
||||
|
||||
@ -367,6 +374,7 @@ static DISCRETE_SOUND_START(dkong2b)
|
||||
/* Stomp */
|
||||
/************************************************/
|
||||
/* Noise */
|
||||
DISCRETE_TASK_START()
|
||||
DISCRETE_LFSR_NOISE(NODE_11, 1, 1, CLOCK_2VF, 1.0, 0, 0.5, &dkong_lfsr)
|
||||
DISCRETE_COUNTER(NODE_12, 1, 0, NODE_11, 7, DISC_COUNT_UP, 0, DISC_CLK_ON_R_EDGE) /* LS161, IC 3J */
|
||||
DISCRETE_TRANSFORM3(NODE_13,NODE_12,3,DK_SUP_V,"01>2*")
|
||||
@ -382,12 +390,14 @@ static DISCRETE_SOUND_START(dkong2b)
|
||||
|
||||
DISCRETE_RCINTEGRATE(NODE_22,NODE_20,DK_R5, RES_2_PARALLEL(DK_R4+DK_R3,DK_R6),0,DK_C19,DK_SUP_V,DISC_RC_INTEGRATE_TYPE1)
|
||||
DISCRETE_MULTIPLY(DS_OUT_SOUND0,1,NODE_22,DK_R3/R_SERIES(DK_R3,DK_R4))
|
||||
DISCRETE_TASK_END(DS_OUT_SOUND0)
|
||||
|
||||
/************************************************/
|
||||
/* Jump */
|
||||
/************************************************/
|
||||
/* tt */
|
||||
/* 4049B Inverter Oscillator build from 3 inverters */
|
||||
DISCRETE_TASK_START()
|
||||
DISCRETE_INVERTER_OSC(NODE_25,1,0,DK_R38,DK_R39,DK_C26,0,&dkong_inverter_osc_desc_jump)
|
||||
|
||||
#if DK_USE_CUSTOM
|
||||
@ -414,10 +424,12 @@ static DISCRETE_SOUND_START(dkong2b)
|
||||
|
||||
DISCRETE_RCINTEGRATE(NODE_39,NODE_38,DK_R27, RES_2_PARALLEL(DK_R28,DK_R26+DK_R25),0,DK_C16,DK_SUP_V,DISC_RC_INTEGRATE_TYPE1)
|
||||
DISCRETE_MULTIPLY(DS_OUT_SOUND1,1,NODE_39,DK_R25/(DK_R26+DK_R25))
|
||||
DISCRETE_TASK_END(DS_OUT_SOUND1)
|
||||
|
||||
/************************************************/
|
||||
/* Walk */
|
||||
/************************************************/
|
||||
DISCRETE_TASK_START()
|
||||
DISCRETE_INVERTER_OSC(NODE_51,1,0,DK_R47,DK_R48,DK_C30,0,&dkong_inverter_osc_desc_walk)
|
||||
|
||||
#if DK_USE_CUSTOM
|
||||
@ -438,11 +450,14 @@ static DISCRETE_SOUND_START(dkong2b)
|
||||
/* Filter and divide - omitted C22 */
|
||||
DISCRETE_CRFILTER(NODE_61, 1, NODE_60, DK_R15+DK_R16, DK_C23)
|
||||
DISCRETE_MULTIPLY(DS_OUT_SOUND2, 1, NODE_61, DK_R15/(DK_R15+DK_R16))
|
||||
DISCRETE_TASK_END(DS_OUT_SOUND2)
|
||||
|
||||
/************************************************/
|
||||
/* DAC */
|
||||
/************************************************/
|
||||
|
||||
DISCRETE_TASK_START()
|
||||
DISCRETE_INPUTX_STREAM(DS_DAC, 0, 1.0, 0)
|
||||
/* Signal decay circuit Q7, R20, C32 */
|
||||
DISCRETE_RCDISC(NODE_70, DS_DISCHARGE_INV, 1, DK_R20, DK_C32)
|
||||
DISCRETE_TRANSFORM4(NODE_71, DS_DAC, DK_SUP_V/256.0, NODE_70, DS_DISCHARGE_INV, "01*3!2+*")
|
||||
@ -463,6 +478,7 @@ static DISCRETE_SOUND_START(dkong2b)
|
||||
#else
|
||||
DISCRETE_MULTIPLY(DS_OUT_DAC, 1, NODE_73, DS_ADJ_DAC)
|
||||
#endif
|
||||
DISCRETE_TASK_END(DS_OUT_DAC)
|
||||
|
||||
/************************************************/
|
||||
/* Amplifier */
|
||||
@ -621,7 +637,10 @@ static DISCRETE_SOUND_START(radarscp)
|
||||
DISCRETE_INPUT_NOT(DS_SOUND6_INV)
|
||||
DISCRETE_INPUT_NOT(DS_SOUND7_INV)
|
||||
DISCRETE_INPUT_NOT(DS_DISCHARGE_INV)
|
||||
DISCRETE_INPUT_DATA(DS_DAC)
|
||||
|
||||
/* Must be in task if tasks added */
|
||||
DISCRETE_INPUTX_STREAM(DS_DAC, 0, 1.0, 0)
|
||||
//DISCRETE_INPUT_DATA(DS_DAC)
|
||||
|
||||
/* Mixing - DAC */
|
||||
DISCRETE_ADJUSTMENT_TAG(DS_ADJ_DAC, 0, 1, DISC_LINADJ, "VR2")
|
||||
@ -1152,7 +1171,7 @@ static ADDRESS_MAP_START( dkong_sound_io_map, ADDRESS_SPACE_IO, 8 )
|
||||
AM_WRITE(dkong_voice_w)
|
||||
AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_DEVREAD("ls175.3d", dkong_tune_r)
|
||||
AM_WRITE(dkong_voice_w)
|
||||
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_DEVWRITE("discrete", dkong_p1_w) /* only write to dac */
|
||||
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_DEVWRITE("discdac", dkong_p1_w) /* only write to dac */
|
||||
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_LATCH8_READWRITE("virtual_p2")
|
||||
AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_LATCH8_READBIT("ls259.6h", 5)
|
||||
AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_LATCH8_READBIT("ls259.6h", 4)
|
||||
@ -1168,7 +1187,7 @@ ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( radarsc1_sound_io_map, ADDRESS_SPACE_IO, 8 )
|
||||
AM_RANGE(0x00, 0x00) AM_MIRROR(0xff) AM_DEVREAD("ls175.3d", latch8_r)
|
||||
AM_RANGE(0x00, 0xff) AM_DEVWRITE("discrete", dkong_p1_w) /* DAC here */
|
||||
AM_RANGE(0x00, 0xff) AM_DEVWRITE("discdac", dkong_p1_w) /* DAC here */
|
||||
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_LATCH8_READ("virtual_p1")
|
||||
AM_DEVWRITE("tms", M58817_command_w)
|
||||
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_LATCH8_WRITE("virtual_p2")
|
||||
@ -1243,6 +1262,11 @@ MACHINE_DRIVER_START( dkong2b_audio )
|
||||
MDRV_CPU_IO_MAP(dkong_sound_io_map)
|
||||
|
||||
MDRV_SPEAKER_STANDARD_MONO("mono")
|
||||
|
||||
MDRV_SOUND_ADD("discdac", DISCRETE, 0)
|
||||
MDRV_SOUND_CONFIG_DISCRETE(dkong2b_dac)
|
||||
MDRV_SOUND_ROUTE_EX(0, "discrete", 1.0, 0)
|
||||
|
||||
MDRV_SOUND_ADD("discrete", DISCRETE, 0)
|
||||
MDRV_SOUND_CONFIG_DISCRETE(dkong2b)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
|
||||
|
@ -327,30 +327,31 @@ static DISCRETE_SOUND_START(galaxian)
|
||||
/************************************************/
|
||||
/* FIRE */
|
||||
/************************************************/
|
||||
DISCRETE_LOGIC_INVERT(NODE_160, 1, GAL_INP_FIRE)
|
||||
DISCRETE_MULTIPLY(NODE_161, 1, TTL_OUT, GAL_INP_FIRE)
|
||||
DISCRETE_MULTIPLY(NODE_162, 1, TTL_OUT, NODE_160) // inverted
|
||||
DISCRETE_RCFILTER(NODE_163, 1, NODE_162, GAL_R47, GAL_C28)
|
||||
/* Mix noise and 163 */
|
||||
DISCRETE_TRANSFORM5(NODE_167, NODE_152, TTL_OUT, 1.0/GAL_R46, NODE_163, 1.0/GAL_R48,
|
||||
"01*2*34*+" )
|
||||
//DISCRETE_MULTIPLY(NODE_164, 1, TTL_OUT, NODE_152)
|
||||
//DISCRETE_MULTIPLY(NODE_165, 1, 1.0/GAL_R46, NODE_164)
|
||||
//DISCRETE_MULTIPLY(NODE_166, 1, 1.0/GAL_R48, NODE_163)
|
||||
//DISCRETE_ADDER2(NODE_167, 1, NODE_165, NODE_166)
|
||||
DISCRETE_MULTIPLY(NODE_168, 1, RES_2_PARALLEL(GAL_R46, GAL_R48), NODE_167)
|
||||
|
||||
DISCRETE_555_ASTABLE_CV(NODE_171, 1, GAL_R44, GAL_R45, GAL_C27, NODE_168, &galaxian_555_fire_vco_desc)
|
||||
DISCRETE_LOGIC_INVERT(NODE_170, 1, GAL_INP_FIRE)
|
||||
DISCRETE_MULTIPLY(NODE_171, 1, TTL_OUT, GAL_INP_FIRE)
|
||||
DISCRETE_MULTIPLY(NODE_172, 1, TTL_OUT, NODE_170) // inverted
|
||||
DISCRETE_RCFILTER(NODE_173, 1, NODE_172, GAL_R47, GAL_C28)
|
||||
/* Mix noise and 163 */
|
||||
DISCRETE_TRANSFORM5(NODE_177, NODE_152, TTL_OUT, 1.0/GAL_R46, NODE_173, 1.0/GAL_R48,
|
||||
"01*2*34*+" )
|
||||
//DISCRETE_MULTIPLY(NODE_174, 1, TTL_OUT, NODE_152)
|
||||
//DISCRETE_MULTIPLY(NODE_175, 1, 1.0/GAL_R46, NODE_174)
|
||||
//DISCRETE_MULTIPLY(NODE_176, 1, 1.0/GAL_R48, NODE_173)
|
||||
//DISCRETE_ADDER2(NODE_177, 1, NODE_175, NODE_176)
|
||||
DISCRETE_MULTIPLY(NODE_178, 1, RES_2_PARALLEL(GAL_R46, GAL_R48), NODE_177)
|
||||
|
||||
DISCRETE_555_ASTABLE_CV(NODE_181, 1, GAL_R44, GAL_R45, GAL_C27, NODE_178, &galaxian_555_fire_vco_desc)
|
||||
|
||||
/* 555 toggles discharge on rc discharge module */
|
||||
DISCRETE_RCDISC5(NODE_172, NODE_171, NODE_161, (GAL_R41), GAL_C25)
|
||||
DISCRETE_RCDISC5(NODE_182, NODE_181, NODE_171, (GAL_R41), GAL_C25)
|
||||
|
||||
/************************************************/
|
||||
/* FINAL MIX */
|
||||
/************************************************/
|
||||
|
||||
DISCRETE_MIXER5(NODE_279, 1, NODE_SUB(133,0), NODE_SUB(133,2), NODE_SUB(133,2), NODE_SUB(133,3), NODE_120, &galaxian_mixerpre_desc)
|
||||
DISCRETE_MIXER3(NODE_280, 1, NODE_279, NODE_157, NODE_172, &galaxian_mixer_desc)
|
||||
DISCRETE_MIXER3(NODE_280, 1, NODE_279, NODE_157, NODE_182, &galaxian_mixer_desc)
|
||||
DISCRETE_OUTPUT(NODE_280, 32767.0/5.0*5)
|
||||
|
||||
DISCRETE_SOUND_END
|
||||
@ -364,7 +365,7 @@ static DISCRETE_SOUND_START(mooncrst)
|
||||
/************************************************/
|
||||
DISCRETE_DELETE(NODE_279, NODE_279)
|
||||
DISCRETE_REPLACE
|
||||
DISCRETE_MIXER7(NODE_280, 1, NODE_SUB(133,0), NODE_SUB(133,2), NODE_SUB(133,2), NODE_SUB(133,3), NODE_120, NODE_157, NODE_172, &mooncrst_mixer_desc)
|
||||
DISCRETE_MIXER7(NODE_280, 1, NODE_SUB(133,0), NODE_SUB(133,2), NODE_SUB(133,2), NODE_SUB(133,3), NODE_120, NODE_157, NODE_182, &mooncrst_mixer_desc)
|
||||
DISCRETE_SOUND_END
|
||||
|
||||
/*************************************
|
||||
|
Loading…
Reference in New Issue
Block a user