Discrete tasks now support multiple task output nodes

- See galaxian for example
This commit is contained in:
Couriersud 2009-08-29 22:27:45 +00:00
parent 3de780ea8a
commit 304cd58528
3 changed files with 115 additions and 85 deletions

View File

@ -125,17 +125,20 @@ INLINE void step_nodes_in_list(linked_list_entry **list)
static void *task_callback(void *param, int threadid)
{
task_info *ti = (task_info *) param;
int samples;
int samples, i;
/* set up task buffer */
ti->context->ptr = &ti->context->node_buf[0];
/* set up task buffers */
for (i = 0; i < ti->context->numbuffered; i++)
ti->context->ptr[i] = &ti->context->node_buf[i][0];
samples = ti->samples;
while (samples-- > 0)
{
step_nodes_in_list(&ti->context->list);
}
/* reset ptr */
ti->context->ptr = &ti->context->node_buf[0];
for (i = 0; i < ti->context->numbuffered; i++)
ti->context->ptr[i] = &ti->context->node_buf[i][0];
free(param);
return NULL;
@ -144,7 +147,10 @@ static void *task_callback(void *param, int threadid)
static DISCRETE_STEP( dso_task )
{
discrete_task_context *ctx = (discrete_task_context *) node->context;
*(ctx->ptr++) = (double) DISCRETE_INPUT(0);
int i;
for (i = 0; i < ctx->numbuffered; i++)
*(ctx->ptr[i]++) = (double) DISCRETE_INPUT(i);
}
static DISCRETE_RESET( dso_task )
@ -759,7 +765,10 @@ INLINE void discrete_stream_update_nodes(discrete_info *info)
for (entry = info->task_list; entry != 0; entry = entry->next)
{
discrete_task_context *task = (discrete_task_context *) entry->ptr;
**task->dest = *task->ptr++;
int i;
for (i = 0; i < task->numbuffered; i++)
**task->dest[i] = *task->ptr[i]++;
}
/* loop over all nodes */
@ -865,6 +874,7 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
node->output[0] = 0.0;
node->block = block;
node->custom = block->custom;
node->active_inputs = block->active_inputs;
/* keep track of special nodes */
if (block->node == NODE_SPECIAL)
@ -902,8 +912,13 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
case DSO_TASK_END:
if (cur_task_node == NULL)
fatalerror("init_nodes() - NO DISCRETE_START_TASK.");
task->numbuffered = node->active_inputs;
{
int i;
for (i = 0; i < task->numbuffered; i++)
task->dest[i] = (double **) &node->input[i];
}
node->context = task;
task->dest = (double **) &node->input[0];
task = NULL;
break;
@ -920,7 +935,6 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
info->indexed_node[NODE_INDEX(block->node)] = node;
}
node->active_inputs = block->active_inputs;
for (inputnum = 0; inputnum < DISCRETE_MAX_INPUTS; inputnum++)
{
node->input[inputnum] = &(block->initial[inputnum]);

View File

@ -3669,9 +3669,10 @@ struct _discrete_task_context
{
linked_list_entry *list;
double *ptr;
double node_buf[2048];
double **dest;
int numbuffered;
double *ptr[5];
double node_buf[5][2048];
double **dest[5];
};
struct _discrete_info
@ -4411,7 +4412,11 @@ enum
/* 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_END(BNODE1) { NODE_SPECIAL, DSO_TASK_END , 1, { BNODE1 }, { BNODE1 }, NULL, "DISCRETE_TASK_END" },
#define DISCRETE_TASK_END2(BNODE1,BNODE2) { NODE_SPECIAL, DSO_TASK_END , 2, { BNODE1,BNODE2 }, { BNODE1,BNODE2 }, NULL, "DISCRETE_TASK_END2" },
#define DISCRETE_TASK_END3(BNODE1,BNODE2,BNODE3) { NODE_SPECIAL, DSO_TASK_END , 3, { BNODE1,BNODE2,BNODE3 }, { BNODE1,BNODE2,BNODE3 }, NULL, "DISCRETE_TASK_END3" },
#define DISCRETE_TASK_END4(BNODE1,BNODE2,BNODE3,BNODE4) { NODE_SPECIAL, DSO_TASK_END , 4, { BNODE1,BNODE2,BNODE3,BNODE4 }, { BNODE1,BNODE2,BNODE3,BNODE4 }, NULL, "DISCRETE_TASK_END4" },
#define DISCRETE_TASK_END5(BNODE1,BNODE2,BNODE3,BNODE4,BNODE5) { NODE_SPECIAL, DSO_TASK_END , 5, { BNODE1,BNODE2,BNODE3,BNODE4,BNODE5 }, { BNODE1,BNODE2,BNODE3,BNODE4,BNODE5 }, NULL, "DISCRETE_TASK_END5" },
//#define DISCRETE_TASK_SYNC() { NODE_SPECIAL, DSO_TASK_SYNC, 0, { 0 }, { 0 }, NULL, "DISCRETE_TASK_SYNC" },
/* output */

View File

@ -35,8 +35,6 @@ TODO:
#define SOUND_CLOCK (XTAL/6/2) /* 1.536 MHz */
#define RNG_RATE (XTAL/3*2) /* RNG clock is XTAL/3*2 see Aaron's note in video/galaxian.c */
//#define DISCRETE_BITSET(_N, _N1, _B, _OV) DISCRETE_TRANSFORM4(_N, _N1, (1 << ((_B)-1)), 0, _OV, "01&2>3*")
/* 74LS259 */
#define GAL_INP_BG_DAC NODE_10 /* at 9M Q4 to Q7 in schematics */
@ -270,81 +268,94 @@ static DISCRETE_SOUND_START(galaxian)
/* Pitch */
DISCRETE_INPUT_DATA(GAL_INP_PITCH)
/************************************************/
/* Background */
/************************************************/
DISCRETE_DAC_R1(NODE_100, 1, GAL_INP_BG_DAC, TTL_OUT, &galaxian_bck_dac)
DISCRETE_555_CC(NODE_105, 1, NODE_100, GAL_R21, GAL_C15, 0, 0, 0, &galaxian_bck_vco)
// Next is mult/add opamp circuit
DISCRETE_MULTADD(NODE_110, 1, NODE_105, GAL_R33/RES_3_PARALLEL(GAL_R31,GAL_R32,GAL_R33),
-5.0*GAL_R33/GAL_R31)
DISCRETE_CLAMP(NODE_111,1,NODE_110,0.0,5.0,0.0)
// The three 555
DISCRETE_555_ASTABLE_CV(NODE_115, GAL_INP_FS1, GAL_R22, GAL_R23, GAL_C17, NODE_111, &galaxian_555_vco_desc)
DISCRETE_555_ASTABLE_CV(NODE_116, GAL_INP_FS2, GAL_R25, GAL_R26, GAL_C18, NODE_111, &galaxian_555_vco_desc)
DISCRETE_555_ASTABLE_CV(NODE_117, GAL_INP_FS3, GAL_R28, GAL_R29, GAL_C19, NODE_111, &galaxian_555_vco_desc)
DISCRETE_MIXER3(NODE_120, 1, NODE_115, NODE_116, NODE_117, &galaxian_bck_mixer_desc)
/************************************************/
/* PITCH */
/************************************************/
/* two cascaded LS164 which are reset to pitch latch value,
* thus generating SOUND_CLOCK / (256 - pitch_clock) signal
*
* One possibility to implement this is
* DISCRETE_TRANSFORM3(NODE_130, SOUND_CLOCK, 256, GAL_INP_PITCH, "012-/")
* DISCRETE_COUNTER(NODE_132, 1, 0, NODE_130, 15, DISC_COUNT_UP, 0, DISC_CLK_IS_FREQ)
* but there is a native choice:
*/
DISCRETE_NOTE(NODE_132, 1, SOUND_CLOCK, GAL_INP_PITCH, 255, 15, DISC_CLK_IS_FREQ)
/* from the 74393 (counter 2 above) only QA, QC, QD are used.
* We decode three here and use SUB_NODE(133,x) below to access.
*/
DISCRETE_BITS_DECODE(NODE_133, NODE_132, 0, 3, TTL_OUT) /* QA-QD 74393 */
/************************************************/
/* HIT */
/************************************************/
/* NOISE */
/* since only a sample of the LFSR is latched @V2 we let the lfsr
* run at a lower speed
*/
DISCRETE_LFSR_NOISE(NODE_150, 1, 1, RNG_RATE/100, 1.0, 0, 0.5, &galaxian_lfsr)
DISCRETE_SQUAREWFIX(NODE_151,1,60*264/2,1.0,50,0.5,0) /* 2V signal */
DISCRETE_LOGIC_DFLIPFLOP(NODE_152,1,1,1,NODE_151,NODE_150)
/* Not 100% correct - switching causes high impedance input for node_157
* this is not emulated */
DISCRETE_RCDISC5(NODE_155, NODE_152, GAL_INP_HIT, (GAL_R35 + GAL_R36), GAL_C21)
DISCRETE_OP_AMP_FILTER(NODE_157, 1, NODE_155, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &galaxian_bandpass_desc)
/* Group Background and pitch */
DISCRETE_TASK_START()
/************************************************/
/* FIRE */
/************************************************/
/************************************************/
/* Background */
/************************************************/
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_DAC_R1(NODE_100, 1, GAL_INP_BG_DAC, TTL_OUT, &galaxian_bck_dac)
DISCRETE_555_CC(NODE_105, 1, NODE_100, GAL_R21, GAL_C15, 0, 0, 0, &galaxian_bck_vco)
// Next is mult/add opamp circuit
DISCRETE_MULTADD(NODE_110, 1, NODE_105, GAL_R33/RES_3_PARALLEL(GAL_R31,GAL_R32,GAL_R33),
-5.0*GAL_R33/GAL_R31)
DISCRETE_CLAMP(NODE_111,1,NODE_110,0.0,5.0,0.0)
// The three 555
DISCRETE_555_ASTABLE_CV(NODE_115, GAL_INP_FS1, GAL_R22, GAL_R23, GAL_C17, NODE_111, &galaxian_555_vco_desc)
DISCRETE_555_ASTABLE_CV(NODE_116, GAL_INP_FS2, GAL_R25, GAL_R26, GAL_C18, NODE_111, &galaxian_555_vco_desc)
DISCRETE_555_ASTABLE_CV(NODE_117, GAL_INP_FS3, GAL_R28, GAL_R29, GAL_C19, NODE_111, &galaxian_555_vco_desc)
DISCRETE_MIXER3(NODE_120, 1, NODE_115, NODE_116, NODE_117, &galaxian_bck_mixer_desc)
/************************************************/
/* PITCH */
/************************************************/
/* two cascaded LS164 which are reset to pitch latch value,
* thus generating SOUND_CLOCK / (256 - pitch_clock) signal
*
* One possibility to implement this is
* DISCRETE_TRANSFORM3(NODE_130, SOUND_CLOCK, 256, GAL_INP_PITCH, "012-/")
* DISCRETE_COUNTER(NODE_132, 1, 0, NODE_130, 15, DISC_COUNT_UP, 0, DISC_CLK_IS_FREQ)
* but there is a native choice:
*/
DISCRETE_NOTE(NODE_132, 1, SOUND_CLOCK, GAL_INP_PITCH, 255, 15, DISC_CLK_IS_FREQ)
/* from the 74393 (counter 2 above) only QA, QC, QD are used.
* We decode three here and use SUB_NODE(133,x) below to access.
*/
DISCRETE_BITS_DECODE(NODE_133, NODE_132, 0, 3, TTL_OUT) /* QA-QD 74393 */
DISCRETE_555_ASTABLE_CV(NODE_181, 1, GAL_R44, GAL_R45, GAL_C27, NODE_178, &galaxian_555_fire_vco_desc)
/* End of this task */
DISCRETE_TASK_END5(NODE_120, NODE_SUB(133,0),NODE_SUB(133,1),NODE_SUB(133,2),NODE_SUB(133,3))
/* Group Hit and Fire */
/* 555 toggles discharge on rc discharge module */
DISCRETE_RCDISC5(NODE_182, NODE_181, NODE_171, (GAL_R41), GAL_C25)
DISCRETE_TASK_START()
/************************************************/
/* HIT */
/************************************************/
/* NOISE */
/* since only a sample of the LFSR is latched @V2 we let the lfsr
* run at a lower speed
*/
DISCRETE_LFSR_NOISE(NODE_150, 1, 1, RNG_RATE/100, 1.0, 0, 0.5, &galaxian_lfsr)
DISCRETE_SQUAREWFIX(NODE_151,1,60*264/2,1.0,50,0.5,0) /* 2V signal */
DISCRETE_LOGIC_DFLIPFLOP(NODE_152,1,1,1,NODE_151,NODE_150)
/* Not 100% correct - switching causes high impedance input for node_157
* this is not emulated */
DISCRETE_RCDISC5(NODE_155, NODE_152, GAL_INP_HIT, (GAL_R35 + GAL_R36), GAL_C21)
DISCRETE_OP_AMP_FILTER(NODE_157, 1, NODE_155, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &galaxian_bandpass_desc)
/************************************************/
/* FIRE */
/************************************************/
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_182, NODE_181, NODE_171, (GAL_R41), GAL_C25)
/* End of task */
DISCRETE_TASK_END2(NODE_157, NODE_182)
/************************************************/
/* FINAL MIX */