Mercurial > audlegacy-plugins
annotate src/console/gme_design.txt @ 540:62c4c304a997 trunk
[svn] - handle OV_HOLE gracefully
author | nenolod |
---|---|
date | Tue, 23 Jan 2007 06:25:58 -0800 |
parents | 986f098da058 |
children |
rev | line source |
---|---|
341 | 1 Game_Music_Emu 0.5.2 Design |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
2 --------------------------- |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
3 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
4 Architecture |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
5 ------------ |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
6 Gme_File and Music_Emu provide a common interface to the emulators. The |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
7 virtual functions are protected rather than public to allow pre- and |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
8 post-processing of arguments and data in one place. This allows the |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
9 emulator classes to assume that everything is set up properly when |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
10 starting a track and playing samples. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
11 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
12 Since silence checking and fading are relatively complex, basic file |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
13 loading and track information are handled in the base class Gme_File. My |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
14 orignal intent was to use Gme_File as the common base class for full |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
15 emulators and track information-only readers, but implementing the C |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
16 interface was much simpler if both derived from Music_Emu. User C++ code |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
17 can still benefit from static checking by using Gme_File where only |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
18 track information will be accessed. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
19 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
20 Each emulator generally has three components: main emulator, CPU |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
21 emulator, and sound chip emulator(s). Each component has minimial |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
22 coupling, so use in a full emulator or standalone is fairly easy. This |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
23 modularity really helps reduce complexity. Blip_Buffer helps a lot with |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
24 simplifying the APU interfaces and implementation. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
25 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
26 The "classic" emulators derive from Classic_Emu, which handles |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
27 Blip_Buffer filling and multiple channels. It uses Multi_Buffer for |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
28 output, allowing you to derive a custom buffer that could output each |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
29 voice to a separate sound channel and do different processing on each. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
30 At some point I'm going to implement a better Effects_Buffer that allows |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
31 individual control of every channel. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
32 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
33 In implementing the C interface, I wanted a way to specify an emulator |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
34 type that didn't require linking in all the emulators. This rules out |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
35 any functions which automatically select it based on a file's extension |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
36 or header contents. For each emulator type there is a global object with |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
37 pointers to functions to create the emulator or a track information |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
38 reader. The emulator type is thus a pointer to this, which conveniently |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
39 allows for a NULL value. The user referencing this emulator type object |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
40 is what ultimately links the emulator in (unless new Foo_Emu is used in |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
41 C++, of course). |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
42 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
43 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
44 Interface conventions |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
45 ---------------------- |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
46 If a function retains a pointer to or replaces the value of an object |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
47 passed, it takes a pointer so that it will be clear in the caller's |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
48 source code that care is required. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
49 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
50 Multi-word names have an underscore '_' separator between individual |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
51 words. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
52 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
53 Functions are named with lowercase words. Functions which perform an |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
54 action with side-effects are named with a verb phrase (i.e. load, move, |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
55 run). Functions which return the value of a piece of state are named |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
56 using a noun phrase (i.e. loaded, moved, running). |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
57 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
58 Classes are named with capitalized words. Only the first letter of an |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
59 acronym is capitalized. Class names are nouns, sometimes suggestive of |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
60 what they do (i.e. File_Scanner). |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
61 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
62 Structure, enumeration, and typedefs to these and built-in types are |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
63 named using lowercase words with a _t suffix. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
64 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
65 Macros are named with all-uppercase words. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
66 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
67 Internal names which can't be hidden due to technical reasons have an |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
68 underscore '_' suffix. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
69 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
70 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
71 Managing Complexity |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
72 ------------------- |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
73 Complexity has been a factor in most library decisions. Many features |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
74 have been passed by due to the complexity they would add. Once |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
75 complexity goes past a certain level, it mentally grasping the library |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
76 in its entirety, at which point more defects will occur and be hard to |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
77 find. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
78 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
79 I chose 16-bit signed samples because it seems to be the most common |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
80 format. Supporting multiple formats would add too much complexity to be |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
81 worth it. Other formats can be obtained via conversion. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
82 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
83 I've kept interfaces fairly lean, leaving many possible features |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
84 untapped but easy to add if necessary. For example the classic emulators |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
85 could have volume and frequency equalization adjusted separately for |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
86 each channel, since they each have an associated Blip_Synth. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
87 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
88 Source files of 400 lines or less seem to be the best size to limit |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
89 complexity. In a few cases there is no reasonable way to split longer |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
90 files, or there is benefit from having the source together in one file. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
91 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
92 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
93 Preventing Bugs |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
94 --------------- |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
95 I've done many things to reduce the opportunity for defects. A general |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
96 principle is to write code so that defects will be as visible as |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
97 possible. I've used several techniques to achieve this. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
98 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
99 I put assertions at key points where defects seem likely or where |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
100 corruption due to a defect is likely to be visible. I've also put |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
101 assertions where violations of the interface are likely. In emulators |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
102 where I am unsure of exact hardware operation in a particular case, I |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
103 output a debug-only message noting that this has occurred; many times I |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
104 haven't implemented a hardware feature because nothing uses it. I've |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
105 made code brittle where there is no clear reason flexibility; code |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
106 written to handle every possibility sacrifices quality and reliability |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
107 to handle vaguely defined situations. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
108 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
109 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
110 Flexibility through indirection |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
111 ------------------------------- |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
112 I've tried to allow the most flexibility of modules by using indirection |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
113 to allow extension by the user. This keeps each module simpler and more |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
114 focused on its unique task. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
115 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
116 The classic emulators use Multi_Buffer, which potentially allows a |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
117 separate Blip_Buffer for each channel. This keeps emulators free of |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
118 typical code to allow output in mono, stereo, panning, etc. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
119 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
120 All emulators use a reader object to access file data, allowing it to be |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
121 stored in a regular file, compressed archive, memory, or generated |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
122 on-the-fly. Again, the library can be kept free of the particulars of |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
123 file access and changes required to support new formats. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
124 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
125 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
126 Emulators in general |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
127 -------------------- |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
128 When I wrote the first NES sound emulator, I stored most of the state in |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
129 an emulator-specific format, with significant redundancy. In the |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
130 register write function I decoded everything into named variables. I |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
131 became tired of the verbosity and wanted to more closely model the |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
132 hardware, so I moved to a style of storing the last written value to |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
133 each register, along with as little other state as possible, mostly the |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
134 internal hardware registers. While this involves slightly more |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
135 recalculation, in most cases the emulation code is of comparable size. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
136 It also makes state save/restore (for use in a full emulator) much |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
137 simpler. Finally, it makes debugging easier since the hardware registers |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
138 used in emulation are obvious. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
139 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
140 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
141 CPU Cores |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
142 --------- |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
143 I've spent lots of time coming up with techniques to optimize the CPU |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
144 cores. Some of the most important: execute multiple instructions during |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
145 an emulation call, keep state in local variables to allow register |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
146 assignment, optimize state representation for most common instructions, |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
147 defer status flag calculation until actually needed, read program code |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
148 directly without a call to the memory read function, always pre-fetch |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
149 the operand byte before decoding instruction, and emulate instructions |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
150 using common blocks of code. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
151 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
152 I've successfully used Nes_Cpu in a fairly complete NES emulator, and |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
153 I'd like to make all the CPU emulators suitable for use in emulators. It |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
154 seems a waste for them to be used only for the small amount of emulation |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
155 necessary for game music files. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
156 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
157 I debugged the CPU cores by writing a test shell that ran them in |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
158 parallel with other CPU cores and compared all memory accesses and |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
159 processor states at each step. This provided good value at little cost. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
160 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
161 The CPU mapping page size is adjustable to allow the best tradeoff |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
162 between memory/cache usage and handler granularity. The interface allows |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
163 code to be somewhat independent of the page size. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
164 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
165 I optimize program memory accesses to to direct reads rather than calls |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
166 to the memory read function. My assumption is that it would be difficult |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
167 to get useful code out of hardware I/O addresses, so no software will |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
168 intentionally execute out of I/O space. Since the page size can be |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
169 changed easily, most program memory mapping schemes can be accommodated. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
170 This greatly reduces memory access function calls. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff
changeset
|
171 |