From e67a58812b4704785a4314ff918b3d078be5b236 Mon Sep 17 00:00:00 2001 From: Daryl Borth Date: Wed, 22 Aug 2018 10:35:43 -0600 Subject: [PATCH] revert recent APU changes. they would randomly compile "wrong" - out <= &m.extra_buf [extra_size] assert would trigger --- source/snes9x/apu/SNES_SPC.cpp | 23 ++++++++++----- source/snes9x/apu/SNES_SPC.h | 18 ++++++++--- source/snes9x/apu/SNES_SPC_misc.cpp | 2 +- source/snes9x/apu/SPC_CPU.h | 18 +++++++---- source/snes9x/apu/SPC_DSP.cpp | 8 ++--- source/snes9x/apu/SPC_DSP.h | 9 ++++-- source/snes9x/apu/blargg_common.h | 46 ++++++++++++++++++++++++++++- source/snes9x/apu/blargg_endian.h | 32 ++++++++++---------- 8 files changed, 115 insertions(+), 41 deletions(-) diff --git a/source/snes9x/apu/SNES_SPC.cpp b/source/snes9x/apu/SNES_SPC.cpp index c4536c0..38b181b 100644 --- a/source/snes9x/apu/SNES_SPC.cpp +++ b/source/snes9x/apu/SNES_SPC.cpp @@ -391,22 +391,25 @@ void SNES_SPC::cpu_write_smp_reg( int data, rel_time_t time, uint16_t addr ) cpu_write_smp_reg_( data, time, addr ); } -void SNES_SPC::cpu_write_high( int data, uint8_t i ) +void SNES_SPC::cpu_write_high( int data, int i, rel_time_t time ) { m.hi_ram [i] = (uint8_t) data; + if ( m.rom_enabled ) RAM [i + rom_addr] = m.rom [i]; // restore overwritten ROM } +int const bits_in_int = CHAR_BIT * sizeof (int); + void SNES_SPC::cpu_write( int data, uint16_t addr, rel_time_t time ) { MEM_ACCESS( time, addr ) // RAM RAM [addr] = (uint8_t) data; - if ( addr >= 0xF0 ) // 64% + int reg = addr - 0xF0; + if ( reg >= 0 ) // 64% { - const uint16_t reg = addr - 0xF0; // $F0-$FF if ( reg < reg_count ) // 87% { @@ -420,12 +423,18 @@ void SNES_SPC::cpu_write( int data, uint16_t addr, rel_time_t time ) #endif // Registers other than $F2 and $F4-$F7 - if ( reg != 2 && (reg < 4 || reg > 7) ) // 36% + //if ( reg != 2 && reg != 4 && reg != 5 && reg != 6 && reg != 7 ) + // TODO: this is a bit on the fragile side + if ( ((~0x2F00 << (bits_in_int - 16)) << reg) < 0 ) // 36% cpu_write_smp_reg( data, time, reg ); } // High mem/address wrap-around - else if ( addr >= rom_addr ) // 1% in IPL ROM area or address wrapped around - cpu_write_high( data, addr - rom_addr ); + else + { + reg -= rom_addr - 0xF0; + if ( reg >= 0 ) // 1% in IPL ROM area or address wrapped around + cpu_write_high( data, reg, time ); + } } } @@ -490,7 +499,7 @@ int SNES_SPC::cpu_read( uint16_t addr, rel_time_t time ) // Prefix and suffix for CPU emulator function #define SPC_CPU_RUN_FUNC \ -uint8_t* SNES_SPC::run_until_( time_t end_time )\ +BOOST::uint8_t* SNES_SPC::run_until_( time_t end_time )\ {\ rel_time_t rel_time = m.spc_time - end_time;\ /*assert( rel_time <= 0 );*/\ diff --git a/source/snes9x/apu/SNES_SPC.h b/source/snes9x/apu/SNES_SPC.h index e615a4e..9013eb1 100644 --- a/source/snes9x/apu/SNES_SPC.h +++ b/source/snes9x/apu/SNES_SPC.h @@ -10,13 +10,15 @@ #include "blargg_endian.h" #ifdef DEBUGGER -#include "../snes9x.h" -#include "../display.h" -#include "../debug.h" +#include "snes9x.h" +#include "display.h" +#include "debug.h" #endif struct SNES_SPC { public: + typedef BOOST::uint8_t uint8_t; + // Must be called once before using blargg_err_t init(); @@ -65,6 +67,10 @@ public: enum { voice_count = 8 }; void mute_voices( int mask ); + // If true, prevents channels and global volumes from being phase-negated. + // Only supported by fast DSP. + void disable_surround( bool disable = true ); + // Sets tempo, where tempo_unit = normal, tempo_unit / 2 = half speed, etc. enum { tempo_unit = 0x100 }; void set_tempo( int ); @@ -129,6 +135,8 @@ public: public: BLARGG_DISABLE_NOTHROW + typedef BOOST::uint16_t uint16_t; + // Time relative to m_spc_time. Speeds up code a bit by eliminating need to // constantly add m_spc_time to time from CPU. CPU uses time that ends at // 0 to eliminate reloading end time every instruction. It pays off. @@ -238,7 +246,7 @@ private: void dsp_write ( int data, rel_time_t ); void cpu_write_smp_reg_( int data, rel_time_t, uint16_t addr ); void cpu_write_smp_reg ( int data, rel_time_t, uint16_t addr ); - void cpu_write_high ( int data, uint8_t i ); + void cpu_write_high ( int data, int i, rel_time_t ); void cpu_write ( int data, uint16_t addr, rel_time_t ); int cpu_read_smp_reg ( int i, rel_time_t ); int cpu_read ( uint16_t addr, rel_time_t ); @@ -292,6 +300,8 @@ inline void SNES_SPC::write_port( time_t t, int port, int data ) } inline void SNES_SPC::mute_voices( int mask ) { dsp.mute_voices( mask ); } + +inline void SNES_SPC::disable_surround( bool disable ) { dsp.disable_surround( disable ); } #if !SPC_NO_COPY_STATE_FUNCS inline bool SNES_SPC::check_kon() { return dsp.check_kon(); } diff --git a/source/snes9x/apu/SNES_SPC_misc.cpp b/source/snes9x/apu/SNES_SPC_misc.cpp index 3d3c9c7..0071362 100644 --- a/source/snes9x/apu/SNES_SPC_misc.cpp +++ b/source/snes9x/apu/SNES_SPC_misc.cpp @@ -409,7 +409,7 @@ void SNES_SPC::dsp_set_stereo_switch( int value ) dsp.set_stereo_switch( value ); } -uint8_t SNES_SPC::dsp_reg_value( int ch, int addr ) +SNES_SPC::uint8_t SNES_SPC::dsp_reg_value( int ch, int addr ) { return dsp.reg_value( ch, addr ); } diff --git a/source/snes9x/apu/SPC_CPU.h b/source/snes9x/apu/SPC_CPU.h index 4ae168c..9fbc101 100644 --- a/source/snes9x/apu/SPC_CPU.h +++ b/source/snes9x/apu/SPC_CPU.h @@ -66,7 +66,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define READ_DP( time, addr ) READ ( time, DP_ADDR( addr ) ) #define WRITE_DP( time, addr, data ) WRITE( time, DP_ADDR( addr ), data ) -#define READ_PROG16( addr ) (RAM [(addr) & 0xffff] | (RAM [((addr) + 1) & 0xffff] << 8)) +#define READ_PROG16( addr ) (RAM [addr & 0xffff] | (RAM [(addr + 1) & 0xffff] << 8)) #define SET_PC( n ) (pc = n) #define GET_PC() (pc) @@ -205,10 +205,10 @@ loop: #define BRANCH( cond )\ {\ pc++;\ - pc += (int8_t) data;\ + pc += (BOOST::int8_t) data;\ if ( cond )\ goto loop;\ - pc -= (int8_t) data;\ + pc -= (BOOST::int8_t) data;\ rel_time -= 2;\ goto loop;\ } @@ -261,7 +261,8 @@ loop: REGS [i] = (uint8_t) data; // Registers other than $F2 and $F4-$F7 - if ( i != 2 && (i < 4 || i > 7)) // 12% + //if ( i != 2 && i != 4 && i != 5 && i != 6 && i != 7 ) + if ( ((~0x2F00 << (bits_in_int - 16)) << i) < 0 ) // 12% cpu_write_smp_reg( data, rel_time, i ); } } @@ -844,7 +845,7 @@ loop: // 12. BRANCHING COMMANDS case 0x2F: // BRA rel - pc += (int8_t) data; + pc += (BOOST::int8_t) data; goto inc_pc_loop; case 0x30: // BMI @@ -1148,8 +1149,11 @@ loop: case 0xFF:{// STOP // handle PC wrap-around - if ( pc == 0x0000 ) + unsigned addr = GET_PC() - 1; + if ( addr >= 0x10000 ) { + addr &= 0xFFFF; + SET_PC( addr ); dprintf( "SPC: PC wrapped around\n" ); goto loop; } @@ -1168,6 +1172,8 @@ out_of_time: stop: // Uncache registers + if ( GET_PC() >= 0x10000 ) + dprintf( "SPC: PC wrapped around\n" ); m.cpu_regs.pc = (uint16_t) GET_PC(); m.cpu_regs.sp = ( uint8_t) GET_SP(); m.cpu_regs.a = ( uint8_t) a; diff --git a/source/snes9x/apu/SPC_DSP.cpp b/source/snes9x/apu/SPC_DSP.cpp index b10ebc8..8fad2f5 100644 --- a/source/snes9x/apu/SPC_DSP.cpp +++ b/source/snes9x/apu/SPC_DSP.cpp @@ -27,11 +27,11 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #endif // TODO: add to blargg_endian.h -#define GET_LE16SA( addr ) ((int16_t) GET_LE16( addr )) +#define GET_LE16SA( addr ) ((BOOST::int16_t) GET_LE16( addr )) #define GET_LE16A( addr ) GET_LE16( addr ) #define SET_LE16A( addr, data ) SET_LE16( addr, data ) -static uint8_t const initial_regs [SPC_DSP::register_count] = +static BOOST::uint8_t const initial_regs [SPC_DSP::register_count] = { 0x45,0x8B,0x5A,0x9A,0xE4,0x82,0x1B,0x78,0x00,0x00,0xAA,0x96,0x89,0x0E,0xE0,0x80, 0x2A,0x49,0x3D,0xBA,0x14,0xA0,0xAC,0xC5,0x00,0x00,0x51,0xBB,0x9C,0x4E,0x7B,0xFF, @@ -906,7 +906,7 @@ void SPC_State_Copier::copy( void* state, size_t size ) int SPC_State_Copier::copy_int( int state, int size ) { - uint8_t s [2]; + BOOST::uint8_t s [2]; SET_LE16( s, state ); func( buf, &s, size ); return GET_LE16( s ); @@ -1057,7 +1057,7 @@ void SPC_DSP::set_stereo_switch( int value ) stereo_switch = value; } -uint8_t SPC_DSP::reg_value( int ch, int addr ) +SPC_DSP::uint8_t SPC_DSP::reg_value( int ch, int addr ) { return m.voices[ch].regs[addr]; } diff --git a/source/snes9x/apu/SPC_DSP.h b/source/snes9x/apu/SPC_DSP.h index 3be6ee8..61d05ab 100644 --- a/source/snes9x/apu/SPC_DSP.h +++ b/source/snes9x/apu/SPC_DSP.h @@ -10,6 +10,8 @@ extern "C" { typedef void (*dsp_copy_func_t)( unsigned char** io, void* state, s class SPC_DSP { public: + typedef BOOST::uint8_t uint8_t; + // Setup // Initializes DSP and has it use the 64K RAM provided @@ -109,6 +111,9 @@ public: public: BLARGG_DISABLE_NOTHROW + typedef BOOST::int8_t int8_t; + typedef BOOST::int16_t int16_t; + enum { echo_hist_size = 8 }; enum env_mode_t { env_release, env_attack, env_decay, env_sustain }; @@ -305,8 +310,8 @@ public: #define SPC_COPY( type, state )\ {\ - state = (type) copier.copy_int( state, sizeof (type) );\ - assert( (type) state == state );\ + state = (BOOST::type) copier.copy_int( state, sizeof (BOOST::type) );\ + assert( (BOOST::type) state == state );\ } #endif diff --git a/source/snes9x/apu/blargg_common.h b/source/snes9x/apu/blargg_common.h index e6448af..775d7f3 100644 --- a/source/snes9x/apu/blargg_common.h +++ b/source/snes9x/apu/blargg_common.h @@ -134,8 +134,52 @@ public: typedef unsigned blargg_ulong; #endif +// BOOST::int8_t etc. + // HAVE_STDINT_H: If defined, use for int8_t etc. -#include +#if defined (HAVE_STDINT_H) + #include + #define BOOST + +// HAVE_INTTYPES_H: If defined, use for int8_t etc. +#elif defined (HAVE_INTTYPES_H) + #include + #define BOOST + +#else + struct BOOST + { + #if UCHAR_MAX == 0xFF && SCHAR_MAX == 0x7F + typedef signed char int8_t; + typedef unsigned char uint8_t; + #else + // No suitable 8-bit type available + typedef struct see_blargg_common_h int8_t; + typedef struct see_blargg_common_h uint8_t; + #endif + + #if USHRT_MAX == 0xFFFF + typedef short int16_t; + typedef unsigned short uint16_t; + #else + // No suitable 16-bit type available + typedef struct see_blargg_common_h int16_t; + typedef struct see_blargg_common_h uint16_t; + #endif + + #if ULONG_MAX == 0xFFFFFFFF + typedef long int32_t; + typedef unsigned long uint32_t; + #elif UINT_MAX == 0xFFFFFFFF + typedef int int32_t; + typedef unsigned int uint32_t; + #else + // No suitable 32-bit type available + typedef struct see_blargg_common_h int32_t; + typedef struct see_blargg_common_h uint32_t; + #endif + }; +#endif #endif #endif diff --git a/source/snes9x/apu/blargg_endian.h b/source/snes9x/apu/blargg_endian.h index 00e9e38..0b4b5f1 100644 --- a/source/snes9x/apu/blargg_endian.h +++ b/source/snes9x/apu/blargg_endian.h @@ -122,15 +122,15 @@ inline void set_be32( void* p, blargg_ulong n ) #if BLARGG_NONPORTABLE // Optimized implementation if byte order is known #if BLARGG_LITTLE_ENDIAN - #define GET_LE16( addr ) (*(uint16_t*) (addr)) - #define GET_LE32( addr ) (*(uint32_t*) (addr)) - #define SET_LE16( addr, data ) (void) (*(uint16_t*) (addr) = (data)) - #define SET_LE32( addr, data ) (void) (*(uint32_t*) (addr) = (data)) + #define GET_LE16( addr ) (*(BOOST::uint16_t*) (addr)) + #define GET_LE32( addr ) (*(BOOST::uint32_t*) (addr)) + #define SET_LE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data)) + #define SET_LE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data)) #elif BLARGG_BIG_ENDIAN - #define GET_BE16( addr ) (*(uint16_t*) (addr)) - #define GET_BE32( addr ) (*(uint32_t*) (addr)) - #define SET_BE16( addr, data ) (void) (*(uint16_t*) (addr) = (data)) - #define SET_BE32( addr, data ) (void) (*(uint32_t*) (addr) = (data)) + #define GET_BE16( addr ) (*(BOOST::uint16_t*) (addr)) + #define GET_BE32( addr ) (*(BOOST::uint32_t*) (addr)) + #define SET_BE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data)) + #define SET_BE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data)) #if BLARGG_CPU_POWERPC // PowerPC has special byte-reversed instructions @@ -171,13 +171,13 @@ inline void set_be32( void* p, blargg_ulong n ) // auto-selecting versions -inline void set_le( uint16_t* p, unsigned n ) { SET_LE16( p, n ); } -inline void set_le( uint32_t* p, blargg_ulong n ) { SET_LE32( p, n ); } -inline void set_be( uint16_t* p, unsigned n ) { SET_BE16( p, n ); } -inline void set_be( uint32_t* p, blargg_ulong n ) { SET_BE32( p, n ); } -inline unsigned get_le( uint16_t* p ) { return GET_LE16( p ); } -inline blargg_ulong get_le( uint32_t* p ) { return GET_LE32( p ); } -inline unsigned get_be( uint16_t* p ) { return GET_BE16( p ); } -inline blargg_ulong get_be( uint32_t* p ) { return GET_BE32( p ); } +inline void set_le( BOOST::uint16_t* p, unsigned n ) { SET_LE16( p, n ); } +inline void set_le( BOOST::uint32_t* p, blargg_ulong n ) { SET_LE32( p, n ); } +inline void set_be( BOOST::uint16_t* p, unsigned n ) { SET_BE16( p, n ); } +inline void set_be( BOOST::uint32_t* p, blargg_ulong n ) { SET_BE32( p, n ); } +inline unsigned get_le( BOOST::uint16_t* p ) { return GET_LE16( p ); } +inline blargg_ulong get_le( BOOST::uint32_t* p ) { return GET_LE32( p ); } +inline unsigned get_be( BOOST::uint16_t* p ) { return GET_BE16( p ); } +inline blargg_ulong get_be( BOOST::uint32_t* p ) { return GET_BE32( p ); } #endif