summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/sound/hc55516.c
diff options
context:
space:
mode:
author Zsolt Vasvari <zsoltvas@mamedev.org>2008-01-21 03:36:21 +0000
committer Zsolt Vasvari <zsoltvas@mamedev.org>2008-01-21 03:36:21 +0000
commitadcf70548a1457bb5b20647e19472964d5df8508 (patch)
tree0e8b3ddf7bd48365229b087f339f45572df9ae64 /src/emu/sound/hc55516.c
parent08efd6203a698b17777ea9fc8c51bce094040401 (diff)
- Added MC3417 and MC3418 variants
- Changed Mouse Trap to use MC3417
Diffstat (limited to 'src/emu/sound/hc55516.c')
-rw-r--r--src/emu/sound/hc55516.c138
1 files changed, 96 insertions, 42 deletions
diff --git a/src/emu/sound/hc55516.c b/src/emu/sound/hc55516.c
index ff0b6492212..fe0448e31df 100644
--- a/src/emu/sound/hc55516.c
+++ b/src/emu/sound/hc55516.c
@@ -1,15 +1,25 @@
+/*****************************************************************************
+
+ Harris HC-55516 (and related) emulator
+
+ Copyright Nicola Salmoria and the MAME Team
+
+ Notes:
+ * The only difference between MC3417 and MC3418 is the number
+ of bits checked for the Coincidence Output. For the MC3417,
+ it is three bits, while for the MC3418 it is four.
+ This is not emulated.
+
+*****************************************************************************/
+
#include "sndintrf.h"
#include "streams.h"
-#include "hc55516.h"
#include <math.h>
-#include "cpuintrf.h"
-
-/* default to 4x oversampling */
+/* 4x oversampling */
#define SAMPLE_RATE (48000 * 4)
-
#define INTEGRATOR_LEAK_TC 0.001
#define FILTER_DECAY_TC 0.004
#define FILTER_CHARGE_TC 0.004
@@ -22,8 +32,9 @@ struct hc55516_data
{
sound_stream *channel;
int clock; /* 0 = software driven, non-0 = oscillator */
+ int active_clock_hi;
- UINT8 last_clock;
+ UINT8 last_clock_state;
UINT8 databit;
UINT8 new_databit;
UINT8 shiftreg;
@@ -45,7 +56,7 @@ static void hc55516_update(void *param, stream_sample_t **inputs, stream_sample_
-static void *hc55516_start(int sndindex, int clock, const void *config)
+static void *start_common(int sndindex, int clock, const void *config, int _active_clock_hi)
{
struct hc55516_data *chip;
@@ -60,9 +71,11 @@ static void *hc55516_start(int sndindex, int clock, const void *config)
/* create the stream */
chip->clock = clock;
+ chip->active_clock_hi = _active_clock_hi;
+ chip->last_clock_state = 0;
chip->channel = stream_create(0, 1, SAMPLE_RATE, chip, hc55516_update);
- state_save_register_item("hc55516", sndindex, chip->last_clock);
+ state_save_register_item("hc55516", sndindex, chip->last_clock_state);
state_save_register_item("hc55516", sndindex, chip->databit);
state_save_register_item("hc55516", sndindex, chip->new_databit);
state_save_register_item("hc55516", sndindex, chip->shiftreg);
@@ -77,7 +90,40 @@ static void *hc55516_start(int sndindex, int clock, const void *config)
}
-INLINE int current_clock_edge(struct hc55516_data *chip)
+static void *hc55516_start(int sndindex, int clock, const void *config)
+{
+ return start_common(sndindex, clock, config, TRUE);
+}
+
+
+static void *mc3417_start(int sndindex, int clock, const void *config)
+{
+ return start_common(sndindex, clock, config, FALSE);
+}
+
+
+static void *mc3418_start(int sndindex, int clock, const void *config)
+{
+ return start_common(sndindex, clock, config, FALSE);
+}
+
+
+
+static void hc55516_reset(void *chip)
+{
+ ((struct hc55516_data *)chip)->last_clock_state = 0;
+}
+
+
+
+INLINE int is_active_clock_transition(struct hc55516_data *chip, int clock_state)
+{
+ return (( chip->active_clock_hi && !chip->last_clock_state && clock_state) ||
+ (!chip->active_clock_hi && chip->last_clock_state && !clock_state));
+}
+
+
+INLINE int current_clock_state(struct hc55516_data *chip)
{
return ((UINT64)chip->update_count * chip->clock * 2 / SAMPLE_RATE) & 0x01;
}
@@ -159,28 +205,26 @@ static void hc55516_update(void *param, stream_sample_t **inputs, stream_sample_
if (chip->clock != 0)
{
- int edge = current_clock_edge(chip);
-
/* external oscillator */
for (i = 0; i < length; i++, data += slope)
{
- int new_edge;
+ UINT8 clock_state;
*buffer++ = data;
chip->update_count++;
- new_edge = current_clock_edge(chip);
+ clock_state = current_clock_state(chip);
- /* pull in next data bit on falling edge of the clock */
- if (edge && !new_edge)
+ /* pull in next data bit on the appropriate edge of the clock */
+ if (is_active_clock_transition(chip, clock_state))
{
chip->databit = chip->new_databit;
process_bit(chip);
}
- edge = new_edge;
+ chip->last_clock_state = clock_state;
}
}
@@ -194,16 +238,12 @@ static void hc55516_update(void *param, stream_sample_t **inputs, stream_sample_
void hc55516_clock_w(int num, int state)
{
struct hc55516_data *chip = sndti_token(SOUND_HC55516, num);
- int clock = state & 1, diffclock;
+ UINT8 clock_state = state ? TRUE : FALSE;
assert(chip->clock == 0);
- /* update the clock */
- diffclock = clock ^ chip->last_clock;
- chip->last_clock = clock;
-
- /* speech clock changing (active on rising edge) */
- if (diffclock && clock)
+ /* speech clock changing? */
+ if (is_active_clock_transition(chip, clock_state))
{
/* update the output buffer before changing the registers */
stream_update(chip->channel);
@@ -213,6 +253,9 @@ void hc55516_clock_w(int num, int state)
process_bit(chip);
}
+
+ /* update the clock */
+ chip->last_clock_state = clock_state;
}
@@ -250,7 +293,7 @@ void hc55516_digit_clock_clear_w(int num, int data)
}
-int hc55516_clock_edge_r(int num)
+int hc55516_clock_state_r(int num)
{
struct hc55516_data *chip = sndti_token(SOUND_HC55516, num);
@@ -258,7 +301,7 @@ int hc55516_clock_edge_r(int num)
stream_update(chip->channel);
- return current_clock_edge(chip);
+ return current_clock_state(chip);
}
@@ -268,16 +311,14 @@ WRITE8_HANDLER( hc55516_0_clock_w ) { hc55516_clock_w(0,data); }
WRITE8_HANDLER( hc55516_0_clock_clear_w ) { hc55516_clock_clear_w(0,data); }
WRITE8_HANDLER( hc55516_0_clock_set_w ) { hc55516_clock_set_w(0,data); }
WRITE8_HANDLER( hc55516_0_digit_clock_clear_w ) { hc55516_digit_clock_clear_w(0,data); }
-READ8_HANDLER ( hc55516_0_clock_edge_r ) { return hc55516_clock_edge_r(0); }
+READ8_HANDLER ( hc55516_0_clock_state_r ) { return hc55516_clock_state_r(0); }
WRITE8_HANDLER( hc55516_1_digit_w ) { hc55516_digit_w(1,data); }
WRITE8_HANDLER( hc55516_1_clock_w ) { hc55516_clock_w(1,data); }
WRITE8_HANDLER( hc55516_1_clock_clear_w ) { hc55516_clock_clear_w(1,data); }
WRITE8_HANDLER( hc55516_1_clock_set_w ) { hc55516_clock_set_w(1,data); }
WRITE8_HANDLER( hc55516_1_digit_clock_clear_w ) { hc55516_digit_clock_clear_w(1,data); }
-READ8_HANDLER ( hc55516_1_clock_edge_r ) { return hc55516_clock_edge_r(1); }
-
-
+READ8_HANDLER ( hc55516_1_clock_state_r ) { return hc55516_clock_state_r(1); }
@@ -285,29 +326,19 @@ READ8_HANDLER ( hc55516_1_clock_edge_r ) { return hc55516_clock_edge_r(1); }
* Generic get_info
**************************************************************************/
-static void hc55516_set_info(void *token, UINT32 state, sndinfo *info)
-{
- switch (state)
- {
- /* no parameters to set */
- }
-}
-
-
void hc55516_get_info(void *token, UINT32 state, sndinfo *info)
{
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
+ case SNDINFO_INT_ALIAS: info->i = SOUND_HC55516; break;
/* --- the following bits of info are returned as pointers to data or functions --- */
- case SNDINFO_PTR_SET_INFO: info->set_info = hc55516_set_info; break;
case SNDINFO_PTR_START: info->start = hc55516_start; break;
- case SNDINFO_PTR_STOP: /* nothing */ break;
- case SNDINFO_PTR_RESET: /* nothing */ break;
+ case SNDINFO_PTR_RESET: info->reset = hc55516_reset; break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
- case SNDINFO_STR_NAME: info->s = "HC55516"; break;
+ case SNDINFO_STR_NAME: info->s = "HC-55516"; break;
case SNDINFO_STR_CORE_FAMILY: info->s = "CVSD"; break;
case SNDINFO_STR_CORE_VERSION: info->s = "2.0"; break;
case SNDINFO_STR_CORE_FILE: info->s = __FILE__; break;
@@ -315,3 +346,26 @@ void hc55516_get_info(void *token, UINT32 state, sndinfo *info)
}
}
+
+void mc3417_get_info(void *token, UINT32 state, sndinfo *info)
+{
+ switch (state)
+ {
+ case SNDINFO_PTR_START: info->start = mc3417_start; break;
+ case SNDINFO_PTR_RESET: /* chip has no reset pin */ break;
+ case SNDINFO_STR_NAME: info->s = "MC3417"; break;
+ default: hc55516_get_info(token, state, info); break;
+ }
+}
+
+
+void mc3418_get_info(void *token, UINT32 state, sndinfo *info)
+{
+ switch (state)
+ {
+ case SNDINFO_PTR_START: info->start = mc3418_start; break;
+ case SNDINFO_PTR_RESET: /* chip has no reset pin */ break;
+ case SNDINFO_STR_NAME: info->s = "MC3418"; break;
+ default: hc55516_get_info(token, state, info); break;
+ }
+}