mirror of
https://github.com/holub/mame
synced 2025-05-20 20:58:51 +03:00
Added OKIM6376 emulation ADPCM Speech Synthesizer [Mirko Buffoni]
* At the moment only the ADPCM part is implemented, while it's missing the BEEP generator and the 2nd channel handling, used mainly for echoing or continuous speech. Added OKIM6376 sound emulation to High Video games [Mirko Buffoni] * Removed GAME_NO_SOUND from newmcard, brasil and fashion * Sound frequency may be incorrect * Although the manual says OKIM6376 is straight ADPCM, generated sound is distorted (over-clamped?)
This commit is contained in:
parent
19818f1f5e
commit
25abe62db4
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -832,6 +832,8 @@ src/emu/sound/okim6258.c svneol=native#text/plain
|
||||
src/emu/sound/okim6258.h svneol=native#text/plain
|
||||
src/emu/sound/okim6295.c svneol=native#text/plain
|
||||
src/emu/sound/okim6295.h svneol=native#text/plain
|
||||
src/emu/sound/okim6376.c svneol=native#text/plain
|
||||
src/emu/sound/okim6376.h svneol=native#text/plain
|
||||
src/emu/sound/pokey.c svneol=native#text/plain
|
||||
src/emu/sound/pokey.h svneol=native#text/plain
|
||||
src/emu/sound/pokey.txt svneol=native#text/plain
|
||||
|
@ -108,6 +108,7 @@ SND_GET_INFO( tms5200 );
|
||||
SND_GET_INFO( tms5220 );
|
||||
SND_GET_INFO( vlm5030 );
|
||||
SND_GET_INFO( adpcm );
|
||||
SND_GET_INFO( okim6376 );
|
||||
SND_GET_INFO( okim6295 );
|
||||
SND_GET_INFO( okim6258 );
|
||||
SND_GET_INFO( msm5205 );
|
||||
@ -317,6 +318,9 @@ static const struct
|
||||
#if (HAS_VLM5030)
|
||||
{ SOUND_VLM5030, SND_GET_INFO_NAME( vlm5030 ) },
|
||||
#endif
|
||||
#if (HAS_OKIM6376)
|
||||
{ SOUND_OKIM6376, SND_GET_INFO_NAME( okim6376 ) },
|
||||
#endif
|
||||
#if (HAS_OKIM6295)
|
||||
{ SOUND_OKIM6295, SND_GET_INFO_NAME( okim6295 ) },
|
||||
#endif
|
||||
|
@ -83,6 +83,7 @@ enum _sound_type
|
||||
SOUND_TMS5200,
|
||||
SOUND_TMS5220,
|
||||
SOUND_VLM5030,
|
||||
SOUND_OKIM6376,
|
||||
SOUND_OKIM6295,
|
||||
SOUND_OKIM6258,
|
||||
SOUND_MSM5205,
|
||||
|
611
src/emu/sound/okim6376.c
Normal file
611
src/emu/sound/okim6376.c
Normal file
@ -0,0 +1,611 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* OKI MSM6376 ADPCM
|
||||
* by Mirko Buffoni
|
||||
*
|
||||
* TODO:
|
||||
* add BEEP tone generator
|
||||
* add 2ch handling (for echoing and continuous speech)
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "sndintrf.h"
|
||||
#include "streams.h"
|
||||
#include "okim6376.h"
|
||||
|
||||
#define MAX_SAMPLE_CHUNK 10000
|
||||
#define MAX_WORDS 111
|
||||
|
||||
|
||||
/* struct describing a single playing ADPCM voice */
|
||||
struct ADPCMVoice
|
||||
{
|
||||
UINT8 playing; /* 1 if we are actively playing */
|
||||
|
||||
UINT32 base_offset; /* pointer to the base memory location */
|
||||
UINT32 sample; /* current sample number */
|
||||
UINT32 count; /* total samples to play */
|
||||
|
||||
UINT32 volume; /* output volume */
|
||||
INT32 signal;
|
||||
INT32 step;
|
||||
};
|
||||
|
||||
struct okim6376
|
||||
{
|
||||
#define OKIM6376_VOICES 2
|
||||
struct ADPCMVoice voice[OKIM6376_VOICES];
|
||||
INT32 command;
|
||||
UINT8 *region_base; /* pointer to the base of the region */
|
||||
sound_stream *stream; /* which stream are we playing on? */
|
||||
UINT32 master_clock; /* master clock frequency */
|
||||
};
|
||||
|
||||
/* step size index shift table */
|
||||
static const int index_shift[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
|
||||
|
||||
/* lookup table for the precomputed difference */
|
||||
static int diff_lookup[49*16];
|
||||
|
||||
/* volume lookup table. Upon configuration, the number of ST pulses determine how much
|
||||
attenuation to apply to the sound signal. */
|
||||
static int volume_table[4] =
|
||||
{
|
||||
0x10, // 0 dB
|
||||
0x08, // -6.0 dB
|
||||
0x04, // -12.0 dB
|
||||
0x02, // -24.0 dB
|
||||
};
|
||||
|
||||
/* tables computed? */
|
||||
static int tables_computed = 0;
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************************
|
||||
|
||||
compute_tables -- compute the difference tables
|
||||
|
||||
***********************************************************************************************/
|
||||
|
||||
static void compute_tables(void)
|
||||
{
|
||||
/* nibble to bit map */
|
||||
static const int nbl2bit[16][4] =
|
||||
{
|
||||
{ 1, 0, 0, 0}, { 1, 0, 0, 1}, { 1, 0, 1, 0}, { 1, 0, 1, 1},
|
||||
{ 1, 1, 0, 0}, { 1, 1, 0, 1}, { 1, 1, 1, 0}, { 1, 1, 1, 1},
|
||||
{-1, 0, 0, 0}, {-1, 0, 0, 1}, {-1, 0, 1, 0}, {-1, 0, 1, 1},
|
||||
{-1, 1, 0, 0}, {-1, 1, 0, 1}, {-1, 1, 1, 0}, {-1, 1, 1, 1}
|
||||
};
|
||||
|
||||
int step, nib;
|
||||
|
||||
/* loop over all possible steps */
|
||||
for (step = 0; step <= 48; step++)
|
||||
{
|
||||
/* compute the step value */
|
||||
int stepval = floor(16.0 * pow(11.0 / 10.0, (double)step));
|
||||
|
||||
/* loop over all nibbles and compute the difference */
|
||||
for (nib = 0; nib < 16; nib++)
|
||||
{
|
||||
diff_lookup[step*16 + nib] = nbl2bit[nib][0] *
|
||||
(stepval * nbl2bit[nib][1] +
|
||||
stepval/2 * nbl2bit[nib][2] +
|
||||
stepval/4 * nbl2bit[nib][3] +
|
||||
stepval/8);
|
||||
}
|
||||
}
|
||||
|
||||
tables_computed = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************************
|
||||
|
||||
reset_adpcm -- reset the ADPCM stream
|
||||
|
||||
***********************************************************************************************/
|
||||
|
||||
static void reset_adpcm(struct ADPCMVoice *voice)
|
||||
{
|
||||
/* make sure we have our tables */
|
||||
if (!tables_computed)
|
||||
compute_tables();
|
||||
|
||||
/* reset the signal/step */
|
||||
voice->signal = -2;
|
||||
voice->step = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************************
|
||||
|
||||
clock_adpcm -- clock the next ADPCM byte
|
||||
|
||||
***********************************************************************************************/
|
||||
|
||||
static INT16 clock_adpcm(struct ADPCMVoice *voice, UINT8 nibble)
|
||||
{
|
||||
voice->signal += diff_lookup[voice->step * 16 + (nibble & 15)];
|
||||
|
||||
/* clamp to the maximum 12bit */
|
||||
if (voice->signal > 4095)
|
||||
voice->signal = 4095;
|
||||
else if (voice->signal < -4096)
|
||||
voice->signal = -4096;
|
||||
|
||||
/* adjust the step size and clamp */
|
||||
voice->step += index_shift[nibble & 7];
|
||||
if (voice->step > 48)
|
||||
voice->step = 48;
|
||||
else if (voice->step < 0)
|
||||
voice->step = 0;
|
||||
|
||||
/* return the signal */
|
||||
return voice->signal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************************
|
||||
|
||||
generate_adpcm -- general ADPCM decoding routine
|
||||
|
||||
***********************************************************************************************/
|
||||
|
||||
static void generate_adpcm(struct okim6376 *chip, struct ADPCMVoice *voice, INT16 *buffer, int samples)
|
||||
{
|
||||
/* if this voice is active */
|
||||
if (voice->playing)
|
||||
{
|
||||
UINT8 *base = chip->region_base + voice->base_offset;
|
||||
int sample = voice->sample;
|
||||
int count = voice->count;
|
||||
|
||||
/* loop while we still have samples to generate */
|
||||
while (samples)
|
||||
{
|
||||
/* compute the new amplitude and update the current step */
|
||||
int nibble = base[sample / 2] >> (((sample & 1) << 2) ^ 4);
|
||||
|
||||
/* output to the buffer, scaling by the volume */
|
||||
/* signal in range -4096..4095, volume in range 2..16 => signal * volume / 2 in range -32768..32767 */
|
||||
*buffer++ = clock_adpcm(voice, nibble) * voice->volume / 2;
|
||||
samples--;
|
||||
|
||||
/* next! */
|
||||
if (++sample >= count)
|
||||
{
|
||||
voice->playing = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* update the parameters */
|
||||
voice->sample = sample;
|
||||
}
|
||||
|
||||
/* fill the rest with silence */
|
||||
while (samples--)
|
||||
*buffer++ = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************************
|
||||
|
||||
okim6376_update -- update the sound chip so that it is in sync with CPU execution
|
||||
|
||||
***********************************************************************************************/
|
||||
|
||||
static STREAM_UPDATE( okim6376_update )
|
||||
{
|
||||
struct okim6376 *chip = param;
|
||||
int i;
|
||||
|
||||
memset(outputs[0], 0, samples * sizeof(*outputs[0]));
|
||||
|
||||
for (i = 0; i < OKIM6376_VOICES; i++)
|
||||
{
|
||||
struct ADPCMVoice *voice = &chip->voice[i];
|
||||
stream_sample_t *buffer = outputs[0];
|
||||
INT16 sample_data[MAX_SAMPLE_CHUNK];
|
||||
int remaining = samples;
|
||||
|
||||
/* loop while we have samples remaining */
|
||||
while (remaining)
|
||||
{
|
||||
int samples = (remaining > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : remaining;
|
||||
int samp;
|
||||
|
||||
generate_adpcm(chip, voice, sample_data, samples);
|
||||
for (samp = 0; samp < samples; samp++)
|
||||
*buffer++ += sample_data[samp];
|
||||
|
||||
remaining -= samples;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************************
|
||||
|
||||
state save support for MAME
|
||||
|
||||
***********************************************************************************************/
|
||||
|
||||
static void adpcm_state_save_register(struct ADPCMVoice *voice, const device_config *device, int index)
|
||||
{
|
||||
state_save_register_device_item(device, index, voice->playing);
|
||||
state_save_register_device_item(device, index, voice->sample);
|
||||
state_save_register_device_item(device, index, voice->count);
|
||||
state_save_register_device_item(device, index, voice->signal);
|
||||
state_save_register_device_item(device, index, voice->step);
|
||||
state_save_register_device_item(device, index, voice->volume);
|
||||
state_save_register_device_item(device, index, voice->base_offset);
|
||||
}
|
||||
|
||||
static void okim6376_state_save_register(struct okim6376 *info, const device_config *device)
|
||||
{
|
||||
int j;
|
||||
|
||||
state_save_register_device_item(device, 0, info->command);
|
||||
for (j = 0; j < OKIM6376_VOICES; j++)
|
||||
adpcm_state_save_register(&info->voice[j], device, j);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************************
|
||||
|
||||
SND_START( okim6376 ) -- start emulation of an OKIM6376-compatible chip
|
||||
|
||||
***********************************************************************************************/
|
||||
|
||||
static SND_START( okim6376 )
|
||||
{
|
||||
struct okim6376 *info;
|
||||
int voice;
|
||||
int divisor = 165;
|
||||
|
||||
info = auto_malloc(sizeof(*info));
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
compute_tables();
|
||||
|
||||
info->command = -1;
|
||||
info->region_base = device->region;
|
||||
info->master_clock = clock;
|
||||
|
||||
/* generate the name and create the stream */
|
||||
info->stream = stream_create(device, 0, 1, clock/divisor, info, okim6376_update);
|
||||
|
||||
/* initialize the voices */
|
||||
for (voice = 0; voice < OKIM6376_VOICES; voice++)
|
||||
{
|
||||
/* initialize the rest of the structure */
|
||||
info->voice[voice].volume = 0;
|
||||
reset_adpcm(&info->voice[voice]);
|
||||
}
|
||||
|
||||
okim6376_state_save_register(info, device);
|
||||
|
||||
/* success */
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************************
|
||||
|
||||
SND_RESET( okim6376 ) -- stop emulation of an OKIM6376-compatible chip
|
||||
|
||||
***********************************************************************************************/
|
||||
|
||||
static SND_RESET( okim6376 )
|
||||
{
|
||||
struct okim6376 *info = device->token;
|
||||
int i;
|
||||
|
||||
stream_update(info->stream);
|
||||
for (i = 0; i < OKIM6376_VOICES; i++)
|
||||
info->voice[i].playing = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************************
|
||||
|
||||
okim6376_status_r -- read the status port of an OKIM6376-compatible chip
|
||||
|
||||
***********************************************************************************************/
|
||||
|
||||
static int okim6376_status_r(int num)
|
||||
{
|
||||
struct okim6376 *info = sndti_token(SOUND_OKIM6376, num);
|
||||
int i, result;
|
||||
|
||||
result = 0xff;
|
||||
|
||||
/* set the bit to 1 if something is playing on a given channel */
|
||||
stream_update(info->stream);
|
||||
for (i = 0; i < OKIM6376_VOICES; i++)
|
||||
{
|
||||
struct ADPCMVoice *voice = &info->voice[i];
|
||||
|
||||
/* set the bit if it's playing */
|
||||
if (!voice->playing)
|
||||
result ^= 1 << i;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************************
|
||||
|
||||
okim6376_data_w -- write to the data port of an OKIM6376-compatible chip
|
||||
|
||||
***********************************************************************************************/
|
||||
|
||||
static void okim6376_data_w(int num, int data)
|
||||
{
|
||||
struct okim6376 *info = sndti_token(SOUND_OKIM6376, num);
|
||||
|
||||
/* if a command is pending, process the second half */
|
||||
if (info->command != -1)
|
||||
{
|
||||
int temp = data >> 4, i, start, stop;
|
||||
unsigned char *base, *base_end;
|
||||
|
||||
|
||||
/* FIX: Check if it's possible to start multiple voices at the same time */
|
||||
if (temp != 0 && temp != 1 && temp != 2)
|
||||
popmessage("OKI6376 start %x contact MAMEDEV", temp);
|
||||
|
||||
/* update the stream */
|
||||
stream_update(info->stream);
|
||||
|
||||
/* determine which voice(s) (voice is set by a 1 bit in the upper 4 bits of the second byte) */
|
||||
for (i = 0; i < OKIM6376_VOICES; i++, temp >>= 1)
|
||||
{
|
||||
if (temp & 1)
|
||||
{
|
||||
struct ADPCMVoice *voice = &info->voice[i];
|
||||
|
||||
/* determine the start/stop positions, max address space is 16Mbit */
|
||||
base = &info->region_base[info->command * 4];
|
||||
base_end = &info->region_base[(MAX_WORDS+1) * 4];
|
||||
start = ((base[0] << 16) + (base[1] << 8) + base[2]) & 0x1fffff;
|
||||
if (start == 0) {
|
||||
voice->playing = 0;
|
||||
} else {
|
||||
/* FIX: for now handle stop reading the next sample start */
|
||||
do {
|
||||
stop = ((base[4] << 16) + (base[5] << 8) + base[6]) & 0x1fffff;
|
||||
if (stop == 0) base += 4;
|
||||
} while (stop == 0 && base < base_end);
|
||||
|
||||
/* set up the voice to play this sample */
|
||||
if (start < stop)
|
||||
{
|
||||
if (!voice->playing)
|
||||
{
|
||||
voice->playing = 1;
|
||||
voice->base_offset = start;
|
||||
voice->sample = 0;
|
||||
voice->count = 2 * (stop - start + 1);
|
||||
|
||||
/* also reset the ADPCM parameters */
|
||||
reset_adpcm(voice);
|
||||
/* FIX: no attenuation for now */
|
||||
voice->volume = volume_table[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("OKIM6376:%d requested to play sample %02x on non-stopped voice\n",num,info->command);
|
||||
}
|
||||
}
|
||||
/* invalid samples go here */
|
||||
else
|
||||
{
|
||||
logerror("OKIM6376:%d requested to play invalid sample %02x\n",num,info->command);
|
||||
voice->playing = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* reset the command */
|
||||
info->command = -1;
|
||||
}
|
||||
|
||||
/* if this is the start of a command, remember the sample number for next time */
|
||||
else if (data & 0x80)
|
||||
{
|
||||
// FIX: maximum adpcm words are 111, there are other 8 commands to generate BEEP tone (0x70 to 0x77),
|
||||
// and others for internal testing, that manual explicitly says not to use (0x78 to 0x7f)
|
||||
info->command = data & 0x7f;
|
||||
}
|
||||
|
||||
/* otherwise, see if this is a silence command */
|
||||
else
|
||||
{
|
||||
int temp = data >> 3, i;
|
||||
|
||||
/* update the stream, then turn it off */
|
||||
stream_update(info->stream);
|
||||
|
||||
/* determine which voice(s) (voice is set by a 1 bit in bits 3-6 of the command */
|
||||
for (i = 0; i < OKIM6376_VOICES; i++, temp >>= 1)
|
||||
{
|
||||
if (temp & 1)
|
||||
{
|
||||
struct ADPCMVoice *voice = &info->voice[i];
|
||||
|
||||
voice->playing = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************************
|
||||
|
||||
okim6376_status_0_r -- generic status read functions
|
||||
okim6376_status_1_r
|
||||
|
||||
***********************************************************************************************/
|
||||
|
||||
READ8_HANDLER( okim6376_status_0_r )
|
||||
{
|
||||
return okim6376_status_r(0);
|
||||
}
|
||||
|
||||
READ8_HANDLER( okim6376_status_1_r )
|
||||
{
|
||||
return okim6376_status_r(1);
|
||||
}
|
||||
|
||||
READ8_HANDLER( okim6376_status_2_r )
|
||||
{
|
||||
return okim6376_status_r(2);
|
||||
}
|
||||
|
||||
READ16_HANDLER( okim6376_status_0_lsb_r )
|
||||
{
|
||||
return okim6376_status_r(0);
|
||||
}
|
||||
|
||||
READ16_HANDLER( okim6376_status_1_lsb_r )
|
||||
{
|
||||
return okim6376_status_r(1);
|
||||
}
|
||||
|
||||
READ16_HANDLER( okim6376_status_2_lsb_r )
|
||||
{
|
||||
return okim6376_status_r(2);
|
||||
}
|
||||
|
||||
READ16_HANDLER( okim6376_status_0_msb_r )
|
||||
{
|
||||
return okim6376_status_r(0) << 8;
|
||||
}
|
||||
|
||||
READ16_HANDLER( okim6376_status_1_msb_r )
|
||||
{
|
||||
return okim6376_status_r(1) << 8;
|
||||
}
|
||||
|
||||
READ16_HANDLER( okim6376_status_2_msb_r )
|
||||
{
|
||||
return okim6376_status_r(2) << 8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************************
|
||||
|
||||
okim6376_data_0_w -- generic data write functions
|
||||
okim6376_data_1_w
|
||||
|
||||
***********************************************************************************************/
|
||||
|
||||
WRITE8_HANDLER( okim6376_data_0_w )
|
||||
{
|
||||
okim6376_data_w(0, data);
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( okim6376_data_1_w )
|
||||
{
|
||||
okim6376_data_w(1, data);
|
||||
}
|
||||
|
||||
WRITE8_HANDLER( okim6376_data_2_w )
|
||||
{
|
||||
okim6376_data_w(2, data);
|
||||
}
|
||||
|
||||
WRITE16_HANDLER( okim6376_data_0_lsb_w )
|
||||
{
|
||||
if (ACCESSING_BITS_0_7)
|
||||
okim6376_data_w(0, data & 0xff);
|
||||
}
|
||||
|
||||
WRITE16_HANDLER( okim6376_data_1_lsb_w )
|
||||
{
|
||||
if (ACCESSING_BITS_0_7)
|
||||
okim6376_data_w(1, data & 0xff);
|
||||
}
|
||||
|
||||
WRITE16_HANDLER( okim6376_data_2_lsb_w )
|
||||
{
|
||||
if (ACCESSING_BITS_0_7)
|
||||
okim6376_data_w(2, data & 0xff);
|
||||
}
|
||||
|
||||
WRITE16_HANDLER( okim6376_data_0_msb_w )
|
||||
{
|
||||
if (ACCESSING_BITS_8_15)
|
||||
okim6376_data_w(0, data >> 8);
|
||||
}
|
||||
|
||||
WRITE16_HANDLER( okim6376_data_1_msb_w )
|
||||
{
|
||||
if (ACCESSING_BITS_8_15)
|
||||
okim6376_data_w(1, data >> 8);
|
||||
}
|
||||
|
||||
WRITE16_HANDLER( okim6376_data_2_msb_w )
|
||||
{
|
||||
if (ACCESSING_BITS_8_15)
|
||||
okim6376_data_w(2, data >> 8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Generic get_info
|
||||
**************************************************************************/
|
||||
|
||||
static SND_SET_INFO( okim6376 )
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
/* no parameters to set */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SND_GET_INFO( okim6376 )
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
/* --- the following bits of info are returned as 64-bit signed integers --- */
|
||||
|
||||
/* --- the following bits of info are returned as pointers to data or functions --- */
|
||||
case SNDINFO_PTR_SET_INFO: info->set_info = SND_SET_INFO_NAME( okim6376 ); break;
|
||||
case SNDINFO_PTR_START: info->start = SND_START_NAME( okim6376 ); break;
|
||||
case SNDINFO_PTR_STOP: /* nothing */ break;
|
||||
case SNDINFO_PTR_RESET: info->reset = SND_RESET_NAME( okim6376 ); break;
|
||||
|
||||
/* --- the following bits of info are returned as NULL-terminated strings --- */
|
||||
case SNDINFO_STR_NAME: strcpy(info->s, "OKI6376"); break;
|
||||
case SNDINFO_STR_CORE_FAMILY: strcpy(info->s, "OKI ADPCM"); break;
|
||||
case SNDINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break;
|
||||
case SNDINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
|
||||
case SNDINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
|
||||
}
|
||||
}
|
||||
|
29
src/emu/sound/okim6376.h
Normal file
29
src/emu/sound/okim6376.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __OKIM6376_H__
|
||||
#define __OKIM6376_H__
|
||||
|
||||
/* an interface for the OKIM6376 and similar chips */
|
||||
|
||||
READ8_HANDLER( okim6376_status_0_r );
|
||||
READ8_HANDLER( okim6376_status_1_r );
|
||||
READ8_HANDLER( okim6376_status_2_r );
|
||||
READ16_HANDLER( okim6376_status_0_lsb_r );
|
||||
READ16_HANDLER( okim6376_status_1_lsb_r );
|
||||
READ16_HANDLER( okim6376_status_2_lsb_r );
|
||||
READ16_HANDLER( okim6376_status_0_msb_r );
|
||||
READ16_HANDLER( okim6376_status_1_msb_r );
|
||||
READ16_HANDLER( okim6376_status_2_msb_r );
|
||||
WRITE8_HANDLER( okim6376_data_0_w );
|
||||
WRITE8_HANDLER( okim6376_data_1_w );
|
||||
WRITE8_HANDLER( okim6376_data_2_w );
|
||||
WRITE16_HANDLER( okim6376_data_0_lsb_w );
|
||||
WRITE16_HANDLER( okim6376_data_1_lsb_w );
|
||||
WRITE16_HANDLER( okim6376_data_2_lsb_w );
|
||||
WRITE16_HANDLER( okim6376_data_0_msb_w );
|
||||
WRITE16_HANDLER( okim6376_data_1_msb_w );
|
||||
WRITE16_HANDLER( okim6376_data_2_msb_w );
|
||||
|
||||
SND_GET_INFO( okim6376 );
|
||||
|
||||
#endif /* __OKIM6376_H__ */
|
@ -365,6 +365,7 @@ endif
|
||||
|
||||
SOUNDDEFS += -DHAS_MSM5205=$(if $(filter MSM5205,$(SOUNDS)),1,0)
|
||||
SOUNDDEFS += -DHAS_MSM5232=$(if $(filter MSM5232,$(SOUNDS)),1,0)
|
||||
SOUNDDEFS += -DHAS_OKIM6376=$(if $(filter OKIM6376,$(SOUNDS)),1,0)
|
||||
SOUNDDEFS += -DHAS_OKIM6295=$(if $(filter OKIM6295,$(SOUNDS)),1,0)
|
||||
SOUNDDEFS += -DHAS_OKIM6258=$(if $(filter OKIM6258,$(SOUNDS)),1,0)
|
||||
|
||||
@ -376,6 +377,10 @@ ifneq ($(filter MSM5232,$(SOUNDS)),)
|
||||
SOUNDOBJS += $(SOUNDOBJ)/msm5232.o
|
||||
endif
|
||||
|
||||
ifneq ($(filter OKIM6376,$(SOUNDS)),)
|
||||
SOUNDOBJS += $(SOUNDOBJ)/okim6376.o
|
||||
endif
|
||||
|
||||
ifneq ($(filter OKIM6295,$(SOUNDS)),)
|
||||
SOUNDOBJS += $(SOUNDOBJ)/okim6295.o
|
||||
endif
|
||||
|
@ -24,6 +24,7 @@ TODO:
|
||||
#include "driver.h"
|
||||
#include "cpu/nec/nec.h"
|
||||
#include "cpu/i86/i86.h"
|
||||
#include "sound/okim6376.h"
|
||||
#include "fashion.lh"
|
||||
|
||||
static UINT16 *blit_ram;
|
||||
@ -275,7 +276,11 @@ static WRITE16_HANDLER( fashion_write2_w )
|
||||
|
||||
static WRITE16_HANDLER( write3_w )
|
||||
{
|
||||
t3 = data;
|
||||
if (t3 != data) {
|
||||
t3 = data;
|
||||
okim6376_data_0_lsb_w(space, 0, t3, mem_mask);
|
||||
okim6376_data_0_lsb_w(space, 0, (1 << 4), mem_mask);
|
||||
}
|
||||
// popmessage("%04x %04x",t1,t3);
|
||||
}
|
||||
|
||||
@ -588,7 +593,13 @@ static MACHINE_DRIVER_START( brasil )
|
||||
MDRV_VIDEO_START(brasil)
|
||||
MDRV_VIDEO_UPDATE(brasil)
|
||||
|
||||
/* sound hardware */
|
||||
MDRV_SPEAKER_STANDARD_MONO("mono")
|
||||
|
||||
//OkiM6376
|
||||
MDRV_SOUND_ADD("samples", OKIM6376, XTAL_12MHz/2/2)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
|
||||
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
|
||||
@ -610,7 +621,13 @@ static MACHINE_DRIVER_START( vidpokr2 )
|
||||
MDRV_VIDEO_START(brasil)
|
||||
MDRV_VIDEO_UPDATE(vidpokr2)
|
||||
|
||||
/* sound hardware */
|
||||
MDRV_SPEAKER_STANDARD_MONO("mono")
|
||||
|
||||
//OkiM6376
|
||||
MDRV_SOUND_ADD("samples", OKIM6376, XTAL_12MHz/2/2)
|
||||
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
|
||||
|
||||
MACHINE_DRIVER_END
|
||||
|
||||
/*
|
||||
@ -709,6 +726,6 @@ static DRIVER_INIT( fashion )
|
||||
memory_install_write16_handler(cpu_get_address_space(machine->cpu[0], ADDRESS_SPACE_IO), 0x0002, 0x0003, 0, 0, fashion_write2_w );
|
||||
}
|
||||
|
||||
GAMEL( 19??, newmcard, 0, vidpokr2, brasil, 0, ROT0, "New High Video?", "New Magic Card", GAME_NO_SOUND, layout_fashion )
|
||||
GAMEL( 2000, brasil, 0, brasil, brasil, 0, ROT0, "New High Video?", "Bra$il (Version 3)", GAME_IMPERFECT_GRAPHICS | GAME_NO_SOUND, layout_fashion )
|
||||
GAMEL( 2000, fashion, brasil, brasil, fashion, fashion, ROT0, "New High Video?", "Fashion (Version 2.14)", GAME_IMPERFECT_GRAPHICS | GAME_NO_SOUND, layout_fashion )
|
||||
GAMEL( 19??, newmcard, 0, vidpokr2, brasil, 0, ROT0, "New High Video?", "New Magic Card", 0, layout_fashion )
|
||||
GAMEL( 2000, brasil, 0, brasil, brasil, 0, ROT0, "New High Video?", "Bra$il (Version 3)", GAME_IMPERFECT_GRAPHICS, layout_fashion )
|
||||
GAMEL( 2000, fashion, brasil, brasil, fashion, fashion, ROT0, "New High Video?", "Fashion (Version 2.14)", GAME_IMPERFECT_GRAPHICS, layout_fashion )
|
||||
|
@ -274,6 +274,7 @@ SOUNDS += MSM5205
|
||||
SOUNDS += MSM5232
|
||||
SOUNDS += OKIM6258
|
||||
SOUNDS += OKIM6295
|
||||
SOUNDS += OKIM6376
|
||||
SOUNDS += UPD7759
|
||||
SOUNDS += HC55516
|
||||
SOUNDS += K005289
|
||||
|
Loading…
Reference in New Issue
Block a user