📄 namcos1.c
字号:
#include "driver.h"
/* note: we work with signed samples here, unlike other drivers */
#ifdef SIGNED_SAMPLES
#define AUDIO_CONV(A) (A)
#define AUDIO_CONV16(A) (A)
#else
#define AUDIO_CONV(A) (A+0x80)
#define AUDIO_CONV16(A) (A+0x8000)
#endif
#define MAX_VOICES 8 /* 8 voices max */
static unsigned char default_prom[] ={
0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x03,0x05,0x03,0x09,0x0b,0x04,0x06,0x02,0x09,0x09,0x07,0x0a,0x05,0x08,0x06,
0x0a,0x06,0x07,0x0c,0x05,0x08,0x04,0x08,0x06,0x07,0x02,0x07,0x05,0x0b,0x07,0x08,
0xf7,0xfa,0xfc,0xfc,0xfe,0xfe,0xfc,0xfc,0xfe,0xfe,0xfc,0xf9,0xf7,0xf7,0xf5,0xf5,
0xf7,0xf9,0xf9,0xf7,0xf7,0xf5,0xf2,0xf0,0xf0,0xf2,0xf2,0xf0,0xf0,0xf2,0xf2,0xf3,
0xf1,0xf1,0xf2,0xf3,0xf3,0xf3,0xf3,0xf4,0xf5,0xf4,0xf3,0xf2,0xf0,0xf0,0xf2,0xf4,
0xf5,0xf5,0xf4,0xf3,0xf3,0xfb,0xfb,0xfa,0xf9,0xfa,0xfb,0xfc,0xfe,0xfe,0xfc,0xfa,
0xf0,0xf7,0xfe,0xf7,0xf3,0xf1,0xf0,0xf1,0xf3,0xf7,0xfb,0xfd,0xfe,0xfd,0xfb,0xf7,
0xf4,0xf2,0xf1,0xf0,0xf1,0xf2,0xf4,0xf7,0xfa,0xfc,0xfd,0xfe,0xfd,0xfc,0xfa,0xf7,
0xfa,0xfc,0xfc,0xfa,0xf7,0xf7,0xf8,0xfb,0xfd,0xfe,0xfd,0xfa,0xf6,0xf5,0xf5,0xf7,
0xf9,0xf9,0xf8,0xf4,0xf1,0xf0,0xf1,0xf3,0xf6,0xf7,0xf7,0xf4,0xf2,0xf2,0xf4,0xf7,
0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xfe,0xfe,0xfd,0xfd,0xfc,0xfb,0xfa,0xf9,0xf7,
0xf5,0xf4,0xf3,0xf2,0xf1,0xf1,0xf0,0xf0,0xf0,0xf1,0xf1,0xf2,0xf3,0xf4,0xf5,0xf7,
0xf0,0xf0,0xf1,0xf1,0xf0,0xf7,0xf8,0xf8,0xf0,0xf0,0xf1,0xf1,0xf0,0xf9,0xfa,0xfa,
0xf0,0xf0,0xf1,0xf1,0xf0,0xfb,0xfc,0xfc,0xf0,0xf0,0xf1,0xf1,0xf0,0xfe,0xff,0xff,
0x08,0x0a,0x0e,0x0a,0x0a,0x0a,0x0a,0x09,0x09,0x09,0x0a,0x0a,0x09,0x09,0x09,0x09,
0x03,0x03,0x03,0x03,0x02,0x02,0x03,0x03,0x03,0x02,0x02,0x02,0x02,0x01,0x04,0x06,
0x00,0x01,0x01,0x06,0x08,0x08,0x06,0x06,0x0c,0x0c,0x0b,0x06,0x08,0x08,0x0a,0x0b,
0x0b,0x0b,0x0b,0x0e,0x0f,0x0f,0x08,0x08,0x0e,0x0e,0x0d,0x0a,0x0b,0x0b,0x0f,0x0f,
0x0f,0x0f,0x0e,0x0e,0x0d,0x0d,0x0c,0x0c,0x0b,0x0b,0x0a,0x0a,0x09,0x09,0x08,0x08,
0x07,0x07,0x06,0x06,0x05,0x05,0x04,0x04,0x03,0x03,0x02,0x02,0x01,0x01,0x00,0x00,
0x00,0x02,0x09,0x0a,0x0a,0x0a,0x05,0x09,0x00,0x00,0x00,0x00,0x02,0x05,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,
0x09,0x01,0x00,0x00,0x00,0x00,0x00,0x04,0x0b,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x02,0x06,0x0b,0x0e,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x06,
0x00,0x00,0x00,0x00,0x02,0x02,0x0b,0x0d,0x0f,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0c,0x0c,0x0a,0x00,0x01,0x01,0x00,0x00,0x0a,0x0a,0x09,0x00,0x0a,0x0a,
0x00,0x00,0x08,0x08,0x07,0x00,0x01,0x01,0x00,0x00,0x0f,0x0f,0x0e,0x00,0x01,0x01,
0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,
0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e,
0x00,0x02,0x03,0x03,0x03,0x04,0x04,0x05,0x04,0x04,0x04,0x03,0x02,0x05,0x09,0x0c,
0x0f,0x0e,0x0c,0x0c,0x0c,0x0a,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0a,0x07,0x03
};
static unsigned char *sound_prom;
static struct namcos1_interface *intf;
static int channel;
/* Registers definition */
#define LEFT_VOLUME 0x00
#define WAVEFORM 0x01
#define PITCH_MSB 0x02
#define PITCH_LSB 0x03
#define RIGHT_VOLUME 0x04
/* Our voice structure */
static struct namcos1_voice {
int pitch;
int lvol;
int rvol;
int step;
unsigned char *wave;
} voice[MAX_VOICES];
#define MAXOUT_MASK 0x0f
#define MAXOUT_BITS 0x04
static unsigned char local_regs[64];
static void namcos1_update8( int num,void *buffer,int length ) {
int i,j, delta, step, data;
unsigned char *rom_ptr;
signed char *buf;
if ( Machine->sample_rate == 0 )
return;
memset( buffer, AUDIO_CONV( 0 ), length );
buf = buffer;
for( i = 0; i < MAX_VOICES; i++ ) {
if ( voice[i].pitch > 0 ) {
delta = voice[i].pitch;
rom_ptr = voice[i].wave;
step = voice[i].step;
for( j = 0; j < length; j++ ) {
data = ( ( rom_ptr[( step >> 0x0f ) & 0x1f] & 0x0f ) - 8 );
data *= ( voice[i].lvol + voice[i].rvol );
data = ( data < 0 ) ? -( ( data >> MAXOUT_BITS ) & MAXOUT_MASK ) : ( ( data >> MAXOUT_BITS ) & MAXOUT_MASK );
buf[j] += AUDIO_CONV( data );
step += delta;
}
voice[i].step = step;
}
}
}
#undef MAXOUT_MASK
#undef MAXOUT_BITS
#define MAXOUT_MASK 0x0fff
#define MAXOUT_BITS 0x04
static void namcos1_update16( int num,void *buffer,int length ) {
int i,j, delta, step, data;
unsigned char *rom_ptr;
signed short *buf;
if ( Machine->sample_rate == 0 )
return;
memset( buffer, AUDIO_CONV16( 0 ), length * sizeof( unsigned short ) );
buf = buffer;
for( i = 0; i < MAX_VOICES; i++ ) {
if ( voice[i].pitch > 0 ) {
delta = voice[i].pitch;
rom_ptr = voice[i].wave;
step = voice[i].step;
for( j = 0; j < length; j++ ) {
data = ( ( rom_ptr[( step >> 0x0f ) & 0x1f] & 0x0f ) - 8 );
data *= ( voice[i].lvol + voice[i].rvol );
data = ( data < 0 ) ? -( ( data << MAXOUT_BITS ) & MAXOUT_MASK ) : ( ( data << MAXOUT_BITS ) & MAXOUT_MASK );
buf[j] += AUDIO_CONV16( data );
step += delta;
}
voice[i].step = step;
}
}
}
#undef MAXOUT_MASK
#undef MAXOUT_BITS
int namcos1_sh_start( struct namcos1_interface *interface ) {
int i;
if ( Machine->sample_rate == 0 )
return 0;
channel = stream_init( "Namco PSG", interface->clock, Machine->sample_bits, 0, ( Machine->sample_bits == 16 ) ? namcos1_update16 : namcos1_update8 );
if ( channel == -1 )
return 1;
intf = interface;
if ( intf->region == -1 )
sound_prom = default_prom;
else
sound_prom = Machine->memory_region[intf->region];
stream_set_volume( channel,interface->volume & 0xff );
/* Init voices */
for ( i = 0; i < MAX_VOICES; i++ ) {
voice[i].pitch = 0;
voice[i].lvol = 0;
voice[i].rvol = 0;
voice[i].wave = &sound_prom[0];
voice[i].step = 0;
}
return 0;
}
void namcos1_sh_stop( void ) {
}
void namcos1_sh_update( void ) {
}
int namcos1_sound_r( int offs ) {
return local_regs[offs];
}
void namcos1_sound_w( int offs, int data ) {
int voicenum, r, base;
if ( offs > 63 ) {
return;
}
local_regs[offs] = data;
if ( Machine->sample_rate == 0 )
return;
voicenum = offs / 8;
base = voicenum * 8;
r = offs % 8;
switch( r ) {
case LEFT_VOLUME:
voice[voicenum].lvol = data & 0x0f;
break;
case WAVEFORM:
voice[voicenum].wave = &sound_prom[32 * ( ( data >> 4 ) & 0x0f )];
break;
case PITCH_MSB:
voice[voicenum].pitch &= 0x00ff;
voice[voicenum].pitch |= ( data << 8 );
break;
case PITCH_LSB:
voice[voicenum].pitch &= 0xff00;
voice[voicenum].pitch |= data;
break;
case RIGHT_VOLUME:
voice[voicenum].rvol = data & 0x0f;
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -