Mercurial > spc_convert
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>