Modernized the vlm5030 speech synthesizer chip. [Osso]

This commit is contained in:
Scott Stone 2013-07-16 18:11:54 +00:00
parent 1432dfec7f
commit 82399c7d11
22 changed files with 570 additions and 563 deletions

View File

@ -109,7 +109,6 @@ chirp 12-..: vokume 0 : silent
*/
#include "emu.h"
#include "vlm5030.h"
#include "devlegcy.h"
/* interpolator per frame */
#define FR_SIZE 4
@ -120,58 +119,6 @@ chirp 12-..: vokume 0 : silent
#define IP_SIZE_FAST (120/FR_SIZE)
#define IP_SIZE_FASTER ( 80/FR_SIZE)
struct vlm5030_state
{
device_t *device;
const vlm5030_interface *intf;
sound_stream * channel;
/* coefficient tables */
const struct tms5100_coeffs *coeff;
/* need to save state */
UINT8 *rom;
int address_mask;
UINT16 address;
UINT8 pin_BSY;
UINT8 pin_ST;
UINT8 pin_VCU;
UINT8 pin_RST;
UINT8 latch_data;
UINT16 vcu_addr_h;
UINT8 parameter;
UINT8 phase;
/* state of option paramter */
int frame_size;
int pitch_offset;
UINT8 interp_step;
UINT8 interp_count; /* number of interp periods */
UINT8 sample_count; /* sample number within interp */
UINT8 pitch_count;
/* these contain data describing the current and previous voice frames */
UINT16 old_energy;
UINT8 old_pitch;
INT16 old_k[10];
UINT16 target_energy;
UINT8 target_pitch;
INT16 target_k[10];
UINT16 new_energy;
UINT8 new_pitch;
INT16 new_k[10];
/* these are all used to contain the current state of the sound generation */
unsigned int current_energy;
unsigned int current_pitch;
int current_k[10];
INT32 x[10];
};
/* phase value */
enum {
@ -208,22 +155,149 @@ static const int vlm5030_speed_table[8] =
IP_SIZE_SLOW
};
static const char VLM_NAME[] = "VLM5030";
const device_type VLM5030 = &device_creator<vlm5030_device>;
INLINE vlm5030_state *get_safe_token(device_t *device)
vlm5030_device::vlm5030_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, VLM5030, "VLM5030", tag, owner, clock, "vlm5030", __FILE__),
device_sound_interface(mconfig, *this),
m_channel(NULL),
m_coeff(NULL),
m_rom(NULL),
m_address_mask(0),
m_address(0),
m_pin_BSY(0),
m_pin_ST(0),
m_pin_VCU(0),
m_pin_RST(0),
m_latch_data(0),
m_vcu_addr_h(0),
m_parameter(0),
m_phase(PH_RESET),
m_frame_size(0),
m_pitch_offset(0),
m_interp_step(0),
m_interp_count(0),
m_sample_count(0),
m_pitch_count(0),
m_old_energy(0),
m_old_pitch(0),
m_target_energy(0),
m_target_pitch(0),
m_new_energy(0),
m_new_pitch(0),
m_current_energy(0),
m_current_pitch(0)
{
assert(device != NULL);
assert(device->type() == VLM5030);
return (vlm5030_state *)downcast<vlm5030_device *>(device)->token();
memset(m_old_k, 0, sizeof(m_old_k));
memset(m_new_k, 0, sizeof(m_new_k));
memset(m_current_k, 0, sizeof(m_current_k));
memset(m_target_k, 0, sizeof(m_target_k));
memset(m_x, 0, sizeof(m_x));
}
static int get_bits(vlm5030_state *chip, int sbit,int bits)
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void vlm5030_device::device_config_complete()
{
int offset = chip->address + (sbit>>3);
// inherit a copy of the static data
const vlm5030_interface *intf = reinterpret_cast<const vlm5030_interface *>(static_config());
if (intf != NULL)
*static_cast<vlm5030_interface *>(this) = *intf;
// or initialize to defaults if none provided
else
{
m_memory_size = 0;
}
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
/* start VLM5030 with sound rom */
/* speech_rom == 0 -> use sampling data mode */
void vlm5030_device::device_start()
{
m_coeff = &vlm5030_coeff;
/* reset input pins */
m_pin_RST = m_pin_ST = m_pin_VCU= 0;
m_latch_data = 0;
device_reset();
m_phase = PH_IDLE;
m_rom = *region();
/* memory size */
if( m_memory_size == 0)
m_address_mask = region()->bytes()-1;
else
m_address_mask = m_memory_size-1;
m_channel = machine().sound().stream_alloc(*this, 0, 1, clock() / 440, this);
/* don't restore "UINT8 *m_rom" when use vlm5030_set_rom() */
save_item(NAME(m_address));
save_item(NAME(m_pin_BSY));
save_item(NAME(m_pin_ST));
save_item(NAME(m_pin_VCU));
save_item(NAME(m_pin_RST));
save_item(NAME(m_latch_data));
save_item(NAME(m_vcu_addr_h));
save_item(NAME(m_parameter));
save_item(NAME(m_phase));
save_item(NAME(m_interp_count));
save_item(NAME(m_sample_count));
save_item(NAME(m_pitch_count));
save_item(NAME(m_old_energy));
save_item(NAME(m_old_pitch));
save_item(NAME(m_old_k));
save_item(NAME(m_target_energy));
save_item(NAME(m_target_pitch));
save_item(NAME(m_target_k));
save_item(NAME(m_x));
machine().save().register_postload(save_prepost_delegate(FUNC(vlm5030_device::restore_state), this));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void vlm5030_device::device_reset()
{
m_phase = PH_RESET;
m_address = 0;
m_vcu_addr_h = 0;
m_pin_BSY = 0;
m_old_energy = m_old_pitch = 0;
m_new_energy = m_new_pitch = 0;
m_current_energy = m_current_pitch = 0;
m_target_energy = m_target_pitch = 0;
memset(m_old_k, 0, sizeof(m_old_k));
memset(m_new_k, 0, sizeof(m_new_k));
memset(m_current_k, 0, sizeof(m_current_k));
memset(m_target_k, 0, sizeof(m_target_k));
m_interp_count = m_sample_count = m_pitch_count = 0;
memset(m_x, 0, sizeof(m_x));
/* reset parameters */
setup_parameter( 0x00);
}
int vlm5030_device::get_bits(int sbit,int bits)
{
int offset = m_address + (sbit>>3);
int data;
data = chip->rom[offset&chip->address_mask] +
(((int)chip->rom[(offset+1)&chip->address_mask])*256);
data = m_rom[offset&m_address_mask] +
(((int)m_rom[(offset+1)&m_address_mask])*256);
data >>= (sbit&7);
data &= (0xff>>(8-bits));
@ -231,65 +305,225 @@ static int get_bits(vlm5030_state *chip, int sbit,int bits)
}
/* get next frame */
static int parse_frame (vlm5030_state *chip)
int vlm5030_device::parse_frame()
{
unsigned char cmd;
int i;
/* remember previous frame */
chip->old_energy = chip->new_energy;
chip->old_pitch = chip->new_pitch;
m_old_energy = m_new_energy;
m_old_pitch = m_new_pitch;
for(i=0;i<=9;i++)
chip->old_k[i] = chip->new_k[i];
m_old_k[i] = m_new_k[i];
/* command byte check */
cmd = chip->rom[chip->address&chip->address_mask];
cmd = m_rom[m_address&m_address_mask];
if( cmd & 0x01 )
{ /* extend frame */
chip->new_energy = chip->new_pitch = 0;
m_new_energy = m_new_pitch = 0;
for(i=0;i<=9;i++)
chip->new_k[i] = 0;
chip->address++;
m_new_k[i] = 0;
m_address++;
if( cmd & 0x02 )
{ /* end of speech */
/* logerror("VLM5030 %04X end \n",chip->address ); */
/* logerror("VLM5030 %04X end \n",m_address ); */
return 0;
}
else
{ /* silent frame */
int nums = ( (cmd>>2)+1 )*2;
/* logerror("VLM5030 %04X silent %d frame\n",chip->address,nums ); */
/* logerror("VLM5030 %04X silent %d frame\n",m_address,nums ); */
return nums * FR_SIZE;
}
}
/* pitch */
chip->new_pitch = ( chip->coeff->pitchtable[get_bits(chip, 1,chip->coeff->pitch_bits)] + chip->pitch_offset )&0xff;
m_new_pitch = ( m_coeff->pitchtable[get_bits(1,m_coeff->pitch_bits)] + m_pitch_offset )&0xff;
/* energy */
chip->new_energy = chip->coeff->energytable[get_bits(chip, 6,chip->coeff->energy_bits)];
m_new_energy = m_coeff->energytable[get_bits(6,m_coeff->energy_bits)];
/* 10 K's */
chip->new_k[9] = chip->coeff->ktable[9][get_bits(chip,11,chip->coeff->kbits[9])];
chip->new_k[8] = chip->coeff->ktable[8][get_bits(chip,14,chip->coeff->kbits[8])];
chip->new_k[7] = chip->coeff->ktable[7][get_bits(chip,17,chip->coeff->kbits[7])];
chip->new_k[6] = chip->coeff->ktable[6][get_bits(chip,20,chip->coeff->kbits[6])];
chip->new_k[5] = chip->coeff->ktable[5][get_bits(chip,23,chip->coeff->kbits[5])];
chip->new_k[4] = chip->coeff->ktable[4][get_bits(chip,26,chip->coeff->kbits[4])];
chip->new_k[3] = chip->coeff->ktable[3][get_bits(chip,29,chip->coeff->kbits[3])];
chip->new_k[2] = chip->coeff->ktable[2][get_bits(chip,33,chip->coeff->kbits[2])];
chip->new_k[1] = chip->coeff->ktable[1][get_bits(chip,37,chip->coeff->kbits[1])];
chip->new_k[0] = chip->coeff->ktable[0][get_bits(chip,42,chip->coeff->kbits[0])];
m_new_k[9] = m_coeff->ktable[9][get_bits(11,m_coeff->kbits[9])];
m_new_k[8] = m_coeff->ktable[8][get_bits(14,m_coeff->kbits[8])];
m_new_k[7] = m_coeff->ktable[7][get_bits(17,m_coeff->kbits[7])];
m_new_k[6] = m_coeff->ktable[6][get_bits(20,m_coeff->kbits[6])];
m_new_k[5] = m_coeff->ktable[5][get_bits(23,m_coeff->kbits[5])];
m_new_k[4] = m_coeff->ktable[4][get_bits(26,m_coeff->kbits[4])];
m_new_k[3] = m_coeff->ktable[3][get_bits(29,m_coeff->kbits[3])];
m_new_k[2] = m_coeff->ktable[2][get_bits(33,m_coeff->kbits[2])];
m_new_k[1] = m_coeff->ktable[1][get_bits(37,m_coeff->kbits[1])];
m_new_k[0] = m_coeff->ktable[0][get_bits(42,m_coeff->kbits[0])];
chip->address+=6;
logerror("VLM5030 %04X voice \n",chip->address );
//fprintf(stderr,"*** target Energy, Pitch, and Ks = %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",chip->new_energy, chip->new_pitch, chip->new_k[0], chip->new_k[1], chip->new_k[2], chip->new_k[3], chip->new_k[4], chip->new_k[5], chip->new_k[6], chip->new_k[7], chip->new_k[8], chip->new_k[9]);
m_address+=6;
logerror("VLM5030 %04X voice \n",m_address );
//fprintf(stderr,"*** target Energy, Pitch, and Ks = %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_new_energy, m_new_pitch, m_new_k[0], m_new_k[1], m_new_k[2], m_new_k[3], m_new_k[4], m_new_k[5], m_new_k[6], m_new_k[7], m_new_k[8], m_new_k[9]);
return FR_SIZE;
}
/* decode and buffering data */
static STREAM_UPDATE( vlm5030_update_callback )
/* realtime update */
void vlm5030_device::update()
{
m_channel->update();
}
/* setup parameteroption when RST=H */
void vlm5030_device::setup_parameter(UINT8 param)
{
/* latch parameter value */
m_parameter = param;
/* bit 0,1 : 4800bps / 9600bps , interporator step */
if(param&2) /* bit 1 = 1 , 9600bps */
m_interp_step = 4; /* 9600bps : no interporator */
else if(param&1) /* bit1 = 0 & bit0 = 1 , 4800bps */
m_interp_step = 2; /* 4800bps : 2 interporator */
else /* bit1 = bit0 = 0 : 2400bps */
m_interp_step = 1; /* 2400bps : 4 interporator */
/* bit 3,4,5 : speed (frame size) */
m_frame_size = vlm5030_speed_table[(param>>3) &7];
/* bit 6,7 : low / high pitch */
if(param&0x80) /* bit7=1 , high pitch */
m_pitch_offset = -8;
else if(param&0x40) /* bit6=1 , low pitch */
m_pitch_offset = 8;
else
m_pitch_offset = 0;
}
void vlm5030_device::restore_state()
{
int i;
int interp_effect = FR_SIZE - (m_interp_count%FR_SIZE);
/* restore parameter data */
setup_parameter( m_parameter);
/* restore current energy,pitch & filter */
m_current_energy = m_old_energy + (m_target_energy - m_old_energy) * interp_effect / FR_SIZE;
if (m_old_pitch > 1)
m_current_pitch = m_old_pitch + (m_target_pitch - m_old_pitch) * interp_effect / FR_SIZE;
for (i = 0; i <= 9 ; i++)
m_current_k[i] = m_old_k[i] + (m_target_k[i] - m_old_k[i]) * interp_effect / FR_SIZE;
}
/* set speech rom address */
void vlm5030_device::set_rom(void *speech_rom)
{
m_rom = (UINT8 *)speech_rom;
}
/* get BSY pin level */
int vlm5030_device::bsy()
{
update();
return m_pin_BSY;
}
/* latch contoll data */
WRITE8_MEMBER( vlm5030_device::data_w )
{
m_latch_data = (UINT8)data;
}
/* set RST pin level : reset / set table address A8-A15 */
void vlm5030_device::rst ( int pin )
{
if( m_pin_RST )
{
if( !pin )
{ /* H -> L : latch parameters */
m_pin_RST = 0;
setup_parameter( m_latch_data);
}
}
else
{
if( pin )
{ /* L -> H : reset chip */
m_pin_RST = 1;
if( m_pin_BSY )
{
device_reset();
}
}
}
}
/* set VCU pin level : ?? unknown */
void vlm5030_device::vcu(int pin)
{
/* direct mode / indirect mode */
m_pin_VCU = pin;
return;
}
/* set ST pin level : set table address A0-A7 / start speech */
void vlm5030_device::st( int pin )
{
int table;
if( m_pin_ST != pin )
{
/* pin level is change */
if( !pin )
{ /* H -> L */
m_pin_ST = 0;
if( m_pin_VCU )
{ /* direct access mode & address High */
m_vcu_addr_h = ((int)m_latch_data<<8) + 0x01;
}
else
{
/* start speech */
/* check access mode */
if( m_vcu_addr_h )
{ /* direct access mode */
m_address = (m_vcu_addr_h&0xff00) + m_latch_data;
m_vcu_addr_h = 0;
}
else
{ /* indirect accedd mode */
table = (m_latch_data&0xfe) + (((int)m_latch_data&1)<<8);
m_address = (((int)m_rom[table&m_address_mask])<<8)
| m_rom[(table+1)&m_address_mask];
#if 0
/* show unsupported parameter message */
if( m_interp_step != 1)
popmessage("No %d %dBPS parameter",table/2,m_interp_step*2400);
#endif
}
update();
/* logerror("VLM5030 %02X start adr=%04X\n",table/2,m_address ); */
/* reset process status */
m_sample_count = m_frame_size;
m_interp_count = FR_SIZE;
/* clear filter */
/* start after 3 sampling cycle */
m_phase = PH_RUN;
}
}
else
{ /* L -> H */
m_pin_ST = 1;
/* setup speech , BSY on after 30ms? */
m_phase = PH_SETUP;
m_sample_count = 1; /* wait time for busy on */
m_pin_BSY = 1; /* */
}
}
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
void vlm5030_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
vlm5030_state *chip = (vlm5030_state *)param;
int buf_count=0;
int interp_effect;
int i;
@ -297,7 +531,7 @@ static STREAM_UPDATE( vlm5030_update_callback )
stream_sample_t *buffer = outputs[0];
/* running */
if( chip->phase == PH_RUN || chip->phase == PH_STOP )
if( m_phase == PH_RUN || m_phase == PH_STOP )
{
/* playing speech */
while (samples > 0)
@ -305,85 +539,85 @@ static STREAM_UPDATE( vlm5030_update_callback )
int current_val;
/* check new interpolator or new frame */
if( chip->sample_count == 0 )
if( m_sample_count == 0 )
{
if( chip->phase == PH_STOP )
if( m_phase == PH_STOP )
{
chip->phase = PH_END;
chip->sample_count = 1;
m_phase = PH_END;
m_sample_count = 1;
goto phase_stop; /* continue to end phase */
}
chip->sample_count = chip->frame_size;
m_sample_count = m_frame_size;
/* interpolator changes */
if ( chip->interp_count == 0 )
if ( m_interp_count == 0 )
{
/* change to new frame */
chip->interp_count = parse_frame(chip); /* with change phase */
if ( chip->interp_count == 0 )
m_interp_count = parse_frame(); /* with change phase */
if ( m_interp_count == 0 )
{ /* end mark found */
chip->interp_count = FR_SIZE;
chip->sample_count = chip->frame_size; /* end -> stop time */
chip->phase = PH_STOP;
m_interp_count = FR_SIZE;
m_sample_count = m_frame_size; /* end -> stop time */
m_phase = PH_STOP;
}
/* Set old target as new start of frame */
chip->current_energy = chip->old_energy;
chip->current_pitch = chip->old_pitch;
m_current_energy = m_old_energy;
m_current_pitch = m_old_pitch;
for(i=0;i<=9;i++)
chip->current_k[i] = chip->old_k[i];
m_current_k[i] = m_old_k[i];
/* is this a zero energy frame? */
if (chip->current_energy == 0)
if (m_current_energy == 0)
{
/*mame_printf_debug("processing frame: zero energy\n");*/
chip->target_energy = 0;
chip->target_pitch = chip->current_pitch;
m_target_energy = 0;
m_target_pitch = m_current_pitch;
for(i=0;i<=9;i++)
chip->target_k[i] = chip->current_k[i];
m_target_k[i] = m_current_k[i];
}
else
{
/*mame_printf_debug("processing frame: Normal\n");*/
/*mame_printf_debug("*** Energy = %d\n",chip->current_energy);*/
/*mame_printf_debug("*** Energy = %d\n",m_current_energy);*/
/*mame_printf_debug("proc: %d %d\n",last_fbuf_head,fbuf_head);*/
chip->target_energy = chip->new_energy;
chip->target_pitch = chip->new_pitch;
m_target_energy = m_new_energy;
m_target_pitch = m_new_pitch;
for(i=0;i<=9;i++)
chip->target_k[i] = chip->new_k[i];
m_target_k[i] = m_new_k[i];
}
}
/* next interpolator */
/* Update values based on step values 25% , 50% , 75% , 100% */
chip->interp_count -= chip->interp_step;
m_interp_count -= m_interp_step;
/* 3,2,1,0 -> 1,2,3,4 */
interp_effect = FR_SIZE - (chip->interp_count%FR_SIZE);
chip->current_energy = chip->old_energy + (chip->target_energy - chip->old_energy) * interp_effect / FR_SIZE;
if (chip->old_pitch > 1)
chip->current_pitch = chip->old_pitch + (chip->target_pitch - chip->old_pitch) * interp_effect / FR_SIZE;
interp_effect = FR_SIZE - (m_interp_count%FR_SIZE);
m_current_energy = m_old_energy + (m_target_energy - m_old_energy) * interp_effect / FR_SIZE;
if (m_old_pitch > 1)
m_current_pitch = m_old_pitch + (m_target_pitch - m_old_pitch) * interp_effect / FR_SIZE;
for (i = 0; i <= 9 ; i++)
chip->current_k[i] = chip->old_k[i] + (chip->target_k[i] - chip->old_k[i]) * interp_effect / FR_SIZE;
m_current_k[i] = m_old_k[i] + (m_target_k[i] - m_old_k[i]) * interp_effect / FR_SIZE;
}
/* calcrate digital filter */
if (chip->old_energy == 0)
if (m_old_energy == 0)
{
/* generate silent samples here */
current_val = 0x00;
}
else if (chip->old_pitch <= 1)
else if (m_old_pitch <= 1)
{ /* generate unvoiced samples here */
current_val = (chip->device->machine().rand()&1) ? chip->current_energy : -chip->current_energy;
current_val = (machine().rand()&1) ? m_current_energy : -m_current_energy;
}
else
{
/* generate voiced samples here */
current_val = ( chip->pitch_count == 0) ? chip->current_energy : 0;
current_val = ( m_pitch_count == 0) ? m_current_energy : 0;
}
/* Lattice filter here */
u[10] = current_val;
for (i = 9; i >= 0; i--)
u[i] = u[i+1] - ((-chip->current_k[i] * chip->x[i]) / 512);
u[i] = u[i+1] - ((-m_current_k[i] * m_x[i]) / 512);
for (i = 9; i >= 1; i--)
chip->x[i] = chip->x[i-1] + ((-chip->current_k[i-1] * u[i-1]) / 512);
chip->x[0] = u[0];
m_x[i] = m_x[i-1] + ((-m_current_k[i-1] * u[i-1]) / 512);
m_x[0] = u[0];
/* clipping, buffering */
if (u[0] > 511)
@ -395,11 +629,11 @@ static STREAM_UPDATE( vlm5030_update_callback )
buf_count++;
/* sample count */
chip->sample_count--;
m_sample_count--;
/* pitch */
chip->pitch_count++;
if (chip->pitch_count >= chip->current_pitch )
chip->pitch_count = 0;
m_pitch_count++;
if (m_pitch_count >= m_current_pitch )
m_pitch_count = 0;
/* size */
samples--;
}
@ -407,32 +641,32 @@ static STREAM_UPDATE( vlm5030_update_callback )
}
/* stop phase */
phase_stop:
switch( chip->phase )
switch( m_phase )
{
case PH_SETUP:
if( chip->sample_count <= samples)
if( m_sample_count <= samples)
{
chip->sample_count = 0;
m_sample_count = 0;
/* logerror("VLM5030 BSY=H\n" ); */
/* pin_BSY = 1; */
chip->phase = PH_WAIT;
m_phase = PH_WAIT;
}
else
{
chip->sample_count -= samples;
m_sample_count -= samples;
}
break;
case PH_END:
if( chip->sample_count <= samples)
if( m_sample_count <= samples)
{
chip->sample_count = 0;
m_sample_count = 0;
/* logerror("VLM5030 BSY=L\n" ); */
chip->pin_BSY = 0;
chip->phase = PH_IDLE;
m_pin_BSY = 0;
m_phase = PH_IDLE;
}
else
{
chip->sample_count -= samples;
m_sample_count -= samples;
}
}
/* silent buffering */
@ -442,295 +676,3 @@ phase_stop:
samples--;
}
}
/* realtime update */
static void vlm5030_update(vlm5030_state *chip)
{
chip->channel->update();
}
/* setup parameteroption when RST=H */
static void vlm5030_setup_parameter(vlm5030_state *chip, UINT8 param)
{
/* latch parameter value */
chip->parameter = param;
/* bit 0,1 : 4800bps / 9600bps , interporator step */
if(param&2) /* bit 1 = 1 , 9600bps */
chip->interp_step = 4; /* 9600bps : no interporator */
else if(param&1) /* bit1 = 0 & bit0 = 1 , 4800bps */
chip->interp_step = 2; /* 4800bps : 2 interporator */
else /* bit1 = bit0 = 0 : 2400bps */
chip->interp_step = 1; /* 2400bps : 4 interporator */
/* bit 3,4,5 : speed (frame size) */
chip->frame_size = vlm5030_speed_table[(param>>3) &7];
/* bit 6,7 : low / high pitch */
if(param&0x80) /* bit7=1 , high pitch */
chip->pitch_offset = -8;
else if(param&0x40) /* bit6=1 , low pitch */
chip->pitch_offset = 8;
else
chip->pitch_offset = 0;
}
static void vlm5030_restore_state(vlm5030_state *chip)
{
int i;
int interp_effect = FR_SIZE - (chip->interp_count%FR_SIZE);
/* restore parameter data */
vlm5030_setup_parameter(chip, chip->parameter);
/* restore current energy,pitch & filter */
chip->current_energy = chip->old_energy + (chip->target_energy - chip->old_energy) * interp_effect / FR_SIZE;
if (chip->old_pitch > 1)
chip->current_pitch = chip->old_pitch + (chip->target_pitch - chip->old_pitch) * interp_effect / FR_SIZE;
for (i = 0; i <= 9 ; i++)
chip->current_k[i] = chip->old_k[i] + (chip->target_k[i] - chip->old_k[i]) * interp_effect / FR_SIZE;
}
static void vlm5030_reset(vlm5030_state *chip)
{
chip->phase = PH_RESET;
chip->address = 0;
chip->vcu_addr_h = 0;
chip->pin_BSY = 0;
chip->old_energy = chip->old_pitch = 0;
chip->new_energy = chip->new_pitch = 0;
chip->current_energy = chip->current_pitch = 0;
chip->target_energy = chip->target_pitch = 0;
memset(chip->old_k, 0, sizeof(chip->old_k));
memset(chip->new_k, 0, sizeof(chip->new_k));
memset(chip->current_k, 0, sizeof(chip->current_k));
memset(chip->target_k, 0, sizeof(chip->target_k));
chip->interp_count = chip->sample_count = chip->pitch_count = 0;
memset(chip->x, 0, sizeof(chip->x));
/* reset parameters */
vlm5030_setup_parameter(chip, 0x00);
}
static DEVICE_RESET( vlm5030 )
{
vlm5030_reset(get_safe_token(device));
}
/* set speech rom address */
void vlm5030_set_rom(device_t *device, void *speech_rom)
{
vlm5030_state *chip = get_safe_token(device);
chip->rom = (UINT8 *)speech_rom;
}
/* get BSY pin level */
int vlm5030_bsy(device_t *device)
{
vlm5030_state *chip = get_safe_token(device);
vlm5030_update(chip);
return chip->pin_BSY;
}
/* latch contoll data */
WRITE8_DEVICE_HANDLER( vlm5030_data_w )
{
vlm5030_state *chip = get_safe_token(device);
chip->latch_data = (UINT8)data;
}
/* set RST pin level : reset / set table address A8-A15 */
void vlm5030_rst (device_t *device, int pin )
{
vlm5030_state *chip = get_safe_token(device);
if( chip->pin_RST )
{
if( !pin )
{ /* H -> L : latch parameters */
chip->pin_RST = 0;
vlm5030_setup_parameter(chip, chip->latch_data);
}
}
else
{
if( pin )
{ /* L -> H : reset chip */
chip->pin_RST = 1;
if( chip->pin_BSY )
{
vlm5030_reset(chip);
}
}
}
}
/* set VCU pin level : ?? unknown */
void vlm5030_vcu(device_t *device, int pin)
{
vlm5030_state *chip = get_safe_token(device);
/* direct mode / indirect mode */
chip->pin_VCU = pin;
return;
}
/* set ST pin level : set table address A0-A7 / start speech */
void vlm5030_st(device_t *device, int pin )
{
vlm5030_state *chip = get_safe_token(device);
int table;
if( chip->pin_ST != pin )
{
/* pin level is change */
if( !pin )
{ /* H -> L */
chip->pin_ST = 0;
if( chip->pin_VCU )
{ /* direct access mode & address High */
chip->vcu_addr_h = ((int)chip->latch_data<<8) + 0x01;
}
else
{
/* start speech */
/* check access mode */
if( chip->vcu_addr_h )
{ /* direct access mode */
chip->address = (chip->vcu_addr_h&0xff00) + chip->latch_data;
chip->vcu_addr_h = 0;
}
else
{ /* indirect accedd mode */
table = (chip->latch_data&0xfe) + (((int)chip->latch_data&1)<<8);
chip->address = (((int)chip->rom[table&chip->address_mask])<<8)
| chip->rom[(table+1)&chip->address_mask];
#if 0
/* show unsupported parameter message */
if( chip->interp_step != 1)
popmessage("No %d %dBPS parameter",table/2,chip->interp_step*2400);
#endif
}
vlm5030_update(chip);
/* logerror("VLM5030 %02X start adr=%04X\n",table/2,chip->address ); */
/* reset process status */
chip->sample_count = chip->frame_size;
chip->interp_count = FR_SIZE;
/* clear filter */
/* start after 3 sampling cycle */
chip->phase = PH_RUN;
}
}
else
{ /* L -> H */
chip->pin_ST = 1;
/* setup speech , BSY on after 30ms? */
chip->phase = PH_SETUP;
chip->sample_count = 1; /* wait time for busy on */
chip->pin_BSY = 1; /* */
}
}
}
/* start VLM5030 with sound rom */
/* speech_rom == 0 -> use sampling data mode */
static DEVICE_START( vlm5030 )
{
const vlm5030_interface defintrf = { 0 };
int emulation_rate;
vlm5030_state *chip = get_safe_token(device);
chip->device = device;
chip->coeff = &vlm5030_coeff;
chip->intf = (device->static_config() != NULL) ? (const vlm5030_interface *)device->static_config() : &defintrf;
emulation_rate = device->clock() / 440;
/* reset input pins */
chip->pin_RST = chip->pin_ST = chip->pin_VCU= 0;
chip->latch_data = 0;
vlm5030_reset(chip);
chip->phase = PH_IDLE;
chip->rom = *device->region();
/* memory size */
if( chip->intf->memory_size == 0)
chip->address_mask = device->region()->bytes()-1;
else
chip->address_mask = chip->intf->memory_size-1;
chip->channel = device->machine().sound().stream_alloc(*device, 0, 1, emulation_rate,chip,vlm5030_update_callback);
/* don't restore "UINT8 *chip->rom" when use vlm5030_set_rom() */
device->save_item(NAME(chip->address));
device->save_item(NAME(chip->pin_BSY));
device->save_item(NAME(chip->pin_ST));
device->save_item(NAME(chip->pin_VCU));
device->save_item(NAME(chip->pin_RST));
device->save_item(NAME(chip->latch_data));
device->save_item(NAME(chip->vcu_addr_h));
device->save_item(NAME(chip->parameter));
device->save_item(NAME(chip->phase));
device->save_item(NAME(chip->interp_count));
device->save_item(NAME(chip->sample_count));
device->save_item(NAME(chip->pitch_count));
device->save_item(NAME(chip->old_energy));
device->save_item(NAME(chip->old_pitch));
device->save_item(NAME(chip->old_k));
device->save_item(NAME(chip->target_energy));
device->save_item(NAME(chip->target_pitch));
device->save_item(NAME(chip->target_k));
device->save_item(NAME(chip->x));
device->machine().save().register_postload(save_prepost_delegate(FUNC(vlm5030_restore_state), chip));
}
const device_type VLM5030 = &device_creator<vlm5030_device>;
vlm5030_device::vlm5030_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, VLM5030, "VLM5030", tag, owner, clock, "vlm5030", __FILE__),
device_sound_interface(mconfig, *this)
{
m_token = global_alloc_clear(vlm5030_state);
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void vlm5030_device::device_config_complete()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void vlm5030_device::device_start()
{
DEVICE_START_NAME( vlm5030 )(this);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void vlm5030_device::device_reset()
{
DEVICE_RESET_NAME( vlm5030 )(this);
}
//-------------------------------------------------
// sound_stream_update - handle a stream update
//-------------------------------------------------
void vlm5030_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
// should never get here
fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
}

View File

@ -4,34 +4,37 @@
#define __VLM5030_H__
struct vlm5030_interface
{
int memory_size; /* memory size of speech rom (0=memory region length) */
};
struct vlm5030_interface
{
int m_memory_size; /* memory size of speech rom (0=memory region length) */
};
class vlm5030_device : public device_t,
public device_sound_interface,
public vlm5030_interface
{
public:
vlm5030_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~vlm5030_device() {}
/* set speech rom address */
void set_rom(void *speech_rom);
/* get BSY pin level */
int bsy();
/* latch contoll data */
DECLARE_WRITE8_MEMBER( data_w );
/* set RST pin level : reset / set table address A8-A15 */
void rst (int pin );
/* set VCU pin level : ?? unknown */
void vcu( int pin );
/* set ST pin level : set table address A0-A7 / start speech */
void st( int pin );
/* set speech rom address */
void vlm5030_set_rom(device_t *device, void *speech_rom);
/* get BSY pin level */
int vlm5030_bsy(device_t *device);
/* latch contoll data */
DECLARE_WRITE8_DEVICE_HANDLER( vlm5030_data_w );
/* set RST pin level : reset / set table address A8-A15 */
void vlm5030_rst (device_t *device, int pin );
/* set VCU pin level : ?? unknown */
void vlm5030_vcu(device_t *device, int pin );
/* set ST pin level : set table address A0-A7 / start speech */
void vlm5030_st(device_t *device, int pin );
class vlm5030_device : public device_t,
public device_sound_interface
{
public:
vlm5030_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~vlm5030_device() { global_free(m_token); }
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
protected:
// device-level overrides
virtual void device_config_complete();
@ -40,9 +43,61 @@ protected:
// sound stream update overrides
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
private:
// internal state
void *m_token;
sound_stream * m_channel;
/* coefficient tables */
const struct tms5100_coeffs *m_coeff;
/* need to save state */
UINT8 *m_rom;
int m_address_mask;
UINT16 m_address;
UINT8 m_pin_BSY;
UINT8 m_pin_ST;
UINT8 m_pin_VCU;
UINT8 m_pin_RST;
UINT8 m_latch_data;
UINT16 m_vcu_addr_h;
UINT8 m_parameter;
UINT8 m_phase;
/* state of option paramter */
int m_frame_size;
int m_pitch_offset;
UINT8 m_interp_step;
UINT8 m_interp_count; /* number of interp periods */
UINT8 m_sample_count; /* sample number within interp */
UINT8 m_pitch_count;
/* these contain data describing the current and previous voice frames */
UINT16 m_old_energy;
UINT8 m_old_pitch;
INT16 m_old_k[10];
UINT16 m_target_energy;
UINT8 m_target_pitch;
INT16 m_target_k[10];
UINT16 m_new_energy;
UINT8 m_new_pitch;
INT16 m_new_k[10];
/* these are all used to contain the current state of the sound generation */
unsigned int m_current_energy;
unsigned int m_current_pitch;
int m_current_k[10];
INT32 m_x[10];
int get_bits(int sbit,int bits);
int parse_frame();
void update();
void setup_parameter(UINT8 param);
void restore_state();
};
extern const device_type VLM5030;

View File

@ -36,7 +36,7 @@ void trackfld_audio_device::device_config_complete()
void trackfld_audio_device::device_start()
{
m_audiocpu =machine().device<cpu_device>("audiocpu");
m_vlm = machine().device("vlm");
m_vlm = machine().device<vlm5030_device>("vlm");
/* sound */
save_item(NAME(m_last_addr));
@ -73,7 +73,7 @@ READ8_MEMBER( trackfld_audio_device::trackfld_sh_timer_r )
READ8_MEMBER( trackfld_audio_device::trackfld_speech_r )
{
return vlm5030_bsy(m_vlm) ? 0x10 : 0;
return m_vlm->bsy() ? 0x10 : 0;
}
WRITE8_MEMBER( trackfld_audio_device::trackfld_sound_w )
@ -86,11 +86,11 @@ WRITE8_MEMBER( trackfld_audio_device::trackfld_sound_w )
/* A8 VLM5030 ST pin */
if (changes & 0x100)
vlm5030_st(m_vlm, offset & 0x100);
m_vlm->st(offset & 0x100);
/* A9 VLM5030 RST pin */
if (changes & 0x200)
vlm5030_rst(m_vlm, offset & 0x200);
m_vlm->rst(offset & 0x200);
m_last_addr = offset;
}
@ -100,7 +100,7 @@ READ8_MEMBER( trackfld_audio_device::hyperspt_sh_timer_r )
UINT32 clock = m_audiocpu->total_cycles() / TIMER_RATE;
if (m_vlm != NULL)
return (clock & 0x3) | (vlm5030_bsy(m_vlm) ? 0x04 : 0);
return (clock & 0x3) | (m_vlm->bsy() ? 0x04 : 0);
else
return (clock & 0x3);
}
@ -118,11 +118,11 @@ WRITE8_MEMBER( trackfld_audio_device::hyperspt_sound_w )
/* A4 VLM5030 ST pin */
if (changes & 0x10)
vlm5030_st(m_vlm, offset & 0x10);
m_vlm->st(offset & 0x10);
/* A5 VLM5030 RST pin */
if( changes & 0x20 )
vlm5030_rst(m_vlm, offset & 0x20);
m_vlm->rst(offset & 0x20);
m_last_addr = offset;
}

View File

@ -32,7 +32,7 @@ private:
int m_last_irq;
cpu_device *m_audiocpu;
device_t *m_vlm;
vlm5030_device *m_vlm;
};
extern const device_type TRACKFLD_AUDIO;

View File

@ -12,7 +12,6 @@
#include "emu.h"
#include "cpu/m6809/m6809.h"
#include "sound/2203intf.h"
#include "sound/vlm5030.h"
#include "sound/flt_rc.h"
#include "includes/konamipt.h"
#include "includes/ddribble.h"
@ -69,33 +68,31 @@ WRITE8_MEMBER(ddribble_state::ddribble_coin_counter_w)
READ8_MEMBER(ddribble_state::ddribble_vlm5030_busy_r)
{
// device_t *device = machine().device("vlm");
return machine().rand(); /* patch */
/* FIXME: remove ? */
#if 0
if (vlm5030_bsy(device)) return 1;
if (m_vlm->bsy()) return 1;
else return 0;
#endif
}
WRITE8_MEMBER(ddribble_state::ddribble_vlm5030_ctrl_w)
{
device_t *device = machine().device("vlm");
UINT8 *SPEECH_ROM = memregion("vlm")->base();
/* b7 : vlm data bus OE */
/* b6 : VLM5030-RST */
vlm5030_rst(device, data & 0x40 ? 1 : 0);
m_vlm->rst(data & 0x40 ? 1 : 0);
/* b5 : VLM5030-ST */
vlm5030_st(device, data & 0x20 ? 1 : 0);
m_vlm->st(data & 0x20 ? 1 : 0);
/* b4 : VLM5300-VCU */
vlm5030_vcu(device, data & 0x10 ? 1 : 0);
m_vlm->vcu(data & 0x10 ? 1 : 0);
/* b3 : ROM bank select */
vlm5030_set_rom(device, &SPEECH_ROM[data & 0x08 ? 0x10000 : 0]);
m_vlm->set_rom(&SPEECH_ROM[data & 0x08 ? 0x10000 : 0]);
/* b2 : SSG-C rc filter enable */
dynamic_cast<filter_rc_device*>(m_filter3)->filter_rc_set_RC(FLT_RC_LOWPASS, 1000, 2200, 1000, data & 0x04 ? CAP_N(150) : 0); /* YM2203-SSG-C */
@ -139,7 +136,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( cpu2_map, AS_PROGRAM, 8, ddribble_state )
AM_RANGE(0x0000, 0x07ff) AM_RAM AM_SHARE("snd_sharedram") /* shared RAM with CPU #1 */
AM_RANGE(0x1000, 0x1001) AM_DEVREADWRITE("ymsnd", ym2203_device, read, write) /* YM2203 */
AM_RANGE(0x3000, 0x3000) AM_DEVWRITE_LEGACY("vlm", vlm5030_data_w) /* Speech data */
AM_RANGE(0x3000, 0x3000) AM_DEVWRITE("vlm", vlm5030_device, data_w) /* Speech data */
AM_RANGE(0x8000, 0xffff) AM_ROM /* ROM */
ADDRESS_MAP_END

View File

@ -11,8 +11,6 @@ Based on drivers from Juno First emulator by Chris Hardy (chrish@kcbbs.gen.nz)
#include "cpu/m6800/m6800.h"
#include "cpu/m6809/m6809.h"
#include "sound/dac.h"
#include "sound/sn76496.h"
#include "sound/vlm5030.h"
#include "machine/konami1.h"
#include "machine/nvram.h"
#include "includes/konamipt.h"
@ -78,7 +76,7 @@ static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, hyperspt_state )
AM_RANGE(0x4000, 0x4fff) AM_RAM
AM_RANGE(0x6000, 0x6000) AM_READ(soundlatch_byte_r)
AM_RANGE(0x8000, 0x8000) AM_DEVREAD("trackfld_audio", trackfld_audio_device, hyperspt_sh_timer_r)
AM_RANGE(0xa000, 0xa000) AM_DEVWRITE_LEGACY("vlm", vlm5030_data_w) /* speech data */
AM_RANGE(0xa000, 0xa000) AM_DEVWRITE("vlm", vlm5030_device, data_w) /* speech data */
AM_RANGE(0xc000, 0xdfff) AM_DEVWRITE("trackfld_audio", trackfld_audio_device, hyperspt_sound_w) /* speech and output control */
AM_RANGE(0xe000, 0xe000) AM_DEVWRITE("dac", dac_device, write_unsigned8)
AM_RANGE(0xe001, 0xe001) AM_WRITE(konami_SN76496_latch_w) /* Loads the snd command into the snd latch */

View File

@ -87,7 +87,6 @@ Notes:
#include "machine/konami1.h"
#include "cpu/m6809/m6809.h"
#include "sound/sn76496.h"
#include "sound/vlm5030.h"
#include "includes/konamipt.h"
#include "includes/jailbrek.h"
@ -114,16 +113,14 @@ INTERRUPT_GEN_MEMBER(jailbrek_state::jb_interrupt_nmi)
READ8_MEMBER(jailbrek_state::jailbrek_speech_r)
{
device_t *device = machine().device("vlm");
return (vlm5030_bsy(device) ? 1 : 0);
return (m_vlm->bsy() ? 1 : 0);
}
WRITE8_MEMBER(jailbrek_state::jailbrek_speech_w)
{
device_t *device = machine().device("vlm");
/* bit 0 could be latch direction like in yiear */
vlm5030_st(device, (data >> 1) & 1);
vlm5030_rst(device, (data >> 2) & 1);
m_vlm->st((data >> 1) & 1);
m_vlm->rst((data >> 2) & 1);
}
static ADDRESS_MAP_START( jailbrek_map, AS_PROGRAM, 8, jailbrek_state )
@ -146,7 +143,7 @@ static ADDRESS_MAP_START( jailbrek_map, AS_PROGRAM, 8, jailbrek_state )
AM_RANGE(0x3302, 0x3302) AM_READ_PORT("P2")
AM_RANGE(0x3303, 0x3303) AM_READ_PORT("DSW1")
AM_RANGE(0x4000, 0x4000) AM_WRITE(jailbrek_speech_w) /* speech pins */
AM_RANGE(0x5000, 0x5000) AM_DEVWRITE_LEGACY("vlm", vlm5030_data_w) /* speech data */
AM_RANGE(0x5000, 0x5000) AM_DEVWRITE("vlm", vlm5030_device, data_w) /* speech data */
AM_RANGE(0x6000, 0x6000) AM_READ(jailbrek_speech_r)
AM_RANGE(0x8000, 0xffff) AM_ROM
ADDRESS_MAP_END

View File

@ -52,8 +52,6 @@ So this is the correct behavior of real hardware, not an emulation bug.
#include "sound/ay8910.h"
#include "sound/2151intf.h"
#include "sound/3812intf.h"
#include "sound/vlm5030.h"
#include "sound/k005289.h"
#include "sound/k051649.h"
#include "includes/nemesis.h"
#include "includes/konamipt.h"
@ -216,19 +214,16 @@ WRITE16_MEMBER(nemesis_state::nemesis_soundlatch_word_w)
WRITE8_MEMBER(nemesis_state::gx400_speech_start_w)
{
device_t *device = machine().device("vlm");
/* the voice data is not in a rom but in sound RAM at $8000 */
vlm5030_set_rom(device, m_gx400_shared_ram + 0x4000);
vlm5030_st(device, 1);
vlm5030_st(device, 0);
m_vlm->set_rom(m_gx400_shared_ram + 0x4000);
m_vlm->st(1);
m_vlm->st(0);
}
WRITE8_MEMBER(nemesis_state::salamand_speech_start_w)
{
device_t *device = machine().device("vlm");
vlm5030_st(device, 1);
vlm5030_st(device, 0);
m_vlm->st(1);
m_vlm->st(0);
}
READ8_MEMBER(nemesis_state::nemesis_portA_r)
@ -243,7 +238,7 @@ READ8_MEMBER(nemesis_state::nemesis_portA_r)
res |= 0xd0;
if (m_vlm != NULL && vlm5030_bsy(m_vlm))
if (m_vlm != NULL && m_vlm->bsy())
res |= 0x20;
return res;
@ -412,7 +407,7 @@ static ADDRESS_MAP_START( gx400_sound_map, AS_PROGRAM, 8, nemesis_state )
AM_RANGE(0x4000, 0x87ff) AM_RAM AM_SHARE("gx400_shared")
AM_RANGE(0xa000, 0xafff) AM_DEVWRITE("k005289", k005289_device, k005289_pitch_A_w)
AM_RANGE(0xc000, 0xcfff) AM_DEVWRITE("k005289", k005289_device, k005289_pitch_B_w)
AM_RANGE(0xe000, 0xe000) AM_DEVWRITE_LEGACY("vlm", vlm5030_data_w)
AM_RANGE(0xe000, 0xe000) AM_DEVWRITE("vlm", vlm5030_device, data_w)
AM_RANGE(0xe001, 0xe001) AM_READ(soundlatch_byte_r)
AM_RANGE(0xe003, 0xe003) AM_DEVWRITE("k005289", k005289_device, k005289_keylatch_A_w)
AM_RANGE(0xe004, 0xe004) AM_DEVWRITE("k005289", k005289_device, k005289_keylatch_B_w)
@ -542,7 +537,7 @@ static ADDRESS_MAP_START( sal_sound_map, AS_PROGRAM, 8, nemesis_state )
AM_RANGE(0xa000, 0xa000) AM_READ(soundlatch_byte_r)
AM_RANGE(0xb000, 0xb00d) AM_DEVREADWRITE("k007232", k007232_device, read, write)
AM_RANGE(0xc000, 0xc001) AM_DEVREADWRITE("ymsnd", ym2151_device, read, write)
AM_RANGE(0xd000, 0xd000) AM_DEVWRITE_LEGACY("vlm", vlm5030_data_w)
AM_RANGE(0xd000, 0xd000) AM_DEVWRITE("vlm", vlm5030_device, data_w)
AM_RANGE(0xe000, 0xe000) AM_READ(wd_r) /* watchdog?? */
AM_RANGE(0xf000, 0xf000) AM_WRITE(salamand_speech_start_w)
ADDRESS_MAP_END
@ -1504,8 +1499,6 @@ static const k007232_interface k007232_config =
void nemesis_state::machine_start()
{
m_vlm = machine().device("vlm");
save_item(NAME(m_irq_on));
save_item(NAME(m_irq1_on));
save_item(NAME(m_irq2_on));

View File

@ -112,7 +112,6 @@ DIP locations verified for:
#include "emu.h"
#include "cpu/z80/z80.h"
#include "cpu/m6502/n2a03.h"
#include "sound/vlm5030.h"
#include "sound/nes_apu.h"
#include "machine/nvram.h"
#include "rendlay.h"
@ -122,25 +121,22 @@ DIP locations verified for:
CUSTOM_INPUT_MEMBER(punchout_state::punchout_vlm5030_busy_r)
{
/* bit 4 of DSW1 is busy pin level */
return (vlm5030_bsy(machine().device("vlm"))) ? 0x00 : 0x01;
return (m_vlm->bsy()) ? 0x00 : 0x01;
}
WRITE8_MEMBER(punchout_state::punchout_speech_reset_w)
{
device_t *device = machine().device("vlm");
vlm5030_rst( device, data & 0x01 );
m_vlm->rst( data & 0x01 );
}
WRITE8_MEMBER(punchout_state::punchout_speech_st_w)
{
device_t *device = machine().device("vlm");
vlm5030_st( device, data & 0x01 );
m_vlm->st( data & 0x01 );
}
WRITE8_MEMBER(punchout_state::punchout_speech_vcu_w)
{
device_t *device = machine().device("vlm");
vlm5030_vcu( device, data & 0x01 );
m_vlm->vcu( data & 0x01 );
}
WRITE8_MEMBER(punchout_state::punchout_2a03_reset_w)
@ -354,7 +350,7 @@ static ADDRESS_MAP_START( punchout_io_map, AS_IO, 8, punchout_state )
AM_RANGE(0x00, 0x01) AM_WRITENOP /* the 2A03 #1 is not present */
AM_RANGE(0x02, 0x02) AM_READ_PORT("DSW2") AM_WRITE(soundlatch_byte_w)
AM_RANGE(0x03, 0x03) AM_READ_PORT("DSW1") AM_WRITE(soundlatch2_byte_w)
AM_RANGE(0x04, 0x04) AM_DEVWRITE_LEGACY("vlm", vlm5030_data_w) /* VLM5030 */
AM_RANGE(0x04, 0x04) AM_DEVWRITE("vlm", vlm5030_device, data_w) /* VLM5030 */
// AM_RANGE(0x05, 0x05) AM_WRITENOP /* unused */
// AM_RANGE(0x06, 0x06) AM_WRITENOP
AM_RANGE(0x08, 0x08) AM_WRITE(nmi_mask_w)

View File

@ -51,7 +51,6 @@ Notes:
#include "cpu/m6809/m6809.h"
#include "cpu/m6809/hd6309.h"
#include "sound/2151intf.h"
#include "sound/vlm5030.h"
#include "includes/rockrage.h"
#include "includes/konamipt.h"
@ -82,16 +81,14 @@ WRITE8_MEMBER(rockrage_state::rockrage_sh_irqtrigger_w)
READ8_MEMBER(rockrage_state::rockrage_VLM5030_busy_r)
{
device_t *device = machine().device("vlm");
return (vlm5030_bsy(device) ? 1 : 0);
return (m_vlm->bsy() ? 1 : 0);
}
WRITE8_MEMBER(rockrage_state::rockrage_speech_w)
{
device_t *device = machine().device("vlm");
/* bit2 = data bus enable */
vlm5030_rst(device, (data >> 1) & 0x01);
vlm5030_st(device, (data >> 0) & 0x01);
m_vlm->rst((data >> 1) & 0x01);
m_vlm->st((data >> 0) & 0x01);
}
static ADDRESS_MAP_START( rockrage_map, AS_PROGRAM, 8, rockrage_state )
@ -115,7 +112,7 @@ static ADDRESS_MAP_START( rockrage_map, AS_PROGRAM, 8, rockrage_state )
ADDRESS_MAP_END
static ADDRESS_MAP_START( rockrage_sound_map, AS_PROGRAM, 8, rockrage_state )
AM_RANGE(0x2000, 0x2000) AM_DEVWRITE_LEGACY("vlm", vlm5030_data_w) /* VLM5030 */
AM_RANGE(0x2000, 0x2000) AM_DEVWRITE("vlm", vlm5030_device, data_w) /* VLM5030 */
AM_RANGE(0x3000, 0x3000) AM_READ(rockrage_VLM5030_busy_r) /* VLM5030 */
AM_RANGE(0x4000, 0x4000) AM_WRITE(rockrage_speech_w) /* VLM5030 */
AM_RANGE(0x5000, 0x5000) AM_READ(soundlatch_byte_r) /* soundlatch_byte_r */

View File

@ -42,8 +42,6 @@ CPU/Video Board Parts:
#include "cpu/z80/z80.h"
#include "cpu/m6809/m6809.h"
#include "sound/dac.h"
#include "sound/sn76496.h"
#include "sound/vlm5030.h"
#include "machine/konami1.h"
#include "includes/konamipt.h"
#include "audio/trackfld.h"
@ -95,7 +93,7 @@ static ADDRESS_MAP_START( sbasketb_sound_map, AS_PROGRAM, 8, sbasketb_state )
AM_RANGE(0x4000, 0x43ff) AM_RAM
AM_RANGE(0x6000, 0x6000) AM_READ(soundlatch_byte_r)
AM_RANGE(0x8000, 0x8000) AM_DEVREAD("trackfld_audio", trackfld_audio_device, hyperspt_sh_timer_r)
AM_RANGE(0xa000, 0xa000) AM_DEVWRITE_LEGACY("vlm", vlm5030_data_w) /* speech data */
AM_RANGE(0xa000, 0xa000) AM_DEVWRITE("vlm", vlm5030_device, data_w) /* speech data */
AM_RANGE(0xc000, 0xdfff) AM_DEVWRITE("trackfld_audio", trackfld_audio_device, hyperspt_sound_w) /* speech and output controll */
AM_RANGE(0xe000, 0xe000) AM_DEVWRITE("dac", dac_device, write_unsigned8)
AM_RANGE(0xe001, 0xe001) AM_WRITE(konami_SN76496_latch_w) /* Loads the snd command into the snd latch */

View File

@ -183,8 +183,6 @@ MAIN BOARD:
#include "cpu/m6800/m6800.h"
#include "machine/konami1.h"
#include "cpu/m6809/m6809.h"
#include "sound/sn76496.h"
#include "sound/vlm5030.h"
#include "sound/dac.h"
#include "audio/trackfld.h"
#include "audio/hyprolyb.h"
@ -256,8 +254,7 @@ WRITE8_MEMBER(trackfld_state::yieartf_nmi_mask_w)
READ8_MEMBER(trackfld_state::trackfld_speech_r)
{
device_t *device = machine().device("vlm");
if (vlm5030_bsy(device))
if (m_vlm->bsy())
return 1;
else
return 0;
@ -265,10 +262,9 @@ READ8_MEMBER(trackfld_state::trackfld_speech_r)
WRITE8_MEMBER(trackfld_state::trackfld_VLM5030_control_w)
{
device_t *device = machine().device("vlm");
/* bit 0 is latch direction */
vlm5030_st(device, (data >> 1) & 1);
vlm5030_rst(device, (data >> 2) & 1);
m_vlm->st((data >> 1) & 1);
m_vlm->rst((data >> 2) & 1);
}
@ -276,7 +272,7 @@ static ADDRESS_MAP_START( yieartf_map, AS_PROGRAM, 8, trackfld_state )
AM_RANGE(0x0000, 0x0000) AM_READ(trackfld_speech_r) AM_WRITE(konami_SN76496_latch_w)
AM_RANGE(0x0001, 0x0001) AM_WRITE(konami_SN76496_w)
AM_RANGE(0x0002, 0x0002) AM_WRITE(trackfld_VLM5030_control_w)
AM_RANGE(0x0003, 0x0003) AM_DEVWRITE_LEGACY("vlm", vlm5030_data_w)
AM_RANGE(0x0003, 0x0003) AM_DEVWRITE("vlm", vlm5030_device, data_w)
AM_RANGE(0x1000, 0x1000) AM_MIRROR(0x007f) AM_WRITE(watchdog_reset_w) /* AFE */
AM_RANGE(0x1080, 0x1080) AM_MIRROR(0x0078) AM_WRITE(trackfld_flipscreen_w) /* FLIP */
AM_RANGE(0x1081, 0x1081) AM_MIRROR(0x0078) AM_DEVWRITE("trackfld_audio", trackfld_audio_device, konami_sh_irqtrigger_w) /* 26 */ /* cause interrupt on audio CPU */
@ -411,7 +407,7 @@ static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, trackfld_state )
AM_RANGE(0xe001, 0xe001) AM_MIRROR(0x1ff8) AM_NOP /* watch dog ?; reaktor reads here */
AM_RANGE(0xe002, 0xe002) AM_MIRROR(0x1ff8) AM_DEVREAD("trackfld_audio", trackfld_audio_device, trackfld_speech_r)
AM_RANGE(0xe003, 0xe003) AM_MIRROR(0x1ff8) AM_MASK(0x0380) AM_DEVWRITE("trackfld_audio", trackfld_audio_device, trackfld_sound_w)
AM_RANGE(0xe004, 0xe004) AM_MIRROR(0x1ff8) AM_DEVWRITE_LEGACY("vlm", vlm5030_data_w)
AM_RANGE(0xe004, 0xe004) AM_MIRROR(0x1ff8) AM_DEVWRITE("vlm", vlm5030_device, data_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( hyprolyb_sound_map, AS_PROGRAM, 8, trackfld_state )

View File

@ -97,7 +97,6 @@ Sound: VLM5030 at 7B
#include "emu.h"
#include "cpu/m6809/m6809.h"
#include "sound/sn76496.h"
#include "sound/vlm5030.h"
#include "includes/konamipt.h"
#include "audio/trackfld.h"
#include "includes/yiear.h"
@ -106,8 +105,7 @@ Sound: VLM5030 at 7B
READ8_MEMBER(yiear_state::yiear_speech_r)
{
device_t *device = machine().device("vlm");
if (vlm5030_bsy(device))
if (m_vlm->bsy())
return 1;
else
return 0;
@ -115,10 +113,9 @@ READ8_MEMBER(yiear_state::yiear_speech_r)
WRITE8_MEMBER(yiear_state::yiear_VLM5030_control_w)
{
device_t *device = machine().device("vlm");
/* bit 0 is latch direction */
vlm5030_st(device, (data >> 1) & 1);
vlm5030_rst(device, (data >> 2) & 1);
m_vlm->st((data >> 1) & 1);
m_vlm->rst((data >> 2) & 1);
}
INTERRUPT_GEN_MEMBER(yiear_state::yiear_vblank_interrupt)
@ -141,7 +138,7 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, yiear_state )
AM_RANGE(0x4800, 0x4800) AM_WRITE(konami_SN76496_latch_w)
AM_RANGE(0x4900, 0x4900) AM_WRITE(konami_SN76496_w)
AM_RANGE(0x4a00, 0x4a00) AM_WRITE(yiear_VLM5030_control_w)
AM_RANGE(0x4b00, 0x4b00) AM_DEVWRITE_LEGACY("vlm", vlm5030_data_w)
AM_RANGE(0x4b00, 0x4b00) AM_DEVWRITE("vlm", vlm5030_device, data_w)
AM_RANGE(0x4c00, 0x4c00) AM_READ_PORT("DSW2")
AM_RANGE(0x4d00, 0x4d00) AM_READ_PORT("DSW3")
AM_RANGE(0x4e00, 0x4e00) AM_READ_PORT("SYSTEM")

View File

@ -4,6 +4,8 @@
***************************************************************************/
#include "sound/vlm5030.h"
class ddribble_state : public driver_device
{
public:
@ -16,7 +18,8 @@ public:
m_bg_videoram(*this, "bg_videoram"),
m_spriteram_2(*this, "spriteram_2"),
m_snd_sharedram(*this, "snd_sharedram"),
m_maincpu(*this, "maincpu") { }
m_maincpu(*this, "maincpu"),
m_vlm(*this, "vlm") { }
/* memory pointers */
required_shared_ptr<UINT8> m_paletteram;
@ -41,6 +44,9 @@ public:
device_t *m_filter1;
device_t *m_filter2;
device_t *m_filter3;
required_device<cpu_device> m_maincpu;
required_device<vlm5030_device> m_vlm;
DECLARE_WRITE8_MEMBER(ddribble_bankswitch_w);
DECLARE_READ8_MEMBER(ddribble_sharedram_r);
DECLARE_WRITE8_MEMBER(ddribble_sharedram_w);
@ -65,5 +71,4 @@ public:
INTERRUPT_GEN_MEMBER(ddribble_interrupt_1);
void set_pens( );
void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect, UINT8* source, int lenght, int gfxset, int flipscreen );
required_device<cpu_device> m_maincpu;
};

View File

@ -1,5 +1,6 @@
#include "sound/sn76496.h"
#include "sound/vlm5030.h"
class hyperspt_state : public driver_device
{
@ -11,7 +12,8 @@ public:
m_videoram(*this, "videoram"),
m_colorram(*this, "colorram"),
m_sn(*this, "snsnd"),
m_maincpu(*this, "maincpu") { }
m_maincpu(*this, "maincpu"),
m_vlm(*this, "vlm") { }
/* memory pointers */
required_shared_ptr<UINT8> m_spriteram;
@ -19,6 +21,9 @@ public:
required_shared_ptr<UINT8> m_videoram;
required_shared_ptr<UINT8> m_colorram;
optional_device<sn76496_device> m_sn;
required_device<cpu_device> m_maincpu;
optional_device<vlm5030_device> m_vlm;
UINT8 * m_scroll2;
UINT8 * m_spriteram2;
@ -45,5 +50,4 @@ public:
UINT32 screen_update_hyperspt(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(vblank_irq);
void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
required_device<cpu_device> m_maincpu;
};

View File

@ -4,6 +4,8 @@
***************************************************************************/
#include "sound/vlm5030.h"
#define MASTER_CLOCK XTAL_18_432MHz
#define VOICE_CLOCK XTAL_3_579545MHz
@ -17,7 +19,8 @@ public:
m_spriteram(*this, "spriteram"),
m_scroll_x(*this, "scroll_x"),
m_scroll_dir(*this, "scroll_dir"),
m_maincpu(*this, "maincpu") { }
m_maincpu(*this, "maincpu"),
m_vlm(*this, "vlm") { }
/* memory pointers */
required_shared_ptr<UINT8> m_colorram;
@ -25,6 +28,10 @@ public:
required_shared_ptr<UINT8> m_spriteram;
required_shared_ptr<UINT8> m_scroll_x;
required_shared_ptr<UINT8> m_scroll_dir;
/* devices */
required_device<cpu_device> m_maincpu;
required_device<vlm5030_device> m_vlm;
/* video-related */
tilemap_t *m_bg_tilemap;
@ -47,5 +54,4 @@ public:
INTERRUPT_GEN_MEMBER(jb_interrupt);
INTERRUPT_GEN_MEMBER(jb_interrupt_nmi);
void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
required_device<cpu_device> m_maincpu;
};

View File

@ -1,5 +1,6 @@
#include "sound/k007232.h"
#include "sound/k005289.h"
#include "sound/vlm5030.h"
class nemesis_state : public driver_device
{
@ -18,10 +19,11 @@ public:
m_spriteram(*this, "spriteram"),
m_paletteram(*this, "paletteram"),
m_gx400_shared_ram(*this, "gx400_shared"),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_k007232(*this, "k007232"),
m_k005289(*this, "k005289"),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"){ }
m_vlm(*this, "vlm") { }
/* memory pointers */
required_shared_ptr<UINT16> m_charram;
@ -36,8 +38,6 @@ public:
required_shared_ptr<UINT16> m_spriteram;
required_shared_ptr<UINT16> m_paletteram;
optional_shared_ptr<UINT8> m_gx400_shared_ram;
optional_device<k007232_device> m_k007232;
optional_device<k005289_device> m_k005289;
/* video-related */
tilemap_t *m_background;
@ -60,7 +60,9 @@ public:
/* devices */
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
device_t *m_vlm;
optional_device<k007232_device> m_k007232;
optional_device<k005289_device> m_k005289;
optional_device<vlm5030_device> m_vlm;
DECLARE_WRITE16_MEMBER(gx400_irq1_enable_word_w);
DECLARE_WRITE16_MEMBER(gx400_irq2_enable_word_w);
DECLARE_WRITE16_MEMBER(gx400_irq4_enable_word_w);

View File

@ -1,3 +1,5 @@
#include "sound/vlm5030.h"
class punchout_state : public driver_device
{
public:
@ -12,7 +14,8 @@ public:
m_bg_bot_videoram(*this, "bg_bot_videoram"),
m_armwrest_fg_videoram(*this, "armwrest_fgram"),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu") { }
m_audiocpu(*this, "audiocpu"),
m_vlm(*this, "vlm") { }
int m_rp5c01_mode_sel;
int m_rp5c01_mem[16*4];
@ -24,6 +27,11 @@ public:
required_shared_ptr<UINT8> m_spr2_videoram;
required_shared_ptr<UINT8> m_bg_bot_videoram;
optional_shared_ptr<UINT8> m_armwrest_fg_videoram;
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<vlm5030_device> m_vlm;
tilemap_t *m_bg_top_tilemap;
tilemap_t *m_bg_bot_tilemap;
tilemap_t *m_fg_tilemap;
@ -75,6 +83,4 @@ public:
void drawbs2(bitmap_ind16 &bitmap, const rectangle &cliprect);
void punchout_copy_top_palette(int bank);
void punchout_copy_bot_palette(int bank);
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
};

View File

@ -4,6 +4,7 @@
*************************************************************************/
#include "sound/vlm5030.h"
#include "video/k007342.h"
#include "video/k007420.h"
@ -13,10 +14,11 @@ public:
rockrage_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_paletteram(*this, "paletteram"),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_k007342(*this, "k007342"),
m_k007420(*this, "k007420"),
m_maincpu(*this, "maincpu") { }
m_vlm(*this, "vlm") { }
/* memory pointers */
required_shared_ptr<UINT8> m_paletteram;
@ -26,9 +28,11 @@ public:
int m_vreg;
/* devices */
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<k007342_device> m_k007342;
required_device<k007420_device> m_k007420;
required_device<vlm5030_device> m_vlm;
DECLARE_WRITE8_MEMBER(rockrage_bankswitch_w);
DECLARE_WRITE8_MEMBER(rockrage_sh_irqtrigger_w);
DECLARE_WRITE8_MEMBER(rockrage_vreg_w);
@ -39,7 +43,6 @@ public:
virtual void palette_init();
UINT32 screen_update_rockrage(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(rockrage_interrupt);
required_device<cpu_device> m_maincpu;
};
/*----------- defined in video/rockrage.c -----------*/

View File

@ -1,5 +1,6 @@
#include "sound/sn76496.h"
#include "sound/vlm5030.h"
class sbasketb_state : public driver_device
{
@ -12,9 +13,10 @@ public:
m_palettebank(*this, "palettebank"),
m_spriteram_select(*this, "spriteramsel"),
m_scroll(*this, "scroll"),
m_sn(*this, "snsnd"),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu") { }
m_audiocpu(*this, "audiocpu"),
m_sn(*this, "snsnd"),
m_vlm(*this, "vlm") { }
/* memory pointers */
required_shared_ptr<UINT8> m_colorram;
@ -23,7 +25,12 @@ public:
required_shared_ptr<UINT8> m_palettebank;
required_shared_ptr<UINT8> m_spriteram_select;
required_shared_ptr<UINT8> m_scroll;
optional_device<sn76489_device> m_sn;
/* devices */
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<sn76489_device> m_sn;
required_device<vlm5030_device> m_vlm;
/* video-related */
tilemap_t *m_bg_tilemap;
@ -46,6 +53,4 @@ public:
UINT32 screen_update_sbasketb(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(vblank_irq);
void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
};

View File

@ -5,6 +5,7 @@
***************************************************************************/
#include "sound/sn76496.h"
#include "sound/vlm5030.h"
class trackfld_state : public driver_device
{
@ -17,8 +18,9 @@ public:
m_scroll2(*this, "scroll2"),
m_videoram(*this, "videoram"),
m_colorram(*this, "colorram"),
m_maincpu(*this, "maincpu"),
m_sn(*this, "snsnd"),
m_maincpu(*this, "maincpu") { }
m_vlm(*this, "vlm") { }
/* memory pointers */
required_shared_ptr<UINT8> m_spriteram2;
@ -27,7 +29,11 @@ public:
required_shared_ptr<UINT8> m_scroll2;
required_shared_ptr<UINT8> m_videoram;
required_shared_ptr<UINT8> m_colorram;
/* devices */
required_device<cpu_device> m_maincpu;
optional_device<sn76496_device> m_sn;
optional_device<vlm5030_device> m_vlm;
/* video-related */
tilemap_t *m_bg_tilemap;
@ -70,5 +76,4 @@ public:
INTERRUPT_GEN_MEMBER(vblank_nmi);
INTERRUPT_GEN_MEMBER(yieartf_timer_irq);
void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
required_device<cpu_device> m_maincpu;
};

View File

@ -1,4 +1,5 @@
#include "sound/sn76496.h"
#include "sound/vlm5030.h"
class yiear_state : public driver_device
{
@ -8,14 +9,19 @@ public:
m_spriteram(*this, "spriteram"),
m_spriteram2(*this, "spriteram2"),
m_videoram(*this, "videoram"),
m_maincpu(*this, "maincpu"),
m_sn(*this, "snsnd"),
m_maincpu(*this, "maincpu") { }
m_vlm(*this, "vlm") { }
/* memory pointers */
required_shared_ptr<UINT8> m_spriteram;
required_shared_ptr<UINT8> m_spriteram2;
required_shared_ptr<UINT8> m_videoram;
optional_device<sn76489a_device> m_sn;
/* devices */
required_device<cpu_device> m_maincpu;
required_device<sn76489a_device> m_sn;
required_device<vlm5030_device> m_vlm;
/* video-related */
tilemap_t *m_bg_tilemap;
@ -39,5 +45,4 @@ public:
INTERRUPT_GEN_MEMBER(yiear_vblank_interrupt);
INTERRUPT_GEN_MEMBER(yiear_nmi_interrupt);
void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
required_device<cpu_device> m_maincpu;
};