summaryrefslogtreecommitdiff
path: root/plugins/gme/Game_Music_Emu-0.5.2/gme/Snes_Spc.h
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gme/Game_Music_Emu-0.5.2/gme/Snes_Spc.h')
-rw-r--r--plugins/gme/Game_Music_Emu-0.5.2/gme/Snes_Spc.h121
1 files changed, 121 insertions, 0 deletions
diff --git a/plugins/gme/Game_Music_Emu-0.5.2/gme/Snes_Spc.h b/plugins/gme/Game_Music_Emu-0.5.2/gme/Snes_Spc.h
new file mode 100644
index 00000000..b558fb71
--- /dev/null
+++ b/plugins/gme/Game_Music_Emu-0.5.2/gme/Snes_Spc.h
@@ -0,0 +1,121 @@
+// Super Nintendo (SNES) SPC-700 APU Emulator
+
+// Game_Music_Emu 0.5.2
+#ifndef SNES_SPC_H
+#define SNES_SPC_H
+
+#include "blargg_common.h"
+#include "Spc_Cpu.h"
+#include "Spc_Dsp.h"
+
+class Snes_Spc {
+public:
+
+ // Load copy of SPC data into emulator. Clear echo buffer if 'clear_echo' is true.
+ enum { spc_file_size = 0x10180 };
+ blargg_err_t load_spc( const void* spc, long spc_size );
+
+ // Generate 'count' samples and optionally write to 'buf'. Count must be even.
+ // Sample output is 16-bit 32kHz, signed stereo pairs with the left channel first.
+ typedef short sample_t;
+ blargg_err_t play( long count, sample_t* buf = NULL );
+
+// Optional functionality
+
+ // Load copy of state into emulator.
+ typedef Spc_Cpu::registers_t registers_t;
+ blargg_err_t load_state( const registers_t& cpu_state, const void* ram_64k,
+ const void* dsp_regs_128 );
+
+ // Clear echo buffer, useful because many tracks have junk in the buffer.
+ void clear_echo();
+
+ // Mute voice n if bit n (1 << n) of mask is set
+ enum { voice_count = Spc_Dsp::voice_count };
+ void mute_voices( int mask );
+
+ // Skip forward by the specified number of samples (64000 samples = 1 second)
+ blargg_err_t skip( long count );
+
+ // Set gain, where 1.0 is normal. When greater than 1.0, output is clamped the
+ // 16-bit sample range.
+ void set_gain( double );
+
+ // If true, prevent channels and global volumes from being phase-negated
+ void disable_surround( bool disable = true );
+
+ // Set 128 bytes to use for IPL boot ROM. Makes copy. Default is zero filled,
+ // to avoid including copyrighted code from the SPC-700.
+ void set_ipl_rom( const void* );
+
+ void set_tempo( double );
+
+public:
+ Snes_Spc();
+ typedef BOOST::uint8_t uint8_t;
+private:
+ // timers
+ struct Timer
+ {
+ spc_time_t next_tick;
+ int period;
+ int count;
+ int divisor;
+ int enabled;
+ int counter;
+
+ void run_until_( spc_time_t );
+ void run_until( spc_time_t time )
+ {
+ if ( time >= next_tick )
+ run_until_( time );
+ }
+ };
+ enum { timer_count = 3 };
+ Timer timer [timer_count];
+
+ // hardware
+ int extra_cycles;
+ spc_time_t time() const;
+ int read( spc_addr_t );
+ void write( spc_addr_t, int );
+ friend class Spc_Cpu;
+
+ // dsp
+ sample_t* sample_buf;
+ sample_t* buf_end; // to do: remove this once possible bug resolved
+ spc_time_t next_dsp;
+ Spc_Dsp dsp;
+ int keys_pressed;
+ int keys_released;
+ sample_t skip_sentinel [1]; // special value for play() passed by skip()
+ void run_dsp( spc_time_t );
+ void run_dsp_( spc_time_t );
+ bool echo_accessed;
+ void check_for_echo_access( spc_addr_t );
+
+ // boot rom
+ enum { rom_size = 64 };
+ enum { rom_addr = 0xFFC0 };
+ bool rom_enabled;
+ void enable_rom( bool );
+
+ // CPU and RAM (at end because it's large)
+ Spc_Cpu cpu;
+ uint8_t extra_ram [rom_size];
+ struct {
+ // padding to catch jumps before beginning or past end
+ uint8_t padding1 [0x100];
+ uint8_t ram [0x10000];
+ uint8_t padding2 [0x100];
+ } mem;
+ uint8_t boot_rom [rom_size];
+};
+
+inline void Snes_Spc::disable_surround( bool disable ) { dsp.disable_surround( disable ); }
+
+inline void Snes_Spc::mute_voices( int mask ) { dsp.mute_voices( mask ); }
+
+inline void Snes_Spc::set_gain( double v ) { dsp.set_gain( v ); }
+
+#endif