diff snes_spc.txt @ 0:e38dacceb958

initial import
author Robert McIntyre <rlm@mit.edu>
date Fri, 21 Oct 2011 05:53:11 -0700
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/snes_spc.txt	Fri Oct 21 05:53:11 2011 -0700
     1.3 @@ -0,0 +1,318 @@
     1.4 +snes_spc 0.9.0: SNES SPC-700 APU Emulator
     1.5 +-----------------------------------------
     1.6 +Author : Shay Green <gblargg@gmail.com>
     1.7 +Website: http://www.slack.net/~ant/
     1.8 +Forum  : http://groups.google.com/group/blargg-sound-libs
     1.9 +License: GNU Lesser General Public License (LGPL)
    1.10 +
    1.11 +
    1.12 +Contents
    1.13 +--------
    1.14 +* C and C++ Interfaces
    1.15 +* Overview
    1.16 +* Full SPC Emulation
    1.17 +* DSP Emulation
    1.18 +* SPC Music Playback
    1.19 +* State Copying
    1.20 +* Library Compilation
    1.21 +* Error handling
    1.22 +* Solving Problems
    1.23 +* Accurate S-DSP Limitations
    1.24 +* Fast S-DSP Limitations
    1.25 +* S-SMP Limitations
    1.26 +* To Do
    1.27 +* Thanks
    1.28 +
    1.29 +
    1.30 +C and C++ Interfaces
    1.31 +--------------------
    1.32 +The library includes a C interface in spc.h and dsp.h, which can be used
    1.33 +from C and C++. This C interface is referred to in the following
    1.34 +documentation. If you're building this as a shared library (rather than
    1.35 +linking statically), you should use the C interface since it will change
    1.36 +less in future versions.
    1.37 +
    1.38 +The native C++ interface is in the header files SNES_SPC.h, SPC_DSP.h,
    1.39 +and SPC_Filter.h, and the two interfaces can be freely mixed in C++
    1.40 +code. Conversion between the two interfaces generally follows a pattern:
    1.41 +
    1.42 +	C interface                     C++ interface
    1.43 +	- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    1.44 +	SNES_SPC* spc;                  SNES_SPC* spc;
    1.45 +	
    1.46 +	spc = spc_new();                spc = new SNES_SPC;
    1.47 +	
    1.48 +	spc_play( spc, count, buf );    spc->play( count, buf );
    1.49 +	
    1.50 +	spc_sample_rate                 SNES_SPC::sample_rate
    1.51 +	
    1.52 +	spc_delete( spc );              delete spc;
    1.53 +
    1.54 +
    1.55 +Overview
    1.56 +--------
    1.57 +There are three main roles for this library:
    1.58 +* Full SPC emulation in a SNES emulator
    1.59 +* DSP emulation in a SNES emulator (where you emulate the SMP CPU)
    1.60 +* SPC playback in an SPC music file player
    1.61 +
    1.62 +Each of these uses are described separately below.
    1.63 +
    1.64 +
    1.65 +Full SPC Emulation
    1.66 +------------------
    1.67 +See spc.h for full function reference (SNES_SPC.h if using C++).
    1.68 +
    1.69 +* Create SPC emulator with spc_new() and check for NULL.
    1.70 +
    1.71 +* Call spc_init_rom() with a pointer to the 64-byte IPL ROM dump (not
    1.72 +included with library).
    1.73 +
    1.74 +* When your emulated SNES is powered on, call spc_reset(). When the
    1.75 +reset switch is pressed, call spc_soft_reset().
    1.76 +
    1.77 +* Call spc_set_output() with your output buffer, then do emulation.
    1.78 +
    1.79 +* When the SNES CPU accesses APU ports, call spc_read_port() and
    1.80 +spc_write_port().
    1.81 +
    1.82 +* When your emulator's timebase is going back to 0, call
    1.83 +spc_end_frame(), usually at the end of a video frame or scanline.
    1.84 +
    1.85 +* Periodically play samples from your buffer. Use spc_sample_count() to
    1.86 +find out how many samples have been written, then spc_set_output() after
    1.87 +you've made more space in your buffer.
    1.88 +
    1.89 +* Save/load full emulator state with spc_copy_state().
    1.90 +
    1.91 +* You can save as an SPC music file with spc_save_spc().
    1.92 +
    1.93 +* When done, use spc_delete() to free memory.
    1.94 +
    1.95 +
    1.96 +DSP Emulation
    1.97 +-------------
    1.98 +See dsp.h for full function reference (SPC_DSP.h if using C++).
    1.99 +
   1.100 +* Create DSP emulator with spc_dsp_new() and check for NULL.
   1.101 +
   1.102 +* Let the DSP know where your 64K RAM is with spc_dsp_init().
   1.103 +
   1.104 +* When your emulated SNES is powered on, call spc_dsp_reset(). When the
   1.105 +reset switch is pressed, call spc_dsp_soft_reset().
   1.106 +
   1.107 +* Call spc_dsp_set_output() with your output buffer, then do emulation.
   1.108 +
   1.109 +* Use spc_dsp_run() to run DSP for specified number of clocks (1024000
   1.110 +per second). Every 32 clocks a pair of samples is added to your output
   1.111 +buffer.
   1.112 +
   1.113 +* Use spc_dsp_read() and spc_dsp_write() to handle DSP reads/writes from
   1.114 +the S-SMP. Before calling these always catch the DSP up to present time
   1.115 +with spc_dsp_run().
   1.116 +
   1.117 +* Periodically play samples from your buffer. Use spc_dsp_sample_count()
   1.118 +to find out how many samples have been written, then
   1.119 +spc_dsp_set_output() after you've made more space in your buffer.
   1.120 +
   1.121 +* Use spc_dsp_copy_state() to save/load full DSP state.
   1.122 +
   1.123 +* When done, use spc_delete() to free memory.
   1.124 +
   1.125 +
   1.126 +SPC Music Playback
   1.127 +------------------
   1.128 +See spc.h for full function reference (SNES_SPC.h if using C++).
   1.129 +
   1.130 +* Create SPC emulator with spc_new() and check for NULL.
   1.131 +
   1.132 +* Load SPC with spc_load_spc() and check for error.
   1.133 +
   1.134 +* Optionally cear echo buffer with spc_clear_echo(). Many SPCs have
   1.135 +garbage in echo buffer, which causes noise at the beginning.
   1.136 +
   1.137 +* Generate samples as needed with spc_play().
   1.138 +
   1.139 +* When done, use spc_delete() to free memory.
   1.140 +
   1.141 +* For a more complete game music playback library, use Game_Music_Emu
   1.142 +
   1.143 +
   1.144 +State Copying
   1.145 +-------------
   1.146 +The SPC and DSP modules include state save/load functions. They take a
   1.147 +pointer to a pointer to a buffer to store state, and a copy function.
   1.148 +This copy function can either copy data to the buffer or from it,
   1.149 +allowing state save and restore with the same library function. The
   1.150 +internal save state format allows for future expansion without making
   1.151 +previous save states unusable.
   1.152 +
   1.153 +The SPC save state format puts the most important parts first to make it
   1.154 +easier to manually examine. It's organized as follows:
   1.155 +
   1.156 +Offset  Size    Data
   1.157 +- - - - - - - - - - - - - - - - - -
   1.158 +     0 $10000   SPC RAM
   1.159 +$10000    $10   SMP $F0-$FF registers
   1.160 +$10010      4   SMP $F4-$F8 output registers
   1.161 +$10014      2   PC
   1.162 +$10016      1   A
   1.163 +$10017      1   X
   1.164 +$10018      1   Y
   1.165 +$10019      1   PSW
   1.166 +$1001A      1   SP
   1.167 +$1001B      5   internal
   1.168 +$10020    $80   DSP registers
   1.169 +$100A0    ...   internal
   1.170 +
   1.171 +
   1.172 +Library Compilation
   1.173 +-------------------
   1.174 +While this library is in C++, it has been written to easily link in a C
   1.175 +program *without* needing the standard C++ library. It doesn't use
   1.176 +exception handling or run-time type information (RTTI), so you can
   1.177 +disable these in your C++ compiler to increase efficiency.
   1.178 +
   1.179 +If you're building a shared library (DLL), I recommend only exporting
   1.180 +the C interfaces in spc.h and dsp.h, as the C++ interfaces expose
   1.181 +implementation details that will break link compatibility across
   1.182 +versions.
   1.183 +
   1.184 +If you're using C and compiling with GCC, I recommend the following
   1.185 +command-line options when compiling the library source, otherwise GCC
   1.186 +will insert calls to the standard C++ library and require that it be
   1.187 +linked in:
   1.188 +
   1.189 +	-fno-rtti -fno-exceptions
   1.190 +
   1.191 +For maximum optimization, see the NDEBUG and BLARGG_NONPORTABLE options
   1.192 +in blargg_config. If using GCC, you can enable these by adding the
   1.193 +following command-line options when you invoke gcc. If you encounter
   1.194 +problems, try without -DBLARGG_NONPORTABLE; if that works, contact me so
   1.195 +I can figure out why BLARGG_NONPORTABLE was causing it to fail.
   1.196 +
   1.197 +	-O3 -DNDEBUG -DBLARGG_NONPORTABLE -fno-rtti -fno-exceptions
   1.198 +
   1.199 +
   1.200 +
   1.201 +Error handling
   1.202 +--------------
   1.203 +Functions which can fail have a return type of spc_err_t (blargg_err_t
   1.204 +in the C++ interfaces), which is a pointer to an error string (const
   1.205 +char*). If a function is successful it returns NULL. Errors that you can
   1.206 +easily avoid are checked with debug assertions; spc_err_t return values
   1.207 +are only used for genuine run-time errors that can't be easily predicted
   1.208 +in advance (out of memory, I/O errors, incompatible file data). Your
   1.209 +code should check all error values.
   1.210 +
   1.211 +To improve usability for C programmers, C++ programmers unfamiliar with
   1.212 +exceptions, and compatibility with older C++ compilers, the library does
   1.213 +*not* throw any C++ exceptions and uses malloc() instead of the standard
   1.214 +operator new. This means that you *must* check for NULL when creating a
   1.215 +library object with the new operator.
   1.216 +
   1.217 +
   1.218 +Solving Problems
   1.219 +----------------
   1.220 +If you're having problems, try the following:
   1.221 +
   1.222 +* If you're getting garbled sound, try this simple siren generator in
   1.223 +place of your call to play(). This will quickly tell whether the problem
   1.224 +is in the library or in your code.
   1.225 +
   1.226 +	static void play_siren( long count, short* out )
   1.227 +	{
   1.228 +		static double a, a2;
   1.229 +		while ( count-- )
   1.230 +			*out++ = 0x2000 * sin( a += .1 + .05*sin( a2+=.00005 ) );
   1.231 +	}
   1.232 +
   1.233 +* Enable debugging support in your environment. This enables assertions
   1.234 +and other run-time checks.
   1.235 +
   1.236 +* Turn the compiler's optimizer is off. Sometimes an optimizer generates
   1.237 +bad code.
   1.238 +
   1.239 +* If multiple threads are being used, ensure that only one at a time is
   1.240 +accessing a given set of objects from the library. This library is not
   1.241 +in general thread-safe, though independent objects can be used in
   1.242 +separate threads.
   1.243 +
   1.244 +* If all else fails, see if the demos work.
   1.245 +
   1.246 +
   1.247 +Accurate S-DSP Limitations
   1.248 +--------------------------
   1.249 +* Power-up and soft reset behavior might have slight inaccuracies.
   1.250 +
   1.251 +* Muting (FLG bit 6) behavior when toggling bit very rapidly is not
   1.252 +emulated properly.
   1.253 +
   1.254 +* No other known inaccuracies. Has passed 100+ strenuous tests.
   1.255 +
   1.256 +
   1.257 +Fast S-DSP Limitations
   1.258 +----------------------
   1.259 +* Uses faster sample calculations except in cases where exact value is
   1.260 +actually important (BRR decoding, and gaussian interpolation combined
   1.261 +with pitch modulation).
   1.262 +
   1.263 +* Stops decoding BRR data when a voice's envelope has released to
   1.264 +silence.
   1.265 +
   1.266 +* Emulates 32 clocks at a time, so DSP register and memory accesses are
   1.267 +all done in a bunch rather than spread out. Even though, some clever
   1.268 +code makes register accesses separated by 40 or so clocks occur with
   1.269 +cycle-accurate timing.
   1.270 +
   1.271 +
   1.272 +S-SMP Limitations
   1.273 +-----------------
   1.274 +* Opcode fetches and indirect pointers are always read directly from
   1.275 +memory, even for the $F0-$FF region, and the DSP is not caught up for
   1.276 +these fetches.
   1.277 +
   1.278 +* Attempts to perversely execute data in registers or an area being
   1.279 +modified by echo will not be emulated properly.
   1.280 +
   1.281 +* Has not been thoroughly tested.
   1.282 +
   1.283 +* Test register ($F0) is not implemented.
   1.284 +
   1.285 +* Echo buffer can overwrite IPL ROM area, and does not correctly update
   1.286 +extra RAM there.
   1.287 +
   1.288 +
   1.289 +To Do
   1.290 +-----
   1.291 +* I'd like feedback on the interface and any ways to improve it. In
   1.292 +particular, the differing features between the accurate and fast DSP
   1.293 +emulators might make it harder to cleanly switch between them without
   1.294 +modifying source code.
   1.295 +
   1.296 +* Finish thorough tests on SMP memory access times.
   1.297 +
   1.298 +* Finish thorough tests on SMP instruction behavior (flags, registers).
   1.299 +
   1.300 +* Finish thorough tests on SMP timers.
   1.301 +
   1.302 +* Finish power-up and reset behavior testing.
   1.303 +
   1.304 +* Come up with best starting conditions to play an SPC and implement in
   1.305 +hardware SNES SPC player for verification.
   1.306 +
   1.307 +
   1.308 +Thanks
   1.309 +------
   1.310 +Thanks to Anti-Resonance's SPC2ROM and help getting SPCs playing on my
   1.311 +SNES in the first place, then Brad Martin's openspc and Chris Moeller's
   1.312 +openspc++ C++ adaptation, giving me a good SPC emulator to start with
   1.313 +several years ago. Thanks to Richard Bannister, Mahendra Tallur, Shazz,
   1.314 +nenolod, theHobbit, Johan Samuelsson, nes6502, and Micket for helping
   1.315 +test my Game_Music_Emu library. Thanks to hcs for help in converting to
   1.316 +C for the Rockbox port. Thanks to byuu (bsnes author) and pagefault and
   1.317 +Nach (zsnes team) for testing and using my new rewritten DSP in their
   1.318 +emulators. Thanks to anomie for his good SNES documentation and
   1.319 +discussions with me to keep it up to date with my latest findings.
   1.320 +-- 
   1.321 +Shay Green <gblargg@gmail.com>