Updated and fixed VGM OKIM6258 support from VGMPlay 0.40.4
parent
d3d370b76e
commit
85cc09e07f
|
@ -36,6 +36,11 @@ void Okim6258_Emu::write( int addr, int data )
|
||||||
okim6258_write( chip, addr, data );
|
okim6258_write( chip, addr, data );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Okim6258_Emu::get_clock()
|
||||||
|
{
|
||||||
|
return okim6258_get_vclk( chip );
|
||||||
|
}
|
||||||
|
|
||||||
void Okim6258_Emu::run( int pair_count, sample_t* out )
|
void Okim6258_Emu::run( int pair_count, sample_t* out )
|
||||||
{
|
{
|
||||||
stream_sample_t bufL[ 1024 ];
|
stream_sample_t bufL[ 1024 ];
|
||||||
|
|
|
@ -17,6 +17,9 @@ public:
|
||||||
// Resets to power-up state
|
// Resets to power-up state
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
// Returns current sample rate of the chip
|
||||||
|
int get_clock();
|
||||||
|
|
||||||
// Writes data to addr
|
// Writes data to addr
|
||||||
void write( int addr, int data );
|
void write( int addr, int data );
|
||||||
|
|
||||||
|
|
|
@ -197,9 +197,19 @@ int Vgm_Core::run_pwm( int time )
|
||||||
return pwm.run_until( time );
|
return pwm.run_until( time );
|
||||||
}
|
}
|
||||||
|
|
||||||
int Vgm_Core::run_okim6258( int time )
|
int Vgm_Core::run_okim6258( int chip, int time )
|
||||||
{
|
{
|
||||||
return okim6258.run_until( time );
|
chip = !!chip;
|
||||||
|
if ( okim6258[chip].enabled() )
|
||||||
|
{
|
||||||
|
int current_clock = okim6258[chip].get_clock();
|
||||||
|
if ( okim6258_hz[chip] != current_clock )
|
||||||
|
{
|
||||||
|
okim6258_hz[chip] = current_clock;
|
||||||
|
okim6258[chip].setup( (double)okim6258_hz[chip] / vgm_rate, 0.85, 1.0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return okim6258[chip].run_until( time );
|
||||||
}
|
}
|
||||||
|
|
||||||
int Vgm_Core::run_okim6295( int chip, int time )
|
int Vgm_Core::run_okim6295( int chip, int time )
|
||||||
|
@ -703,8 +713,8 @@ void Vgm_Core::chip_reg_write(unsigned Sample, byte ChipType, byte ChipID, byte
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x17:
|
case 0x17:
|
||||||
if ( run_okim6258( to_fm_time( Sample ) ) )
|
if ( run_okim6258( ChipID, to_fm_time( Sample ) ) )
|
||||||
okim6258.write( Offset, Data );
|
okim6258[ChipID].write( Offset, Data );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x18:
|
case 0x18:
|
||||||
|
@ -898,7 +908,8 @@ blargg_err_t Vgm_Core::load_mem_( byte const data [], int size )
|
||||||
rf5c68.enable( false );
|
rf5c68.enable( false );
|
||||||
rf5c164.enable( false );
|
rf5c164.enable( false );
|
||||||
pwm.enable( false );
|
pwm.enable( false );
|
||||||
okim6258.enable( false );
|
okim6258[0].enable( false );
|
||||||
|
okim6258[1].enable( false );
|
||||||
okim6295[0].enable( false );
|
okim6295[0].enable( false );
|
||||||
okim6295[1].enable( false );
|
okim6295[1].enable( false );
|
||||||
k051649.enable( false );
|
k051649.enable( false );
|
||||||
|
@ -1234,13 +1245,24 @@ blargg_err_t Vgm_Core::init_chips( double* rate, bool reinit )
|
||||||
}
|
}
|
||||||
if ( okim6258_rate )
|
if ( okim6258_rate )
|
||||||
{
|
{
|
||||||
|
bool dual_chip = !!( header().okim6258_rate[3] & 0x40 );
|
||||||
if ( !reinit )
|
if ( !reinit )
|
||||||
{
|
{
|
||||||
okim6258_hz = okim6258.set_rate( okim6258_rate, header().okim6258_flags & 0x03, ( header().okim6258_flags & 0x04 ) >> 2, ( header().okim6258_flags & 0x08 ) >> 3 );
|
okim6258_hz[0] = okim6258[0].set_rate( okim6258_rate, header().okim6258_flags & 0x03, ( header().okim6258_flags & 0x04 ) >> 2, ( header().okim6258_flags & 0x08 ) >> 3 );
|
||||||
CHECK_ALLOC( okim6258_hz );
|
CHECK_ALLOC( okim6258_hz[0] );
|
||||||
|
}
|
||||||
|
RETURN_ERR( okim6258[0].setup( (double)okim6258_hz[0] / vgm_rate, 0.85, 1.0 ) );
|
||||||
|
okim6258[0].enable();
|
||||||
|
if ( dual_chip )
|
||||||
|
{
|
||||||
|
if ( !reinit )
|
||||||
|
{
|
||||||
|
okim6258_hz[1] = okim6258[1].set_rate( okim6258_rate, header().okim6258_flags & 0x03, ( header().okim6258_flags & 0x04 ) >> 2, ( header().okim6258_flags & 0x08 ) >> 3 );
|
||||||
|
CHECK_ALLOC( okim6258_hz[1] );
|
||||||
|
}
|
||||||
|
RETURN_ERR( okim6258[1].setup( (double)okim6258_hz[1] / vgm_rate, 0.85, 1.0 ) );
|
||||||
|
okim6258[1].enable();
|
||||||
}
|
}
|
||||||
RETURN_ERR( okim6258.setup( (double)okim6258_hz / vgm_rate, 0.85, 1.0 ) );
|
|
||||||
okim6258.enable();
|
|
||||||
}
|
}
|
||||||
if ( okim6295_rate )
|
if ( okim6295_rate )
|
||||||
{
|
{
|
||||||
|
@ -1384,8 +1406,11 @@ void Vgm_Core::start_track()
|
||||||
if ( pwm.enabled() )
|
if ( pwm.enabled() )
|
||||||
pwm.reset();
|
pwm.reset();
|
||||||
|
|
||||||
if ( okim6258.enabled() )
|
if ( okim6258[0].enabled() )
|
||||||
okim6258.reset();
|
okim6258[0].reset();
|
||||||
|
|
||||||
|
if ( okim6258[1].enabled() )
|
||||||
|
okim6258[1].reset();
|
||||||
|
|
||||||
if ( okim6295[0].enabled() )
|
if ( okim6295[0].enabled() )
|
||||||
okim6295[0].reset();
|
okim6295[0].reset();
|
||||||
|
@ -1757,7 +1782,7 @@ blip_time_t Vgm_Core::run( vgm_time_t end_time )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmd_okim6258_write:
|
case cmd_okim6258_write:
|
||||||
chip_reg_write( vgm_time, 0x17, 0x00, 0x00, pos [0] & 0x7F, pos [1] );
|
chip_reg_write( vgm_time, 0x17, ChipID, 0x00, pos [0] & 0x7F, pos [1] );
|
||||||
pos += 2;
|
pos += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2157,9 +2182,13 @@ int Vgm_Core::play_frame( blip_time_t blip_time, int sample_count, blip_sample_t
|
||||||
{
|
{
|
||||||
pwm.begin_frame( out );
|
pwm.begin_frame( out );
|
||||||
}
|
}
|
||||||
if ( okim6258.enabled() )
|
if ( okim6258[0].enabled() )
|
||||||
{
|
{
|
||||||
okim6258.begin_frame( out );
|
okim6258[0].begin_frame( out );
|
||||||
|
if ( okim6258[1].enabled() )
|
||||||
|
{
|
||||||
|
okim6258[1].begin_frame( out );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ( okim6295[0].enabled() )
|
if ( okim6295[0].enabled() )
|
||||||
{
|
{
|
||||||
|
@ -2211,7 +2240,7 @@ int Vgm_Core::play_frame( blip_time_t blip_time, int sample_count, blip_sample_t
|
||||||
run_rf5c68( pairs );
|
run_rf5c68( pairs );
|
||||||
run_rf5c164( pairs );
|
run_rf5c164( pairs );
|
||||||
run_pwm( pairs );
|
run_pwm( pairs );
|
||||||
run_okim6258( pairs );
|
run_okim6258( 0, pairs ); run_okim6258( 1, pairs );
|
||||||
run_okim6295( 0, pairs ); run_okim6295( 1, pairs );
|
run_okim6295( 0, pairs ); run_okim6295( 1, pairs );
|
||||||
run_k051649( pairs );
|
run_k051649( pairs );
|
||||||
run_k053260( pairs );
|
run_k053260( pairs );
|
||||||
|
|
|
@ -150,7 +150,7 @@ public:
|
||||||
// True if any FM chips are used by file. Always false until init_fm()
|
// True if any FM chips are used by file. Always false until init_fm()
|
||||||
// is called.
|
// is called.
|
||||||
bool uses_fm() const { return ym2612[0].enabled() || ym2413[0].enabled() || ym2151[0].enabled() || c140.enabled() ||
|
bool uses_fm() const { return ym2612[0].enabled() || ym2413[0].enabled() || ym2151[0].enabled() || c140.enabled() ||
|
||||||
segapcm.enabled() || rf5c68.enabled() || rf5c164.enabled() || pwm.enabled() || okim6258.enabled() || okim6295[0].enabled() ||
|
segapcm.enabled() || rf5c68.enabled() || rf5c164.enabled() || pwm.enabled() || okim6258[0].enabled() || okim6295[0].enabled() ||
|
||||||
k051649.enabled() || k053260.enabled() || k054539.enabled() || ym2203[0].enabled() || ym3812[0].enabled() || ymf262[0].enabled() ||
|
k051649.enabled() || k053260.enabled() || k054539.enabled() || ym2203[0].enabled() || ym3812[0].enabled() || ymf262[0].enabled() ||
|
||||||
ymz280b.enabled() || ym2610[0].enabled() || ym2608[0].enabled() || qsound[0].enabled() ||
|
ymz280b.enabled() || ym2610[0].enabled() || ym2608[0].enabled() || qsound[0].enabled() ||
|
||||||
(header().ay8910_rate[0] | header().ay8910_rate[1] | header().ay8910_rate[2] | header().ay8910_rate[3]) ||
|
(header().ay8910_rate[0] | header().ay8910_rate[1] | header().ay8910_rate[2] | header().ay8910_rate[3]) ||
|
||||||
|
@ -205,7 +205,7 @@ public:
|
||||||
Chip_Resampler_Emu<Rf5C68_Emu> rf5c68;
|
Chip_Resampler_Emu<Rf5C68_Emu> rf5c68;
|
||||||
Chip_Resampler_Emu<Rf5C164_Emu> rf5c164;
|
Chip_Resampler_Emu<Rf5C164_Emu> rf5c164;
|
||||||
Chip_Resampler_Emu<Pwm_Emu> pwm;
|
Chip_Resampler_Emu<Pwm_Emu> pwm;
|
||||||
Chip_Resampler_Emu<Okim6258_Emu> okim6258; int okim6258_hz;
|
Chip_Resampler_Emu<Okim6258_Emu> okim6258[2]; int okim6258_hz[2];
|
||||||
Chip_Resampler_Emu<Okim6295_Emu> okim6295[2]; int okim6295_hz;
|
Chip_Resampler_Emu<Okim6295_Emu> okim6295[2]; int okim6295_hz;
|
||||||
Chip_Resampler_Emu<K051649_Emu> k051649;
|
Chip_Resampler_Emu<K051649_Emu> k051649;
|
||||||
Chip_Resampler_Emu<K053260_Emu> k053260;
|
Chip_Resampler_Emu<K053260_Emu> k053260;
|
||||||
|
@ -334,7 +334,7 @@ private:
|
||||||
int run_rf5c68( int time );
|
int run_rf5c68( int time );
|
||||||
int run_rf5c164( int time );
|
int run_rf5c164( int time );
|
||||||
int run_pwm( int time );
|
int run_pwm( int time );
|
||||||
int run_okim6258( int time );
|
int run_okim6258( int chip, int time );
|
||||||
int run_okim6295( int chip, int time );
|
int run_okim6295( int chip, int time );
|
||||||
int run_k051649( int time );
|
int run_k051649( int time );
|
||||||
int run_k053260( int time );
|
int run_k053260( int time );
|
||||||
|
|
|
@ -42,10 +42,24 @@ struct _okim6258_state
|
||||||
|
|
||||||
UINT8 output_bits;
|
UINT8 output_bits;
|
||||||
|
|
||||||
|
// Valley Bell: Added a small queue to prevent race conditions.
|
||||||
|
UINT8 data_buf[2];
|
||||||
|
UINT8 data_buf_pos;
|
||||||
|
// Data Empty Values:
|
||||||
|
// 00 - data written, but not read yet
|
||||||
|
// 01 - read data, waiting for next write
|
||||||
|
// 02 - tried to read, but had no data
|
||||||
|
UINT8 data_empty;
|
||||||
|
// Valley Bell: Added pan
|
||||||
|
UINT8 pan;
|
||||||
|
INT32 last_smpl;
|
||||||
|
|
||||||
INT32 signal;
|
INT32 signal;
|
||||||
INT32 step;
|
INT32 step;
|
||||||
|
|
||||||
UINT8 clock_buffer[0x04];
|
UINT8 clock_buffer[0x04];
|
||||||
|
UINT32 initial_clock;
|
||||||
|
UINT8 initial_div;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* step size index shift table */
|
/* step size index shift table */
|
||||||
|
@ -154,16 +168,55 @@ void okim6258_update(void *_chip, stream_sample_t **outputs, int samples)
|
||||||
while (samples)
|
while (samples)
|
||||||
{
|
{
|
||||||
/* Compute the new amplitude and update the current step */
|
/* Compute the new amplitude and update the current step */
|
||||||
int nibble = (chip->data_in >> nibble_shift) & 0xf;
|
//int nibble = (chip->data_in >> nibble_shift) & 0xf;
|
||||||
|
int nibble;
|
||||||
|
INT16 sample;
|
||||||
|
|
||||||
|
if (! nibble_shift)
|
||||||
|
{
|
||||||
|
// 1st nibble - get data
|
||||||
|
if (! chip->data_empty)
|
||||||
|
{
|
||||||
|
chip->data_in = chip->data_buf[chip->data_buf_pos >> 4];
|
||||||
|
chip->data_buf_pos ^= 0x10;
|
||||||
|
if ((chip->data_buf_pos >> 4) == (chip->data_buf_pos & 0x0F))
|
||||||
|
chip->data_empty ++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chip->data_in = 0x80;
|
||||||
|
if (chip->data_empty < 0x80)
|
||||||
|
chip->data_empty ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nibble = (chip->data_in >> nibble_shift) & 0xf;
|
||||||
|
|
||||||
/* Output to the buffer */
|
/* Output to the buffer */
|
||||||
INT16 sample = clock_adpcm(chip, nibble);
|
//INT16 sample = clock_adpcm(chip, nibble);
|
||||||
|
if (chip->data_empty < 0x02)
|
||||||
|
{
|
||||||
|
sample = clock_adpcm(chip, nibble);
|
||||||
|
chip->last_smpl = sample;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sample = chip->last_smpl;
|
||||||
|
// Valley Bell: data_empty behaviour (loosely) ported from XM6
|
||||||
|
if (chip->data_empty >= 0x12)
|
||||||
|
{
|
||||||
|
chip->data_empty -= 0x10;
|
||||||
|
if (chip->signal < 0)
|
||||||
|
chip->signal ++;
|
||||||
|
else if (chip->signal > 0)
|
||||||
|
chip->signal --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nibble_shift ^= 4;
|
nibble_shift ^= 4;
|
||||||
|
|
||||||
//*buffer++ = sample;
|
//*buffer++ = sample;
|
||||||
*bufL++ = sample;
|
*bufL++ = (chip->pan & 0x02) ? 0x00 : sample;
|
||||||
*bufR++ = sample;
|
*bufR++ = (chip->pan & 0x01) ? 0x00 : sample;
|
||||||
samples--;
|
samples--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,6 +273,8 @@ void * device_start_okim6258(int clock, int divider, int adpcm_type, int output_
|
||||||
compute_tables();
|
compute_tables();
|
||||||
|
|
||||||
//info->master_clock = device->clock();
|
//info->master_clock = device->clock();
|
||||||
|
info->initial_clock = clock;
|
||||||
|
info->initial_div = divider;
|
||||||
info->master_clock = clock;
|
info->master_clock = clock;
|
||||||
info->adpcm_type = /*intf->*/adpcm_type;
|
info->adpcm_type = /*intf->*/adpcm_type;
|
||||||
info->clock_buffer[0x00] = (clock & 0x000000FF) >> 0;
|
info->clock_buffer[0x00] = (clock & 0x000000FF) >> 0;
|
||||||
|
@ -263,9 +318,24 @@ void device_reset_okim6258(void *chip)
|
||||||
|
|
||||||
//stream_update(info->stream);
|
//stream_update(info->stream);
|
||||||
|
|
||||||
|
info->master_clock = info->initial_clock;
|
||||||
|
info->clock_buffer[0x00] = (info->initial_clock & 0x000000FF) >> 0;
|
||||||
|
info->clock_buffer[0x01] = (info->initial_clock & 0x0000FF00) >> 8;
|
||||||
|
info->clock_buffer[0x02] = (info->initial_clock & 0x00FF0000) >> 16;
|
||||||
|
info->clock_buffer[0x03] = (info->initial_clock & 0xFF000000) >> 24;
|
||||||
|
info->divider = dividers[info->initial_div];
|
||||||
|
|
||||||
|
|
||||||
info->signal = -2;
|
info->signal = -2;
|
||||||
info->step = 0;
|
info->step = 0;
|
||||||
info->status = 0;
|
info->status = 0;
|
||||||
|
|
||||||
|
// Valley Bell: Added reset of the Data In register.
|
||||||
|
info->data_in = 0x00;
|
||||||
|
info->data_buf[0] = info->data_buf[1] = 0x00;
|
||||||
|
info->data_buf_pos = 0x00;
|
||||||
|
info->data_empty = 0xFF;
|
||||||
|
info->pan = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -357,8 +427,17 @@ void okim6258_data_w(void *chip, offs_t offset, UINT8 data)
|
||||||
/* update the stream */
|
/* update the stream */
|
||||||
//stream_update(info->stream);
|
//stream_update(info->stream);
|
||||||
|
|
||||||
info->data_in = data;
|
//info->data_in = data;
|
||||||
info->nibble_shift = 0;
|
//info->nibble_shift = 0;
|
||||||
|
|
||||||
|
if (info->data_empty >= 0x02)
|
||||||
|
{
|
||||||
|
info->data_buf_pos = 0x00;
|
||||||
|
info->data_buf[info->data_buf_pos & 0x0F] = 0x80;
|
||||||
|
}
|
||||||
|
info->data_buf[info->data_buf_pos & 0x0F] = data;
|
||||||
|
info->data_buf_pos ^= 0x01;
|
||||||
|
info->data_empty = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -389,11 +468,14 @@ void okim6258_ctrl_w(void *chip, offs_t offset, UINT8 data)
|
||||||
info->status |= STATUS_PLAYING;
|
info->status |= STATUS_PLAYING;
|
||||||
|
|
||||||
/* Also reset the ADPCM parameters */
|
/* Also reset the ADPCM parameters */
|
||||||
info->signal = -2;
|
//info->signal = -2;
|
||||||
|
//info->step = 0;
|
||||||
|
//info->nibble_shift = 0;
|
||||||
|
}
|
||||||
|
//info->signal = -2;
|
||||||
info->step = 0;
|
info->step = 0;
|
||||||
info->nibble_shift = 0;
|
info->nibble_shift = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info->status &= ~STATUS_PLAYING;
|
info->status &= ~STATUS_PLAYING;
|
||||||
|
@ -419,6 +501,16 @@ void okim6258_set_clock_byte(void *chip, UINT8 Byte, UINT8 val)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void okim6258_pan_w(void *chip, UINT8 data)
|
||||||
|
{
|
||||||
|
okim6258_state *info = (okim6258_state *) chip;
|
||||||
|
|
||||||
|
info->pan = data;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void okim6258_write(void *chip, UINT8 Port, UINT8 Data)
|
void okim6258_write(void *chip, UINT8 Port, UINT8 Data)
|
||||||
{
|
{
|
||||||
switch(Port)
|
switch(Port)
|
||||||
|
@ -429,6 +521,9 @@ void okim6258_write(void *chip, UINT8 Port, UINT8 Data)
|
||||||
case 0x01:
|
case 0x01:
|
||||||
okim6258_data_w(chip, 0x00, Data);
|
okim6258_data_w(chip, 0x00, Data);
|
||||||
break;
|
break;
|
||||||
|
case 0x02:
|
||||||
|
okim6258_pan_w(chip, Data);
|
||||||
|
break;
|
||||||
case 0x08:
|
case 0x08:
|
||||||
case 0x09:
|
case 0x09:
|
||||||
case 0x0A:
|
case 0x0A:
|
||||||
|
|
Loading…
Reference in New Issue