annotate Plugins/Input/console/design.txt @ 108:cde5ca21ddc3 trunk

[svn] Improved latency on the decode loop.
author nenolod
date Wed, 02 Nov 2005 21:45:23 -0800
parents 252843aac42f
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
90
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
1 Game_Music_Emu Design Notes
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
2
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
3
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
4 Managing Complexity
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
5 -------------------
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
6 Complexity has been a factor in most library decisions. Many features
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
7 have been passed by due to the complexity they would add. Once past a
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
8 certain level, complexity prevents mentally grasping the library in its
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
9 entirety, at which point more defects will occur and be hard to find.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
10
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
11 I chose 16-bit signed samples because it seems to be the most common
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
12 format. Supporting multiple formats would add too much complexity to be
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
13 worth it. Other formats can be obtained via conversion.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
14
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
15 I've kept interfaces fairly lean, leaving many possible features
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
16 untapped but easy to add if necessary. For example the classic emulators
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
17 could have volume and frequency equalization adjusted separately for
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
18 each channel, since they each have an associated Blip_Synth.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
19
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
20 Source files of 400 lines or less seem to be the best size to limit
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
21 complexity. In a few cases there is no reasonable way to split longer
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
22 files, or there is benefit from having the source together in one file.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
23
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
24
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
25 Library Configuration
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
26 ---------------------
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
27 Library optimizations can be configured through macros defined in
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
28 config.h. By default, the library is configured to be most likely to
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
29 compile and work on any platform, rather than be most optimal with
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
30 increased chance of problems. It's easier to track down optimiztation
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
31 problems if the library can first be shown to work correctly without
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
32 them.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
33
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
34
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
35 Flexibility through indirection
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
36 -------------------------------
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
37 I've tried to allow the most flexibility of modules by using indirection
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
38 to allow extension by the user. This keeps each module simple and more
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
39 focused on its unique task.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
40
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
41 The classic emulators use Multi_Buffer, which potentially allows a
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
42 separate Blip_Buffer for each channel. This keeps emulators free of
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
43 typical code to allow output in mono, stereo, panning, etc.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
44
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
45 All emulators use a reader object to access file data, allowing it to be
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
46 stored in a regular file, compressed archive, memory, or generated
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
47 on-the-fly. Again, the library can be kept free of the particulars of
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
48 file access and changes required to support new formats.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
49
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
50
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
51 Choice of pre-ISO (ARM) C++
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
52 ---------------------------
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
53 The library started out as an unreleased NSF player written using ISO
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
54 C++. The code was clean enough that I decided to release it as a player
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
55 library. Before release I evaluated its use of C++ features to determine
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
56 the important ones.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
57
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
58 Namespaces and exceptions weren't essential, so I compared a version of
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
59 the library with and without them. I decided that I could do without and
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
60 get better compatibility with older compilers or newer ones with buggy
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
61 namespace and exception implementations.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
62
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
63 Templates are the worst area for most compilers, due to their inherent
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
64 complexity, but they are too useful to avoid entirely. I've used them
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
65 sparingly and in ways that compilers are more likely to work with.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
66
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
67 Sticking to ARM C++ has helped keep the library simpler to understand.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
68
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
69
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
70 Platform-specific optimization
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
71 ------------------------------
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
72 Performance profiling doesn't shown any big bottlenecks that warrant
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
73 heavy platform-specific optimization. The main bottlenecks are CPU
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
74 emulation, Blip_Buffer synthesis and sample reading, Super NES DSP, Sega
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
75 Genesis FM, and Fir_Resampler.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
76
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
77 Further optimization of the CPU emulators can probably only be achieved
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
78 by writing them in assembly or using dynamic recompilation. Blip_Buffer
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
79 might benefit somewhat from vector instructions. Sega Genesis FM
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
80 synthesis can probably be made twice as fast by someone who fully
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
81 understands its operation (I am almost clueless about its internals).
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
82 The Super NES DSP might have some room for optimization. Fir_Resampler
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
83 would benefit greatly from vector operations.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
84
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
85 Most of the above optimizations add more complexity than they are worth.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
86 All that seems worthwhile is optimization of Sega Genesis FM emulation
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
87 and Fir_Resampler.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
88
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
89
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
90 Preventing Bugs
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
91 ---------------
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
92 I've done many things to reduce the opportunity for defects. A general
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
93 principle is to write code so that defects will be as visible as
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
94 possible. I've used several techniques to achieve this.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
95
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
96 I put assertions at key points where defects seem likely or where
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
97 corruption due to a defect is likely to be visible. I've also put
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
98 assetions where violations of the interface are likely. In emulators
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
99 where I am unsure of exact hardware operation in a particular case, I
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
100 output a debug-only message noting that this has occurred; many times I
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
101 haven't implemented a hardware feature because nothing uses it. I've
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
102 made code brittle where there is no clear reason flexibility; code
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
103 written to handle every possibility sacrifices quality and reliability
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
104 to handle vaguely defined situations.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
105
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
106
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
107 Miscellaneous
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
108 -------------
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
109 I don't like naming header files with a ".hpp" suffix for some reason.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
110 They aren't as visually distinct from ".cpp" source files. The ".cpp"
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
111 suffix is useful to inform the compiler that it's a C++ file rather than
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
112 a C file, but I don't know of significant practical benefits the ".hpp"
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
113 suffix gives over ".h" (I used to use *no* suffix for header files, but
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
114 this does cause problems).
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
115
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
116 When implementation has to be put in a header file, it's as far near the
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
117 end as possible to prevent distraction from the public interface.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
118
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
119
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
120 CPU Cores
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
121 ---------
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
122 I've spent lots of time coming up with techniques to optimize the CPU
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
123 cores. Some of the most important: execute multiple instructions during
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
124 an emulation call, keep state in local variables to allow register
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
125 assignment, optimize state representation for most common instructions,
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
126 defer status flag calculation until actually needed, read program code
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
127 directly without a call to the memory read function, always pre-fetch
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
128 the operand byte before decoding instruction, and emulate instructions
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
129 using common blocks of code.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
130
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
131 I've successfully used Nes_Cpu in a simple NES emulator, and I'd like to
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
132 make all the CPU emulators suitable for use in emulators. It seems a
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
133 waste for them to be used only for the small amount of emulation
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
134 necessary for game music files.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
135
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
136 I debugged the CPU cores by writing a test shell that ran them in
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
137 parallel with other CPU cores and compared all memory accesses and
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
138 processor states at each step. This provided good value at little cost.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
139
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
140 The CPU mapping page size is adjustable to allow the best tradeoff
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
141 between memory/cache usage and handler granularity. The interface allows
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
142 code to be somewhat independent of the page size.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
143
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
144 I optimize program memory accesses to to direct reads rather than calls
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
145 to the memory read function. My assumption is that it would be difficult
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
146 to get useful code out of hardware I/O addresses, so no software will
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
147 intentionally execute out of I/O space. Since the page size can be
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
148 changed easily, most program memory mapping schemes can be accommodated.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
149 This greatly reduces memory access function calls.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
150
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
151
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
152 Sub-Libraries
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
153 -------------
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
154 I've also released the sound cores as individual libraries to reduce
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
155 complexity for emulator authors who just want a single sound core. These
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
156 authors will be using the sound cores directly, while users of this
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
157 music emulator library won't even see them, so documentation and demos
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
158 can be specific to each library.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
159
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
160
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
161 Documentation
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
162 -------------
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
163 I started out with separate documentation in HTML and found that it
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
164 wasn't going to be easy to maintain. I switched to putting descriptions
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
165 of function behavior in header files before the function declarations.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
166 This has worked well so far.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
167
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
168 I think the concrete executable demo code helps the most when someone is
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
169 using the library for the first time, since it shows a complete program
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
170 and provides a framework for using the library. By recording to a sound
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
171 file, I can keep the code portable, and the result can be listened to or
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
172 examined closely, which is important for something real-time like sound.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
173
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
174
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
175 I want to write some tutorials to complement the demo code, desribing
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
176 the basic framework and operation of the modules.
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
177