diff options
author | 2008-01-21 03:36:21 +0000 | |
---|---|---|
committer | 2008-01-21 03:36:21 +0000 | |
commit | adcf70548a1457bb5b20647e19472964d5df8508 (patch) | |
tree | 0e8b3ddf7bd48365229b087f339f45572df9ae64 /src/emu/sound/hc55516.c | |
parent | 08efd6203a698b17777ea9fc8c51bce094040401 (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.c | 138 |
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; + } +} |