void dss_lfsr_step(struct node_description *node) { const struct discrete_lfsr_desc *lfsr_desc = node->custom; struct dss_lfsr_context *context = node->context; PRECISION shiftAmount; int fb0,fb1,fbresult,i; /* Reset everything if necessary */ if((node->input[1] ? 1 : 0) == ((lfsr_desc->flags & DISC_LFSR_FLAG_RESET_TYPE_H) ? 1 : 0)) { dss_lfsr_reset(node); } i=0; /* Calculate the number of full shift register cycles since last machine sample. */ shiftAmount = ((context->sampleStep + context->t) / context->shiftStep); context->t = (shiftAmount - (int)shiftAmount) * context->shiftStep; /* left over amount of time */ while(i<(int)shiftAmount) { i++; /* Now clock the LFSR by 1 cycle and output */ /* Fetch the last feedback result */ fbresult=((context->lfsr_reg)>>(lfsr_desc->bitlength))&0x01; /* Stage 2 feedback combine fbresultNew with infeed bit */ fbresult=dss_lfsr_function(lfsr_desc->feedback_function1,fbresult,((node->input[4])?0x01:0x00),0x01); /* Stage 3 first we setup where the bit is going to be shifted into */ fbresult=fbresult*lfsr_desc->feedback_function2_mask; /* Then we left shift the register, */ context->lfsr_reg=(context->lfsr_reg)<<1; /* Now move the fbresult into the shift register and mask it to the bitlength */ context->lfsr_reg=dss_lfsr_function(lfsr_desc->feedback_function2,fbresult, (context->lfsr_reg), ((1<<(lfsr_desc->bitlength))-1)); /* Now get and store the new feedback result */ /* Fetch the feedback bits */ fb0=((context->lfsr_reg)>>(lfsr_desc->feedback_bitsel0))&0x01; fb1=((context->lfsr_reg)>>(lfsr_desc->feedback_bitsel1))&0x01; /* Now do the combo on them */ fbresult=dss_lfsr_function(lfsr_desc->feedback_function0,fb0,fb1,0x01); context->lfsr_reg=dss_lfsr_function(DISC_LFSR_REPLACE,(context->lfsr_reg), fbresult<<(lfsr_desc->bitlength), ((2<<(lfsr_desc->bitlength))-1)); /* Now select the output bit */ node->output=((context->lfsr_reg)>>(lfsr_desc->output_bit))&0x01; /* Final inversion if required */ if(lfsr_desc->flags & DISC_LFSR_FLAG_OUT_INVERT) node->output=(node->output)?0.0:1.0; /* Gain stage */ node->output=(node->output)?(node->input[3])/2:-(node->input[3])/2; /* Bias input as required */ node->output=node->output+node->input[5]; } if(!node->input[0]) { node->output=0; } }
void dss_lfsr_reset(struct node_description *node) { const struct discrete_lfsr_desc *lfsr_desc = node->custom; struct dss_lfsr_context *context = node->context; int fb0,fb1,fbresult; if ((lfsr_desc->clock_type < DISC_CLK_ON_F_EDGE) || (lfsr_desc->clock_type > DISC_CLK_IS_FREQ)) discrete_log("Invalid clock type passed in NODE_%d\n", node->node - NODE_START); context->last = (DSS_COUNTER__CLOCK != 0); if (lfsr_desc->clock_type == DISC_CLK_IS_FREQ) context->t_clock = 1.0 / DSS_LFSR_NOISE__CLOCK; context->t_left = 0; context->lfsr_reg=lfsr_desc->reset_value; /* Now get and store the new feedback result */ /* Fetch the feedback bits */ fb0=((context->lfsr_reg)>>(lfsr_desc->feedback_bitsel0))&0x01; fb1=((context->lfsr_reg)>>(lfsr_desc->feedback_bitsel1))&0x01; /* Now do the combo on them */ fbresult=dss_lfsr_function(lfsr_desc->feedback_function0,fb0,fb1,0x01); context->lfsr_reg=dss_lfsr_function(DISC_LFSR_REPLACE,(context->lfsr_reg), fbresult<<(lfsr_desc->bitlength), ((2<<(lfsr_desc->bitlength))-1)); /* Now select and setup the output bit */ node->output=((context->lfsr_reg)>>(lfsr_desc->output_bit))&0x01; /* Final inversion if required */ if(lfsr_desc->flags&DISC_LFSR_FLAG_OUT_INVERT) node->output=(node->output)?0.0:1.0; /* Gain stage */ node->output=(node->output)?(DSS_LFSR_NOISE__AMP)/2:-(DSS_LFSR_NOISE__AMP)/2; /* Bias input as required */ node->output=node->output+DSS_LFSR_NOISE__BIAS; }
int dss_lfsr_reset(struct node_description *node) { struct dss_lfsr_context *context; struct discrete_lfsr_desc *lfsr_desc; context=(struct dss_lfsr_context*)node->context; lfsr_desc=(struct discrete_lfsr_desc*)(node->custom); context->lfsr_reg=lfsr_desc->reset_value; context->lfsr_reg=dss_lfsr_function(DISC_LFSR_REPLACE,0, (dss_lfsr_function(lfsr_desc->feedback_function0,0,0,0x01))<<(lfsr_desc->bitlength),((2<<(lfsr_desc->bitlength))-1)); discrete_log("Shift register RESET to %#10X.\n",(context->lfsr_reg)); /* Now select and setup the output bit */ node->output=((context->lfsr_reg)>>(lfsr_desc->output_bit))&0x01; /* Final inversion if required */ if(lfsr_desc->flags&DISC_LFSR_FLAG_OUT_INVERT) node->output=(node->output)?0.0:1.0; /* Gain stage */ node->output=(node->output)?(node->input[3])/2:-(node->input[3])/2; /* Bias input as required */ node->output=node->output+node->input[5]; return 0; }
void dss_lfsr_reset(struct node_description *node) { const struct discrete_lfsr_desc *lfsr_desc = node->custom; struct dss_lfsr_context *context = node->context; context->t = 0; context->sampleStep = 1.0 / Machine->sample_rate; context->shiftStep = 1.0 / node->input[2]; context->lfsr_reg=lfsr_desc->reset_value; context->lfsr_reg=dss_lfsr_function(DISC_LFSR_REPLACE,0, (dss_lfsr_function(lfsr_desc->feedback_function0,0,0,0x01))<<(lfsr_desc->bitlength),((2<<(lfsr_desc->bitlength))-1)); /* Now select and setup the output bit */ node->output=((context->lfsr_reg)>>(lfsr_desc->output_bit))&0x01; /* Final inversion if required */ if(lfsr_desc->flags&DISC_LFSR_FLAG_OUT_INVERT) node->output=(node->output)?0.0:1.0; /* Gain stage */ node->output=(node->output)?(node->input[3])/2:-(node->input[3])/2; /* Bias input as required */ node->output=node->output+node->input[5]; }
void dss_lfsr_step(struct node_description *node) { const struct discrete_lfsr_desc *lfsr_desc = node->custom; struct dss_lfsr_context *context = node->context; double cycles; int clock, inc = 0; int fb0,fb1,fbresult; if (lfsr_desc->clock_type == DISC_CLK_IS_FREQ) { /* We need to keep clocking the internal clock even if disabled. */ cycles = (context->t_left + discrete_current_context->sample_time) / context->t_clock; inc = (int)cycles; context->t_left = (cycles - inc) * context->t_clock; } /* Reset everything if necessary */ if((DSS_LFSR_NOISE__RESET ? 1 : 0) == ((lfsr_desc->flags & DISC_LFSR_FLAG_RESET_TYPE_H) ? 1 : 0)) { dss_lfsr_reset(node); return; } switch (lfsr_desc->clock_type) { case DISC_CLK_ON_F_EDGE: case DISC_CLK_ON_R_EDGE: /* See if the clock has toggled to the proper edge */ clock = (DSS_LFSR_NOISE__CLOCK != 0); if (context->last != clock) { context->last = clock; if (lfsr_desc->clock_type == clock) { /* Toggled */ inc = 1; } } break; case DISC_CLK_BY_COUNT: /* Clock number of times specified. */ inc = (int)DSS_LFSR_NOISE__CLOCK; break; } for (clock = 0; clock < inc; clock++) { /* Fetch the last feedback result */ fbresult=((context->lfsr_reg)>>(lfsr_desc->bitlength))&0x01; /* Stage 2 feedback combine fbresultNew with infeed bit */ fbresult=dss_lfsr_function(lfsr_desc->feedback_function1,fbresult,((DSS_LFSR_NOISE__FEED)?0x01:0x00),0x01); /* Stage 3 first we setup where the bit is going to be shifted into */ fbresult=fbresult*lfsr_desc->feedback_function2_mask; /* Then we left shift the register, */ context->lfsr_reg=(context->lfsr_reg)<<1; /* Now move the fbresult into the shift register and mask it to the bitlength */ context->lfsr_reg=dss_lfsr_function(lfsr_desc->feedback_function2,fbresult, (context->lfsr_reg), ((1<<(lfsr_desc->bitlength))-1)); /* Now get and store the new feedback result */ /* Fetch the feedback bits */ fb0=((context->lfsr_reg)>>(lfsr_desc->feedback_bitsel0))&0x01; fb1=((context->lfsr_reg)>>(lfsr_desc->feedback_bitsel1))&0x01; /* Now do the combo on them */ fbresult=dss_lfsr_function(lfsr_desc->feedback_function0,fb0,fb1,0x01); context->lfsr_reg=dss_lfsr_function(DISC_LFSR_REPLACE,(context->lfsr_reg), fbresult<<(lfsr_desc->bitlength), ((2<<(lfsr_desc->bitlength))-1)); /* Now select the output bit */ node->output=((context->lfsr_reg)>>(lfsr_desc->output_bit))&0x01; /* Final inversion if required */ if(lfsr_desc->flags & DISC_LFSR_FLAG_OUT_INVERT) node->output=(node->output)?0.0:1.0; /* Gain stage */ node->output=(node->output)?(DSS_LFSR_NOISE__AMP)/2:-(DSS_LFSR_NOISE__AMP)/2; /* Bias input as required */ node->output=node->output+DSS_LFSR_NOISE__BIAS; } if(!DSS_LFSR_NOISE__ENABLE) { node->output=0; } }