view snes_spc.txt @ 9:477c36226481 tip

added old scripts for historical interest.
author Robert McIntyre <rlm@mit.edu>
date Fri, 21 Oct 2011 07:46:18 -0700
parents e38dacceb958
children
line wrap: on
line source
1 snes_spc 0.9.0: SNES SPC-700 APU Emulator
2 -----------------------------------------
3 Author : Shay Green <gblargg@gmail.com>
4 Website: http://www.slack.net/~ant/
5 Forum : http://groups.google.com/group/blargg-sound-libs
6 License: GNU Lesser General Public License (LGPL)
9 Contents
10 --------
11 * C and C++ Interfaces
12 * Overview
13 * Full SPC Emulation
14 * DSP Emulation
15 * SPC Music Playback
16 * State Copying
17 * Library Compilation
18 * Error handling
19 * Solving Problems
20 * Accurate S-DSP Limitations
21 * Fast S-DSP Limitations
22 * S-SMP Limitations
23 * To Do
24 * Thanks
27 C and C++ Interfaces
28 --------------------
29 The library includes a C interface in spc.h and dsp.h, which can be used
30 from C and C++. This C interface is referred to in the following
31 documentation. If you're building this as a shared library (rather than
32 linking statically), you should use the C interface since it will change
33 less in future versions.
35 The native C++ interface is in the header files SNES_SPC.h, SPC_DSP.h,
36 and SPC_Filter.h, and the two interfaces can be freely mixed in C++
37 code. Conversion between the two interfaces generally follows a pattern:
39 C interface C++ interface
40 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
41 SNES_SPC* spc; SNES_SPC* spc;
43 spc = spc_new(); spc = new SNES_SPC;
45 spc_play( spc, count, buf ); spc->play( count, buf );
47 spc_sample_rate SNES_SPC::sample_rate
49 spc_delete( spc ); delete spc;
52 Overview
53 --------
54 There are three main roles for this library:
55 * Full SPC emulation in a SNES emulator
56 * DSP emulation in a SNES emulator (where you emulate the SMP CPU)
57 * SPC playback in an SPC music file player
59 Each of these uses are described separately below.
62 Full SPC Emulation
63 ------------------
64 See spc.h for full function reference (SNES_SPC.h if using C++).
66 * Create SPC emulator with spc_new() and check for NULL.
68 * Call spc_init_rom() with a pointer to the 64-byte IPL ROM dump (not
69 included with library).
71 * When your emulated SNES is powered on, call spc_reset(). When the
72 reset switch is pressed, call spc_soft_reset().
74 * Call spc_set_output() with your output buffer, then do emulation.
76 * When the SNES CPU accesses APU ports, call spc_read_port() and
77 spc_write_port().
79 * When your emulator's timebase is going back to 0, call
80 spc_end_frame(), usually at the end of a video frame or scanline.
82 * Periodically play samples from your buffer. Use spc_sample_count() to
83 find out how many samples have been written, then spc_set_output() after
84 you've made more space in your buffer.
86 * Save/load full emulator state with spc_copy_state().
88 * You can save as an SPC music file with spc_save_spc().
90 * When done, use spc_delete() to free memory.
93 DSP Emulation
94 -------------
95 See dsp.h for full function reference (SPC_DSP.h if using C++).
97 * Create DSP emulator with spc_dsp_new() and check for NULL.
99 * Let the DSP know where your 64K RAM is with spc_dsp_init().
101 * When your emulated SNES is powered on, call spc_dsp_reset(). When the
102 reset switch is pressed, call spc_dsp_soft_reset().
104 * Call spc_dsp_set_output() with your output buffer, then do emulation.
106 * Use spc_dsp_run() to run DSP for specified number of clocks (1024000
107 per second). Every 32 clocks a pair of samples is added to your output
108 buffer.
110 * Use spc_dsp_read() and spc_dsp_write() to handle DSP reads/writes from
111 the S-SMP. Before calling these always catch the DSP up to present time
112 with spc_dsp_run().
114 * Periodically play samples from your buffer. Use spc_dsp_sample_count()
115 to find out how many samples have been written, then
116 spc_dsp_set_output() after you've made more space in your buffer.
118 * Use spc_dsp_copy_state() to save/load full DSP state.
120 * When done, use spc_delete() to free memory.
123 SPC Music Playback
124 ------------------
125 See spc.h for full function reference (SNES_SPC.h if using C++).
127 * Create SPC emulator with spc_new() and check for NULL.
129 * Load SPC with spc_load_spc() and check for error.
131 * Optionally cear echo buffer with spc_clear_echo(). Many SPCs have
132 garbage in echo buffer, which causes noise at the beginning.
134 * Generate samples as needed with spc_play().
136 * When done, use spc_delete() to free memory.
138 * For a more complete game music playback library, use Game_Music_Emu
141 State Copying
142 -------------
143 The SPC and DSP modules include state save/load functions. They take a
144 pointer to a pointer to a buffer to store state, and a copy function.
145 This copy function can either copy data to the buffer or from it,
146 allowing state save and restore with the same library function. The
147 internal save state format allows for future expansion without making
148 previous save states unusable.
150 The SPC save state format puts the most important parts first to make it
151 easier to manually examine. It's organized as follows:
153 Offset Size Data
154 - - - - - - - - - - - - - - - - - -
155 0 $10000 SPC RAM
156 $10000 $10 SMP $F0-$FF registers
157 $10010 4 SMP $F4-$F8 output registers
158 $10014 2 PC
159 $10016 1 A
160 $10017 1 X
161 $10018 1 Y
162 $10019 1 PSW
163 $1001A 1 SP
164 $1001B 5 internal
165 $10020 $80 DSP registers
166 $100A0 ... internal
169 Library Compilation
170 -------------------
171 While this library is in C++, it has been written to easily link in a C
172 program *without* needing the standard C++ library. It doesn't use
173 exception handling or run-time type information (RTTI), so you can
174 disable these in your C++ compiler to increase efficiency.
176 If you're building a shared library (DLL), I recommend only exporting
177 the C interfaces in spc.h and dsp.h, as the C++ interfaces expose
178 implementation details that will break link compatibility across
179 versions.
181 If you're using C and compiling with GCC, I recommend the following
182 command-line options when compiling the library source, otherwise GCC
183 will insert calls to the standard C++ library and require that it be
184 linked in:
186 -fno-rtti -fno-exceptions
188 For maximum optimization, see the NDEBUG and BLARGG_NONPORTABLE options
189 in blargg_config. If using GCC, you can enable these by adding the
190 following command-line options when you invoke gcc. If you encounter
191 problems, try without -DBLARGG_NONPORTABLE; if that works, contact me so
192 I can figure out why BLARGG_NONPORTABLE was causing it to fail.
194 -O3 -DNDEBUG -DBLARGG_NONPORTABLE -fno-rtti -fno-exceptions
198 Error handling
199 --------------
200 Functions which can fail have a return type of spc_err_t (blargg_err_t
201 in the C++ interfaces), which is a pointer to an error string (const
202 char*). If a function is successful it returns NULL. Errors that you can
203 easily avoid are checked with debug assertions; spc_err_t return values
204 are only used for genuine run-time errors that can't be easily predicted
205 in advance (out of memory, I/O errors, incompatible file data). Your
206 code should check all error values.
208 To improve usability for C programmers, C++ programmers unfamiliar with
209 exceptions, and compatibility with older C++ compilers, the library does
210 *not* throw any C++ exceptions and uses malloc() instead of the standard
211 operator new. This means that you *must* check for NULL when creating a
212 library object with the new operator.
215 Solving Problems
216 ----------------
217 If you're having problems, try the following:
219 * If you're getting garbled sound, try this simple siren generator in
220 place of your call to play(). This will quickly tell whether the problem
221 is in the library or in your code.
223 static void play_siren( long count, short* out )
224 {
225 static double a, a2;
226 while ( count-- )
227 *out++ = 0x2000 * sin( a += .1 + .05*sin( a2+=.00005 ) );
228 }
230 * Enable debugging support in your environment. This enables assertions
231 and other run-time checks.
233 * Turn the compiler's optimizer is off. Sometimes an optimizer generates
234 bad code.
236 * If multiple threads are being used, ensure that only one at a time is
237 accessing a given set of objects from the library. This library is not
238 in general thread-safe, though independent objects can be used in
239 separate threads.
241 * If all else fails, see if the demos work.
244 Accurate S-DSP Limitations
245 --------------------------
246 * Power-up and soft reset behavior might have slight inaccuracies.
248 * Muting (FLG bit 6) behavior when toggling bit very rapidly is not
249 emulated properly.
251 * No other known inaccuracies. Has passed 100+ strenuous tests.
254 Fast S-DSP Limitations
255 ----------------------
256 * Uses faster sample calculations except in cases where exact value is
257 actually important (BRR decoding, and gaussian interpolation combined
258 with pitch modulation).
260 * Stops decoding BRR data when a voice's envelope has released to
261 silence.
263 * Emulates 32 clocks at a time, so DSP register and memory accesses are
264 all done in a bunch rather than spread out. Even though, some clever
265 code makes register accesses separated by 40 or so clocks occur with
266 cycle-accurate timing.
269 S-SMP Limitations
270 -----------------
271 * Opcode fetches and indirect pointers are always read directly from
272 memory, even for the $F0-$FF region, and the DSP is not caught up for
273 these fetches.
275 * Attempts to perversely execute data in registers or an area being
276 modified by echo will not be emulated properly.
278 * Has not been thoroughly tested.
280 * Test register ($F0) is not implemented.
282 * Echo buffer can overwrite IPL ROM area, and does not correctly update
283 extra RAM there.
286 To Do
287 -----
288 * I'd like feedback on the interface and any ways to improve it. In
289 particular, the differing features between the accurate and fast DSP
290 emulators might make it harder to cleanly switch between them without
291 modifying source code.
293 * Finish thorough tests on SMP memory access times.
295 * Finish thorough tests on SMP instruction behavior (flags, registers).
297 * Finish thorough tests on SMP timers.
299 * Finish power-up and reset behavior testing.
301 * Come up with best starting conditions to play an SPC and implement in
302 hardware SNES SPC player for verification.
305 Thanks
306 ------
307 Thanks to Anti-Resonance's SPC2ROM and help getting SPCs playing on my
308 SNES in the first place, then Brad Martin's openspc and Chris Moeller's
309 openspc++ C++ adaptation, giving me a good SPC emulator to start with
310 several years ago. Thanks to Richard Bannister, Mahendra Tallur, Shazz,
311 nenolod, theHobbit, Johan Samuelsson, nes6502, and Micket for helping
312 test my Game_Music_Emu library. Thanks to hcs for help in converting to
313 C for the Rockbox port. Thanks to byuu (bsnes author) and pagefault and
314 Nach (zsnes team) for testing and using my new rewritten DSP in their
315 emulators. Thanks to anomie for his good SNES documentation and
316 discussions with me to keep it up to date with my latest findings.
317 --
318 Shay Green <gblargg@gmail.com>