mirror of
https://github.com/holub/mame
synced 2025-06-01 10:31:48 +03:00
More 566 work. Not worth mentioning.
This commit is contained in:
parent
7cbb5098b9
commit
5fc5a8b203
@ -114,6 +114,8 @@ struct dsd_566_context
|
||||
double threshold_low; /* falling threshold */
|
||||
double threshold_high; /* rising threshold */
|
||||
double triangle_ac_offset; /* used to shift a triangle to AC */
|
||||
double v_osc_stable;
|
||||
double v_osc_stop;
|
||||
};
|
||||
|
||||
struct dsd_ls624_context
|
||||
@ -1386,8 +1388,8 @@ static DISCRETE_RESET(dsd_555_vco1)
|
||||
* The 566 is a constant current based VCO. If you change R, that affects
|
||||
* the charge/discharge rate. A constant current source will charge the
|
||||
* cap linearly. Of course due to the transistors there will be some
|
||||
* non-linear areas at the ends of the Vmod range. I do not currently
|
||||
* simulate these. They are beyond the spec of the IC anyways.
|
||||
* non-linear areas at the ends of the Vmod range. As the Vmod voltage
|
||||
* drops from Vcharge, the frequency generated increases.
|
||||
*
|
||||
* The Triangle (pin 4) output is just a buffered version of the cap
|
||||
* charge. It is about 1.35 higher then the cap voltage.
|
||||
@ -1409,6 +1411,19 @@ static DISCRETE_RESET(dsd_555_vco1)
|
||||
* and Vmod. Due to transistor action, it is not 100%, but this formula
|
||||
* gives a good approximation:
|
||||
* I = ((B+ - Vmod - 0.1) * 0.95) / R
|
||||
* You can test the current VS modulation function by using 10k for R
|
||||
* and replace C with a 10k resistor. Then you can monitor the voltage
|
||||
* on pin 7 to work out the current. I=V/R. It will start to oscillate
|
||||
* when in the cap threshold range.
|
||||
*
|
||||
* When Vmod drops below the stable range, the current source no longer
|
||||
* functions properly. Technically this is out of the range specified
|
||||
* for the IC. Of course old games used this range anyways, so we need
|
||||
* to know how the real IC behaves. When Vmod drops below the stable range,
|
||||
* the charge current is stops dropping instead of increasing, while the
|
||||
* discharge current still functions. This means the frequency generated
|
||||
* starts to drop as the voltage lowers, instead of the normal increase
|
||||
* in frequency.
|
||||
*
|
||||
************************************************************************/
|
||||
#define DSD_566__VMOD DISCRETE_INPUT(0)
|
||||
@ -1433,30 +1448,49 @@ static const struct
|
||||
{3.364, /*3.784,*/ 4.259, /*4.552,*/ 4.888, 5.384, 5.896, 6.416}, /* c_high */
|
||||
{1.940, /*2.100,*/ 2.276, /*2.404,*/ 2.580, 2.880, 3.180, 3.488}, /* c_low */
|
||||
{4.352, /*4.144,*/ 4.080, /*4.260,*/ 4.500, 4.960, 5.456, 5.940}, /* sqr_low */
|
||||
/* osc_stable and stop may not be 100% accurate. Had the scope on the wrong setting. */
|
||||
/* They may be 0.02V too high. I will retest these before implementing */
|
||||
{5.100, /*5.380,*/ 5.800, /*6.116,*/ 6.360, 6.992, 7.284, 7.840}, /* osc_stable */
|
||||
{4.420, /*4.820,*/ 5.296, /*5.616,*/ 5.920, 6.448, 6.920, 7.480} /* osc_stop */
|
||||
{4.885, /*5.316,*/ 5.772, /*6.075,*/ 6.335, 6.912, 7.492, 7.945}, /* osc_stable */
|
||||
{4.495, /*4.895,*/ 5.343, /*5.703,*/ 5.997, 6.507, 7.016, 7.518} /* osc_stop */
|
||||
};
|
||||
|
||||
static DISCRETE_STEP(dsd_566)
|
||||
{
|
||||
struct dsd_566_context *context = (struct dsd_566_context *)node->context;
|
||||
|
||||
double i; /* Charging current created by vIn */
|
||||
double i = 0; /* Charging current created by vIn */
|
||||
double i_rise; /* non-linear rise charge current */
|
||||
double dt; /* change in time */
|
||||
double x_time = 0;
|
||||
double v_cap; /* Current voltage on capacitor, before dt */
|
||||
double v_cap_next = 0; /* Voltage on capacitor, after dt */
|
||||
int count_f = 0, count_r = 0;
|
||||
int options = (int)DSD_566__OPTIONS;
|
||||
|
||||
dt = node->info->sample_time; /* Change in time */
|
||||
v_cap = context->cap_voltage; /* Set to voltage before change */
|
||||
|
||||
|
||||
/* Calculate charging current */
|
||||
i = ((DSD_566__VCHARGE - DSD_566__VMOD - 0.1) * .95) / DSD_566__R;
|
||||
/* Calculate charging current if it is in range */
|
||||
if (DSD_566__VMOD > context->v_osc_stop)
|
||||
{
|
||||
double v_charge = DSD_566__VCHARGE - DSD_566__VMOD - 0.1;
|
||||
if (v_charge > 0)
|
||||
{
|
||||
i = (v_charge * .95) / DSD_566__R;
|
||||
if (DSD_566__VMOD < context->v_osc_stable)
|
||||
{
|
||||
/* no where near correct calculation of non linear range */
|
||||
i_rise = ((DSD_566__VCHARGE - context->v_osc_stable - 0.1) * .95) / DSD_566__R;
|
||||
i_rise *= 1.0 - (context->v_osc_stable - DSD_566__VMOD) / (context->v_osc_stable - context->v_osc_stop);
|
||||
}
|
||||
else
|
||||
i_rise = i;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
else return;
|
||||
|
||||
/* Keep looping until all toggling in time sample is used up. */
|
||||
/* Keep looping until all toggling in this time sample is used up. */
|
||||
do
|
||||
{
|
||||
if (context->flip_flop)
|
||||
@ -1475,13 +1509,15 @@ static DISCRETE_STEP(dsd_566)
|
||||
}
|
||||
v_cap = context->threshold_low;
|
||||
context->flip_flop = 0;
|
||||
count_f++;
|
||||
x_time = dt;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Charging */
|
||||
/* iC=C*dv/dt works out to dv=iC*dt/C */
|
||||
v_cap_next = v_cap + (i * dt / DSD_566__C);
|
||||
v_cap_next = v_cap + (i_rise * dt / DSD_566__C);
|
||||
dt = 0;
|
||||
/* Yes, if the cap voltage has reached the max voltage it can,
|
||||
* and the 566 threshold has not been reached, then oscillation stops.
|
||||
@ -1500,6 +1536,8 @@ static DISCRETE_STEP(dsd_566)
|
||||
}
|
||||
v_cap = context->threshold_high;
|
||||
context->flip_flop = 1;
|
||||
count_r++;
|
||||
x_time = dt;
|
||||
}
|
||||
}
|
||||
} while(dt);
|
||||
@ -1521,6 +1559,18 @@ static DISCRETE_STEP(dsd_566)
|
||||
if (options & DISC_566_OUT_AC)
|
||||
node->output[0] -= context->triangle_ac_offset;
|
||||
break;
|
||||
case DISC_566_OUT_COUNT_F_X:
|
||||
node->output[0] = count_f ? count_f + x_time : count_f;
|
||||
break;
|
||||
case DISC_566_OUT_COUNT_R_X:
|
||||
node->output[0] = count_r ? count_r + x_time : count_r;
|
||||
break;
|
||||
case DISC_566_OUT_COUNT_F:
|
||||
node->output[0] = count_f;
|
||||
break;
|
||||
case DISC_566_OUT_COUNT_R:
|
||||
node->output[0] = count_r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1551,6 +1601,8 @@ static DISCRETE_RESET(dsd_566)
|
||||
context->threshold_low = ne566.c_low[v_int] + DSD_566__VNEG;
|
||||
context->v_sqr_high = DSD_566__VPOS - 1;
|
||||
context->v_sqr_low = ne566.sqr_low[v_int] + DSD_566__VNEG;
|
||||
context->v_osc_stable = ne566.osc_stable[v_int] + DSD_566__VNEG;
|
||||
context->v_osc_stop = ne566.osc_stop[v_int] + DSD_566__VNEG;
|
||||
|
||||
if ((int)DSD_566__OPTIONS & DISC_566_OUT_AC)
|
||||
{
|
||||
|
@ -3192,6 +3192,10 @@
|
||||
* DISC_566_OUT_SQUARE - Pin 3 Square Wave Output (DEFAULT)
|
||||
* DISC_566_OUT_TRIANGLE - Pin 4 Triangle Wave Output
|
||||
* DISC_566_OUT_LOGIC - Internal Flip/Flop Output
|
||||
* DISC_566_COUNT_F - # of falling edges
|
||||
* DISC_566_COUNT_R - # of rising edges
|
||||
* DISC_566_COUNT_F_X - # of falling edges with x-time
|
||||
* DISC_566_COUNT_R_X - # of rising edges with x-time
|
||||
*
|
||||
* EXAMPLES: see Starship 1
|
||||
*
|
||||
@ -3584,8 +3588,11 @@ enum
|
||||
#define DISC_566_OUT_SQUARE 0x00 /* Squarewave */
|
||||
#define DISC_566_OUT_TRIANGLE 0x10 /* Triangle waveform */
|
||||
#define DISC_566_OUT_LOGIC 0x20 /* 0/1 logic output */
|
||||
|
||||
#define DISC_566_OUT_MASK 0x30 /* Bits that define output type.
|
||||
#define DISC_566_OUT_COUNT_F 0x30
|
||||
#define DISC_566_OUT_COUNT_R 0x40
|
||||
#define DISC_566_OUT_COUNT_F_X 0x50
|
||||
#define DISC_566_OUT_COUNT_R_X 0x60
|
||||
#define DISC_566_OUT_MASK 0x70 /* Bits that define output type.
|
||||
* Used only internally in module. */
|
||||
|
||||
/* LS624 output flags */
|
||||
|
@ -348,11 +348,11 @@ DISCRETE_SOUND_START( skyraid )
|
||||
NODE_30, /* VMOD */
|
||||
SKYRAID_R18, SKYRAID_C48,
|
||||
5, -5, 5, /* VPOS,VNEG,VCHARGE */
|
||||
DISC_566_OUT_LOGIC)
|
||||
DISC_566_OUT_COUNT_R)
|
||||
DISCRETE_LOGIC_SHIFT(NODE_32, /* IC H7, J7 output */
|
||||
SKYRAID_NOISE, /* IC H7, J7 pins 1 & 2 */
|
||||
1, NODE_31, 16, /* RESET, CLK, SIZE */
|
||||
DISC_LOGIC_SHIFT__RESET_L | DISC_LOGIC_SHIFT__LEFT | DISC_CLK_ON_R_EDGE)
|
||||
DISC_LOGIC_SHIFT__RESET_L | DISC_LOGIC_SHIFT__LEFT | DISC_CLK_BY_COUNT)
|
||||
/* move bits together for ease of use */
|
||||
DISCRETE_TRANSFORM4(NODE_33, NODE_32, 1, 1 << 14, 2, "01&02/3&|")
|
||||
DISCRETE_DAC_R1(SKYRAID_PLANE_SND,
|
||||
@ -369,11 +369,11 @@ DISCRETE_SOUND_START( skyraid )
|
||||
NODE_40, /* VMOD */
|
||||
SKYRAID_R16, SKYRAID_C45,
|
||||
5, -5, SKYRAID_MISSLE_CHARGE_PLUS, /* VPOS,VNEG,VCHARGE */
|
||||
DISC_566_OUT_LOGIC)
|
||||
DISC_566_OUT_COUNT_R)
|
||||
DISCRETE_LOGIC_SHIFT(NODE_42, /* IC K7, L7 output */
|
||||
SKYRAID_NOISE, /* IC K7, L7 pins 1 & 2 */
|
||||
1, NODE_41, 16, /* RESET, CLK, SIZE */
|
||||
DISC_LOGIC_SHIFT__RESET_L | DISC_LOGIC_SHIFT__LEFT | DISC_CLK_ON_R_EDGE)
|
||||
DISC_LOGIC_SHIFT__RESET_L | DISC_LOGIC_SHIFT__LEFT | DISC_CLK_BY_COUNT)
|
||||
DISCRETE_BIT_DECODE(SKYRAID_MSL_A_SND, NODE_42, 0, DEFAULT_TTL_V_LOGIC_1) /* IC K7, pin 3 */
|
||||
DISCRETE_BIT_DECODE(SKYRAID_MSL_B_SND, NODE_42, 15, DEFAULT_TTL_V_LOGIC_1) /* IC L7, pin 13 */
|
||||
|
||||
|
@ -250,7 +250,7 @@ static MACHINE_DRIVER_START( skyraid )
|
||||
/* sound hardware */
|
||||
MDRV_SPEAKER_STANDARD_MONO("mono")
|
||||
|
||||
MDRV_SOUND_ADD("discrete", DISCRETE, 96000)
|
||||
MDRV_SOUND_ADD("discrete", DISCRETE, 0)
|
||||
MDRV_SOUND_CONFIG_DISCRETE(skyraid)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
|
||||
MACHINE_DRIVER_END
|
||||
|
Loading…
Reference in New Issue
Block a user