Run SMP and DSP in less of a lockstep arrangement
parent
9211827957
commit
0a2dd30a51
|
@ -198,9 +198,9 @@ public:
|
|||
unsigned read_counter( int rate );
|
||||
|
||||
int interpolate( voice_t const* v );
|
||||
int interpolate_cubic( voice_t const* v );
|
||||
int interpolate_sinc( voice_t const* v );
|
||||
int interpolate_linear( voice_t const* v );
|
||||
int interpolate_cubic( voice_t const* v );
|
||||
int interpolate_sinc( voice_t const* v );
|
||||
int interpolate_linear( voice_t const* v );
|
||||
int interpolate_nearest( voice_t const* v );
|
||||
|
||||
void run_envelope( voice_t* const v );
|
||||
|
@ -250,7 +250,7 @@ public:
|
|||
#include <assert.h>
|
||||
|
||||
inline int SPC_DSP::sample_count() const { return m.out - m.out_begin; }
|
||||
|
||||
|
||||
inline int SPC_DSP::read( int addr ) const
|
||||
{
|
||||
assert( (unsigned) addr < register_count );
|
||||
|
|
|
@ -3,18 +3,25 @@
|
|||
|
||||
namespace SuperFamicom {
|
||||
|
||||
void DSP::step(unsigned clocks) {
|
||||
void DSP::step(uint64_t clocks) {
|
||||
clock += clocks;
|
||||
}
|
||||
|
||||
void DSP::enter() {
|
||||
spc_dsp.run(1);
|
||||
step(24 * 4096);
|
||||
int64_t dsp_clocks = (-clock) / (24 * 4096) + 1;
|
||||
spc_dsp.run(dsp_clocks);
|
||||
step(dsp_clocks * 24 * 4096);
|
||||
|
||||
signed count = spc_dsp.sample_count();
|
||||
if(count > 0) {
|
||||
for(unsigned n = 0; n < count; n += 2) smp.sample(samplebuffer[n + 0], samplebuffer[n + 1]);
|
||||
if(count > removed_samples) {
|
||||
for(unsigned n = removed_samples; n < count; n += 2) {
|
||||
if (!smp.sample(samplebuffer[n + 0], samplebuffer[n + 1])) {
|
||||
removed_samples = n;
|
||||
return;
|
||||
}
|
||||
}
|
||||
spc_dsp.set_output(samplebuffer, 8192);
|
||||
removed_samples = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,11 +41,13 @@ void DSP::power() {
|
|||
spc_dsp.init(smp.apuram);
|
||||
spc_dsp.reset();
|
||||
spc_dsp.set_output(samplebuffer, 8192);
|
||||
removed_samples = 0;
|
||||
}
|
||||
|
||||
void DSP::reset() {
|
||||
spc_dsp.soft_reset();
|
||||
spc_dsp.set_output(samplebuffer, 8192);
|
||||
removed_samples = 0;
|
||||
}
|
||||
|
||||
void DSP::channel_enable(unsigned channel, bool enable) {
|
||||
|
@ -55,7 +64,7 @@ void DSP::disable_surround(bool disable) {
|
|||
}
|
||||
|
||||
DSP::DSP(struct SMP & p_smp)
|
||||
: smp( p_smp ), clock( 0 ) {
|
||||
: smp( p_smp ), clock( 0 ), removed_samples( 0 ) {
|
||||
for(unsigned i = 0; i < 8; i++) channel_enabled[i] = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,9 @@ namespace SuperFamicom {
|
|||
|
||||
struct DSP {
|
||||
int64_t clock;
|
||||
unsigned long removed_samples;
|
||||
|
||||
inline void step(unsigned clocks);
|
||||
inline void step(uint64_t clocks);
|
||||
|
||||
bool mute();
|
||||
uint8_t read(uint8_t addr);
|
||||
|
|
|
@ -22,6 +22,14 @@ void SMP::port_write(uint8_t port, uint8_t data) {
|
|||
uint8_t SMP::op_busread(uint16_t addr) {
|
||||
unsigned result;
|
||||
|
||||
if ( !(dsp.read( SPC_DSP::r_flg ) & 0x20) ) {
|
||||
int start = 0x100 * dsp.read( SPC_DSP::r_esa );
|
||||
int end = start + 0x800 * (dsp.read( SPC_DSP::r_edl ) & 0x0F);
|
||||
if ( end > 0x10000 )
|
||||
end = 0x10000;
|
||||
if ( addr >= start || addr < end) synchronize_dsp();
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0xf0: //TEST -- write-only register
|
||||
return 0x00;
|
||||
|
@ -34,6 +42,7 @@ uint8_t SMP::op_busread(uint16_t addr) {
|
|||
|
||||
case 0xf3: //DSPDATA
|
||||
//0x80-0xff are read-only mirrors of 0x00-0x7f
|
||||
synchronize_dsp();
|
||||
return dsp.read(status.dsp_addr & 0x7f);
|
||||
|
||||
case 0xf4: //CPUIO0
|
||||
|
@ -77,6 +86,7 @@ uint8_t SMP::op_busread(uint16_t addr) {
|
|||
}
|
||||
|
||||
void SMP::op_buswrite(uint16_t addr, uint8_t data) {
|
||||
synchronize_dsp();
|
||||
switch(addr) {
|
||||
case 0xf0: //TEST
|
||||
if(regs.p.p) break; //writes only valid when P flag is clear
|
||||
|
|
|
@ -14,21 +14,26 @@ void SMP::step(unsigned clocks) {
|
|||
}
|
||||
|
||||
void SMP::synchronize_dsp() {
|
||||
while(dsp.clock < 0 && sample_buffer < sample_buffer_end) dsp.enter();
|
||||
while(dsp.clock < 0) dsp.enter();
|
||||
}
|
||||
|
||||
void SMP::enter() {
|
||||
while(status.clock_speed != 2 && sample_buffer < sample_buffer_end) op_step();
|
||||
if (status.clock_speed == 2) {
|
||||
while(sample_buffer < sample_buffer_end) {
|
||||
clock -= (sample_buffer_end - sample_buffer) * 24 * 16;
|
||||
while(status.clock_speed != 2 && clock < 0) op_step();
|
||||
if(status.clock_speed == 2) step(-clock);
|
||||
synchronize_dsp();
|
||||
if (sample_buffer < sample_buffer_end) {
|
||||
dsp.clock -= 24 * 32 * (sample_buffer_end - sample_buffer) / 2;
|
||||
synchronize_dsp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SMP::render(int16_t * buffer, unsigned count) {
|
||||
while (count > 4096) {
|
||||
sample_buffer = buffer;
|
||||
sample_buffer_end = buffer + 4096;
|
||||
buffer += 4096;
|
||||
count -= 4096;
|
||||
enter();
|
||||
}
|
||||
sample_buffer = buffer;
|
||||
sample_buffer_end = buffer + count;
|
||||
enter();
|
||||
|
@ -46,14 +51,16 @@ void SMP::skip(unsigned count) {
|
|||
enter();
|
||||
}
|
||||
|
||||
void SMP::sample(int16_t left, int16_t right) {
|
||||
bool SMP::sample(int16_t left, int16_t right) {
|
||||
if ( sample_buffer_end - sample_buffer < 2 ) return false;
|
||||
if ( sample_buffer > ((const int16_t *)0) + 4096 ) {
|
||||
if ( sample_buffer < sample_buffer_end ) *sample_buffer++ = left;
|
||||
if ( sample_buffer < sample_buffer_end ) *sample_buffer++ = right;
|
||||
*sample_buffer++ = left;
|
||||
*sample_buffer++ = right;
|
||||
}
|
||||
else if ( sample_buffer < sample_buffer_end ){
|
||||
else {
|
||||
sample_buffer += 2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SMP::power() {
|
||||
|
|
|
@ -47,7 +47,7 @@ private:
|
|||
int16_t * sample_buffer;
|
||||
int16_t const* sample_buffer_end;
|
||||
public:
|
||||
void sample( int16_t, int16_t );
|
||||
bool sample( int16_t, int16_t );
|
||||
|
||||
SMP();
|
||||
~SMP();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
void SMP::add_clocks(unsigned clocks) {
|
||||
step(clocks);
|
||||
synchronize_dsp();
|
||||
//synchronize_dsp();
|
||||
}
|
||||
|
||||
void SMP::cycle_edge() {
|
||||
|
|
Loading…
Reference in New Issue