added minimal support for MSM6585

This commit is contained in:
Michaël Banaan Ananas 2012-07-29 18:16:45 +00:00
parent 2a92957014
commit bfa4f38f05
6 changed files with 67 additions and 43 deletions

View File

@ -25,6 +25,11 @@
*
* A reset signal is set high or low to determine whether playback (and interrupts) are occuring
*
*
* TODO:
* - convert to modern
* - lowpass filter for MSM6585
*
*/
typedef struct _msm5205_state msm5205_state;
@ -32,9 +37,9 @@ struct _msm5205_state
{
const msm5205_interface *intf;
device_t *device;
sound_stream * stream; /* number of stream system */
INT32 clock; /* clock rate */
emu_timer *timer; /* VCLK callback timer */
sound_stream * stream; /* number of stream system */
INT32 clock; /* clock rate */
emu_timer *timer; /* VCLK callback timer */
INT32 data; /* next adpcm data */
INT32 vclk; /* vclk signal (external mode) */
INT32 reset; /* reset pin signal */
@ -56,7 +61,7 @@ INLINE msm5205_state *get_safe_token(device_t *device)
static void msm5205_playmode(msm5205_state *voice,int select);
/*
* ADPCM lockup tabe
* ADPCM lookup table
*/
/* step size index shift table */
@ -117,16 +122,17 @@ static STREAM_UPDATE( MSM5205_update )
memset (buffer,0,samples*sizeof(*buffer));
}
/* timer callback at VCLK low eddge */
/* timer callback at VCLK low edge on MSM5205 (at rising edge on MSM6585) */
static TIMER_CALLBACK( MSM5205_vclk_callback )
{
msm5205_state *voice = (msm5205_state *)ptr;
int val;
int new_signal;
/* callback user handler and latch next data */
if(voice->intf->vclk_callback) (*voice->intf->vclk_callback)(voice->device);
/* reset check at last hieddge of VCLK */
/* reset check at last hiedge of VCLK */
if(voice->reset)
{
new_signal = 0;
@ -144,6 +150,7 @@ static TIMER_CALLBACK( MSM5205_vclk_callback )
if (voice->step > 48) voice->step = 48;
else if (voice->step < 0) voice->step = 0;
}
/* update when signal changed */
if( voice->signal != new_signal)
{
@ -165,6 +172,7 @@ static DEVICE_RESET( msm5205 )
voice->reset = 0;
voice->signal = 0;
voice->step = 0;
/* timer and bitwidth set */
msm5205_playmode(voice,voice->intf->select);
}
@ -250,19 +258,23 @@ void msm5205_data_w (device_t *device, int data)
}
/*
* Handle an change of the selector
* Handle a change of the selector
*/
void msm5205_playmode_w(device_t *device, int select)
{
msm5205_state *voice = get_safe_token(device);
msm5205_playmode(voice,select);
msm5205_playmode(voice, select);
}
static void msm5205_playmode(msm5205_state *voice,int select)
static void msm5205_playmode(msm5205_state *voice, int select)
{
static const int prescaler_table[4] = {96,48,64,0};
int prescaler = prescaler_table[select & 3];
static const int prescaler_table[2][4] =
{
{ 96, 48, 64, 0},
{160, 40, 80, 20}
};
int prescaler = prescaler_table[select >> 3 & 1][select & 3];
int bitwidth = (select & 4) ? 4 : 3;
@ -271,6 +283,7 @@ static void msm5205_playmode(msm5205_state *voice,int select)
voice->stream->update();
voice->prescaler = prescaler;
/* timer set */
if( prescaler )
{
@ -318,21 +331,31 @@ DEVICE_GET_INFO( msm5205 )
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(msm5205_state); break;
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(msm5205_state); break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( msm5205 ); break;
case DEVINFO_FCT_STOP: /* nothing */ break;
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME( msm5205 ); break;
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( msm5205 ); break;
case DEVINFO_FCT_STOP: /* nothing */ break;
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME( msm5205 ); break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: strcpy(info->s, "MSM5205"); break;
case DEVINFO_STR_NAME: strcpy(info->s, "MSM5205"); break;
case DEVINFO_STR_FAMILY: strcpy(info->s, "ADPCM"); break;
case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
}
}
DEVICE_GET_INFO( msm6585 )
{
switch (state)
{
case DEVINFO_STR_NAME: strcpy(info->s, "MSM6585"); break;
default: DEVICE_GET_INFO_CALL(msm5205); break;
}
}
DEFINE_LEGACY_SOUND_DEVICE(MSM5205, msm5205);
DEFINE_LEGACY_SOUND_DEVICE(MSM6585, msm6585);

View File

@ -8,7 +8,7 @@
/* an interface for the MSM5205 and similar chips */
/* prescaler selector defines */
/* default master clock is 384KHz */
/* MSM5205 default master clock is 384KHz */
#define MSM5205_S96_3B 0 /* prescaler 1/96(4KHz) , data 3bit */
#define MSM5205_S48_3B 1 /* prescaler 1/48(8KHz) , data 3bit */
#define MSM5205_S64_3B 2 /* prescaler 1/64(6KHz) , data 3bit */
@ -18,6 +18,12 @@
#define MSM5205_S64_4B 6 /* prescaler 1/64(6KHz) , data 4bit */
#define MSM5205_SEX_4B 7 /* VCLK slave mode , data 4bit */
/* MSM6585 default master clock is 640KHz */
#define MSM6585_S160 (4+8) /* prescaler 1/160(4KHz), data 4bit */
#define MSM6585_S40 (5+8) /* prescaler 1/40(16KHz), data 4bit */
#define MSM6585_S80 (6+8) /* prescaler 1/80 (8KHz), data 4bit */
#define MSM6585_S20 (7+8) /* prescaler 1/20(32KHz), data 4bit */
typedef struct _msm5205_interface msm5205_interface;
struct _msm5205_interface
{
@ -41,5 +47,6 @@ void msm5205_set_volume(device_t *device,int volume);
void msm5205_change_clock_w(device_t *device, INT32 clock);
DECLARE_LEGACY_SOUND_DEVICE(MSM5205, msm5205);
DECLARE_LEGACY_SOUND_DEVICE(MSM6585, msm6585);
#endif /* __MSM5205_H__ */

View File

@ -383,7 +383,7 @@ ifneq ($(filter OKIM6258 OKIM6295 OKIM9810 I5000_SND,$(SOUNDS)),)
SOUNDOBJS += $(SOUNDOBJ)/okiadpcm.o
endif
ifneq ($(filter MSM5205,$(SOUNDS)),)
ifneq ($(filter MSM5205 MSM6585,$(SOUNDS)),)
SOUNDOBJS += $(SOUNDOBJ)/msm5205.o
endif

View File

@ -28,16 +28,6 @@ BGMs (controlled by OKI MSM6585 sound chip)
Built in low-pass filter
Expanded sampling frequency
Differences between MSM6585 & MSM5205:
MSM6586 MSM5205
Master clock frequency 640kHz 384kHz
Sampling frequency 4k/8k/16k/32kHz 4k/6k/8kHz
ADPCM bit length 4-bit 3-bit/4-bit
DA converter 12-bit 10-bit
Low-pass filter -40dB/oct N/A
Overflow prevent circuit Included N/A
Stephh's notes (based on the game M68000 code and some tests) :
- Reset the game while pressing START1 to enter the "test mode"
@ -395,10 +385,10 @@ GFXDECODE_END
(SOUND)
**************************************************************/
static const msm5205_interface msm5205_config =
static const msm5205_interface msm6585_config =
{
gcp_adpcm_int, /* VCK function */
MSM5205_S48_4B /* 8 kHz */
MSM6585_S40 /* 16 kHz */
};
/***********************************************************
@ -475,8 +465,8 @@ static MACHINE_CONFIG_START( gcpinbal, gcpinbal_state )
MCFG_OKIM6295_ADD("oki", 1056000, OKIM6295_PIN7_HIGH)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.30)
MCFG_SOUND_ADD("msm", MSM5205, 384000) /* Actually an OKI MSM6585 @ 640kHz */
MCFG_SOUND_CONFIG(msm5205_config)
MCFG_SOUND_ADD("msm", MSM6585, XTAL_640kHz)
MCFG_SOUND_CONFIG(msm6585_config)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_CONFIG_END

View File

@ -68,6 +68,8 @@ It has Sega and Taito logos in the roms ?!
ES8712 sound may not be quite right. Samples are currently looped, but
whether they should and how, is unknown.
where does the M6585 hook up to?
cleanup
@ -84,11 +86,12 @@ class vmetal_state : public metro_state
public:
vmetal_state(const machine_config &mconfig, device_type type, const char *tag)
: metro_state(mconfig, type, tag),
m_texttileram(*this, "texttileram"),
m_mid1tileram(*this, "mid1tileram"),
m_mid2tileram(*this, "mid2tileram"),
m_tlookup(*this, "tlookup"),
m_vmetal_videoregs(*this, "vmetal_regs") { }
m_texttileram(*this, "texttileram"),
m_mid1tileram(*this, "mid1tileram"),
m_mid2tileram(*this, "mid2tileram"),
m_tlookup(*this, "tlookup"),
m_vmetal_videoregs(*this, "vmetal_regs")
{ }
required_shared_ptr<UINT16> m_texttileram;
required_shared_ptr<UINT16> m_mid1tileram;

View File

@ -7,17 +7,18 @@ class gcpinbal_state : public driver_device
public:
gcpinbal_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_oki(*this, "oki"),
m_msm(*this, "msm") ,
m_maincpu(*this, "maincpu"),
m_oki(*this, "oki"),
m_msm(*this, "msm"),
m_tilemapram(*this, "tilemapram"),
m_spriteram(*this, "spriteram"),
m_ioc_ram(*this, "ioc_ram"){ }
m_ioc_ram(*this, "ioc_ram")
{ }
/* devices */
required_device<cpu_device> m_maincpu;
required_device<okim6295_device> m_oki;
required_device<msm5205_device> m_msm;
required_device<msm6585_device> m_msm;
/* memory pointers */
required_shared_ptr<UINT16> m_tilemapram;