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 );
|
||||
}
|
||||
|
||||
int Okim6258_Emu::get_clock()
|
||||
{
|
||||
return okim6258_get_vclk( chip );
|
||||
}
|
||||
|
||||
void Okim6258_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
stream_sample_t bufL[ 1024 ];
|
||||
|
|
|
@ -16,6 +16,9 @@ public:
|
|||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Returns current sample rate of the chip
|
||||
int get_clock();
|
||||
|
||||
// Writes data to addr
|
||||
void write( int addr, int data );
|
||||
|
|
|
@ -197,9 +197,19 @@ int Vgm_Core::run_pwm( int 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 )
|
||||
|
@ -703,8 +713,8 @@ void Vgm_Core::chip_reg_write(unsigned Sample, byte ChipType, byte ChipID, byte
|
|||
break;
|
||||
|
||||
case 0x17:
|
||||
if ( run_okim6258( to_fm_time( Sample ) ) )
|
||||
okim6258.write( Offset, Data );
|
||||
if ( run_okim6258( ChipID, to_fm_time( Sample ) ) )
|
||||
okim6258[ChipID].write( Offset, Data );
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
|
@ -898,7 +908,8 @@ blargg_err_t Vgm_Core::load_mem_( byte const data [], int size )
|
|||
rf5c68.enable( false );
|
||||
rf5c164.enable( false );
|
||||
pwm.enable( false );
|
||||
okim6258.enable( false );
|
||||
okim6258[0].enable( false );
|
||||
okim6258[1].enable( false );
|
||||
okim6295[0].enable( false );
|
||||
okim6295[1].enable( false );
|
||||
k051649.enable( false );
|
||||
|
@ -1234,13 +1245,24 @@ blargg_err_t Vgm_Core::init_chips( double* rate, bool reinit )
|
|||
}
|
||||
if ( okim6258_rate )
|
||||
{
|
||||
bool dual_chip = !!( header().okim6258_rate[3] & 0x40 );
|
||||
if ( !reinit )
|
||||
{
|
||||
okim6258_hz = okim6258.set_rate( okim6258_rate, header().okim6258_flags & 0x03, ( header().okim6258_flags & 0x04 ) >> 2, ( header().okim6258_flags & 0x08 ) >> 3 );
|
||||
CHECK_ALLOC( okim6258_hz );
|
||||
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[0] );
|
||||
}
|
||||
RETURN_ERR( okim6258.setup( (double)okim6258_hz / vgm_rate, 0.85, 1.0 ) );
|
||||
okim6258.enable();
|
||||
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();
|
||||
}
|
||||
}
|
||||
if ( okim6295_rate )
|
||||
{
|
||||
|
@ -1384,8 +1406,11 @@ void Vgm_Core::start_track()
|
|||
if ( pwm.enabled() )
|
||||
pwm.reset();
|
||||
|
||||
if ( okim6258.enabled() )
|
||||
okim6258.reset();
|
||||
if ( okim6258[0].enabled() )
|
||||
okim6258[0].reset();
|
||||
|
||||
if ( okim6258[1].enabled() )
|
||||
okim6258[1].reset();
|
||||
|
||||
if ( okim6295[0].enabled() )
|
||||
okim6295[0].reset();
|
||||
|
@ -1757,7 +1782,7 @@ blip_time_t Vgm_Core::run( vgm_time_t end_time )
|
|||
break;
|
||||
|
||||
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;
|
||||
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 );
|
||||
}
|
||||
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() )
|
||||
{
|
||||
|
@ -2211,7 +2240,7 @@ int Vgm_Core::play_frame( blip_time_t blip_time, int sample_count, blip_sample_t
|
|||
run_rf5c68( pairs );
|
||||
run_rf5c164( pairs );
|
||||
run_pwm( pairs );
|
||||
run_okim6258( pairs );
|
||||
run_okim6258( 0, pairs ); run_okim6258( 1, pairs );
|
||||
run_okim6295( 0, pairs ); run_okim6295( 1, pairs );
|
||||
run_k051649( pairs );
|
||||
run_k053260( pairs );
|
||||
|
|
|
@ -150,7 +150,7 @@ public:
|
|||
// True if any FM chips are used by file. Always false until init_fm()
|
||||
// is called.
|
||||
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() ||
|
||||
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]) ||
|
||||
|
@ -205,7 +205,7 @@ public:
|
|||
Chip_Resampler_Emu<Rf5C68_Emu> rf5c68;
|
||||
Chip_Resampler_Emu<Rf5C164_Emu> rf5c164;
|
||||
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<K051649_Emu> k051649;
|
||||
Chip_Resampler_Emu<K053260_Emu> k053260;
|
||||
|
@ -334,7 +334,7 @@ private:
|
|||
int run_rf5c68( int time );
|
||||
int run_rf5c164( 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_k051649( int time );
|
||||
int run_k053260( int time );
|
||||
|
|
|
@ -42,10 +42,24 @@ struct _okim6258_state
|
|||
|
||||
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 step;
|
||||
|
||||
UINT8 clock_buffer[0x04];
|
||||
UINT32 initial_clock;
|
||||
UINT8 initial_div;
|
||||
};
|
||||
|
||||
/* step size index shift table */
|
||||
|
@ -144,29 +158,68 @@ void okim6258_update(void *_chip, stream_sample_t **outputs, int samples)
|
|||
//stream_sample_t *buffer = outputs[0];
|
||||
stream_sample_t *bufL = outputs[0];
|
||||
stream_sample_t *bufR = outputs[1];
|
||||
|
||||
|
||||
//memset(outputs[0], 0, samples * sizeof(*outputs[0]));
|
||||
|
||||
|
||||
if (chip->status & STATUS_PLAYING)
|
||||
{
|
||||
int nibble_shift = chip->nibble_shift;
|
||||
|
||||
|
||||
while (samples)
|
||||
{
|
||||
/* 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 */
|
||||
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;
|
||||
|
||||
|
||||
//*buffer++ = sample;
|
||||
*bufL++ = sample;
|
||||
*bufR++ = sample;
|
||||
*bufL++ = (chip->pan & 0x02) ? 0x00 : sample;
|
||||
*bufR++ = (chip->pan & 0x01) ? 0x00 : sample;
|
||||
samples--;
|
||||
}
|
||||
|
||||
|
||||
/* Update the parameters */
|
||||
chip->nibble_shift = nibble_shift;
|
||||
}
|
||||
|
@ -220,6 +273,8 @@ void * device_start_okim6258(int clock, int divider, int adpcm_type, int output_
|
|||
compute_tables();
|
||||
|
||||
//info->master_clock = device->clock();
|
||||
info->initial_clock = clock;
|
||||
info->initial_div = divider;
|
||||
info->master_clock = clock;
|
||||
info->adpcm_type = /*intf->*/adpcm_type;
|
||||
info->clock_buffer[0x00] = (clock & 0x000000FF) >> 0;
|
||||
|
@ -263,9 +318,24 @@ void device_reset_okim6258(void *chip)
|
|||
|
||||
//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->step = 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 */
|
||||
//stream_update(info->stream);
|
||||
|
||||
info->data_in = data;
|
||||
info->nibble_shift = 0;
|
||||
//info->data_in = data;
|
||||
//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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -381,24 +460,27 @@ void okim6258_ctrl_w(void *chip, offs_t offset, UINT8 data)
|
|||
info->status &= ~(STATUS_PLAYING | STATUS_RECORDING);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (data & COMMAND_PLAY)
|
||||
{
|
||||
if (!(info->status & STATUS_PLAYING))
|
||||
{
|
||||
info->status |= STATUS_PLAYING;
|
||||
|
||||
|
||||
/* Also reset the ADPCM parameters */
|
||||
info->signal = -2;
|
||||
info->step = 0;
|
||||
info->nibble_shift = 0;
|
||||
//info->signal = -2;
|
||||
//info->step = 0;
|
||||
//info->nibble_shift = 0;
|
||||
}
|
||||
//info->signal = -2;
|
||||
info->step = 0;
|
||||
info->nibble_shift = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->status &= ~STATUS_PLAYING;
|
||||
}
|
||||
|
||||
|
||||
if (data & COMMAND_RECORD)
|
||||
{
|
||||
/*logerror("M6258: Record enabled\n");*/
|
||||
|
@ -419,6 +501,16 @@ void okim6258_set_clock_byte(void *chip, UINT8 Byte, UINT8 val)
|
|||
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)
|
||||
{
|
||||
switch(Port)
|
||||
|
@ -429,6 +521,9 @@ void okim6258_write(void *chip, UINT8 Port, UINT8 Data)
|
|||
case 0x01:
|
||||
okim6258_data_w(chip, 0x00, Data);
|
||||
break;
|
||||
case 0x02:
|
||||
okim6258_pan_w(chip, Data);
|
||||
break;
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0A:
|
||||
|
|
Loading…
Reference in New Issue