diff options
author | Jens Arnold <amiconn@rockbox.org> | 2005-03-02 23:49:38 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2005-03-02 23:49:38 +0000 |
commit | 384de102469fee4e0792df8fe38586d3206774ed (patch) | |
tree | ee5342103e17738acfb8421328ea7c57433f55e6 | |
parent | 48dad47df98bdec632e8930b6a97359dc2c428f5 (diff) | |
download | rockbox-384de102469fee4e0792df8fe38586d3206774ed.tar.gz rockbox-384de102469fee4e0792df8fe38586d3206774ed.zip |
Rockboy - gameboy emulation for rockbox, based on gnuboy. Still a bit early, but already playable on iRiver H1xx and the simulators. The archos recorder version is currently rather slow...
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6104 a1c6a512-1295-4272-9138-f99709370657
56 files changed, 9225 insertions, 1 deletions
diff --git a/apps/plugins/Makefile b/apps/plugins/Makefile index 3e56510f53..6c3917c0cb 100644 --- a/apps/plugins/Makefile +++ b/apps/plugins/Makefile | |||
@@ -34,7 +34,13 @@ OBJS := $(SRC:%.c=$(OBJDIR)/%.o) | |||
34 | DEFS := $(SRC:%.c=$(OBJDIR)/%.def) | 34 | DEFS := $(SRC:%.c=$(OBJDIR)/%.def) |
35 | DIRS = . | 35 | DIRS = . |
36 | 36 | ||
37 | all: $(OBJDIR)/libplugin.a $(ROCKS) $(DEPFILE) | 37 | #for any recorder and iRiver model |
38 | ifneq (,$(strip $(foreach tgt,RECORDER IRIVER,$(findstring $(tgt),$(TARGET))))) | ||
39 | SUBDIRS += rockboy | ||
40 | endif | ||
41 | |||
42 | .PHONY: $(SUBDIRS) | ||
43 | all: $(OBJDIR)/libplugin.a $(ROCKS) $(SUBDIRS) $(DEPFILE) | ||
38 | 44 | ||
39 | ifndef SIMVER | 45 | ifndef SIMVER |
40 | $(OBJDIR)/%.elf: $(OBJDIR)/%.o $(LINKFILE) $(OBJDIR)/libplugin.a | 46 | $(OBJDIR)/%.elf: $(OBJDIR)/%.o $(LINKFILE) $(OBJDIR)/libplugin.a |
@@ -95,10 +101,16 @@ $(LINKFILE): $(LDS) | |||
95 | @echo "build $@" | 101 | @echo "build $@" |
96 | @cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) $(DEFINES) -E -P - >$@ | 102 | @cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) $(DEFINES) -E -P - >$@ |
97 | 103 | ||
104 | $(SUBDIRS): | ||
105 | @echo "MAKE in $@" | ||
106 | @mkdir -p $(OBJDIR)/$@ | ||
107 | @$(MAKE) -C $@ TARGET=$(TARGET) DEBUG=$(DEBUG) OUTDIR=$(OBJDIR) OBJDIR=$(OBJDIR)/$@ VERSION=$(VERSION) EXTRA_DEFINES="$(EXTRA_DEFINES)" MEM=${MEMORYSIZE} | ||
108 | |||
98 | clean: | 109 | clean: |
99 | @echo "cleaning plugins" | 110 | @echo "cleaning plugins" |
100 | @rm -f $(ROCKS) $(LINKFILE) $(OBJDIR)/*.rock $(DEPFILE) $(ELFS) \ | 111 | @rm -f $(ROCKS) $(LINKFILE) $(OBJDIR)/*.rock $(DEPFILE) $(ELFS) \ |
101 | $(OBJS) $(DEFS) | 112 | $(OBJS) $(DEFS) |
102 | @$(MAKE) -C lib clean | 113 | @$(MAKE) -C lib clean |
114 | @$(MAKE) -C rockboy clean | ||
103 | 115 | ||
104 | -include $(DEPFILE) | 116 | -include $(DEPFILE) |
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES index 643fc0c5c1..581d164e94 100644 --- a/apps/plugins/SOURCES +++ b/apps/plugins/SOURCES | |||
@@ -29,6 +29,10 @@ oscillograph.c | |||
29 | oscilloscope.c | 29 | oscilloscope.c |
30 | pong.c | 30 | pong.c |
31 | rockblox.c | 31 | rockblox.c |
32 | #if (CONFIG_KEYPAD == RECORDER_PAD) && !defined(SIMULATOR) | ||
33 | /* loader, only needed for Archos */ | ||
34 | rockboy.c | ||
35 | #endif | ||
32 | sliding_puzzle.c | 36 | sliding_puzzle.c |
33 | snake.c | 37 | snake.c |
34 | snake2.c | 38 | snake2.c |
diff --git a/apps/plugins/rockboy.c b/apps/plugins/rockboy.c new file mode 100644 index 0000000000..4778fa8ee6 --- /dev/null +++ b/apps/plugins/rockboy.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 Jens Arnold | ||
11 | * | ||
12 | * Overlay loader for rockboy on Archos | ||
13 | * | ||
14 | * All files in this archive are subject to the GNU General Public License. | ||
15 | * See the file COPYING in the source tree root for full license agreement. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "plugin.h" | ||
22 | |||
23 | #if MEM <= 8 && !defined(SIMULATOR) | ||
24 | |||
25 | #define OVL_NAME "/.rockbox/viewers/rockboy.ovl" | ||
26 | #define OVL_DISPLAYNAME "RockBoy" | ||
27 | |||
28 | struct plugin_api* rb; | ||
29 | unsigned char *mp3buf; | ||
30 | int mp3buf_size; | ||
31 | |||
32 | /* this is the plugin entry point */ | ||
33 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
34 | { | ||
35 | int fh, readsize; | ||
36 | struct { | ||
37 | unsigned long magic; | ||
38 | unsigned char *start_addr; | ||
39 | unsigned char *end_addr; | ||
40 | enum plugin_status(*entry_point)(struct plugin_api*, void*); | ||
41 | } header; | ||
42 | |||
43 | /* this macro should be called as the first thing you do in the plugin. | ||
44 | it test that the api version and model the plugin was compiled for | ||
45 | matches the machine it is running on */ | ||
46 | TEST_PLUGIN_API(api); | ||
47 | rb = api; | ||
48 | |||
49 | fh = rb->open(OVL_NAME, O_RDONLY); | ||
50 | if (fh < 0) | ||
51 | { | ||
52 | rb->splash(2*HZ, true, "Couldn't open " OVL_DISPLAYNAME " overlay."); | ||
53 | return PLUGIN_ERROR; | ||
54 | } | ||
55 | readsize = rb->read(fh, &header, sizeof(header)); | ||
56 | if (readsize != sizeof(header) || header.magic != 0x524f564c) | ||
57 | { | ||
58 | rb->close(fh); | ||
59 | rb->splash(2*HZ, true, OVL_NAME " is not a valid Rockbox overlay."); | ||
60 | return PLUGIN_ERROR; | ||
61 | } | ||
62 | |||
63 | mp3buf = rb->plugin_get_mp3_buffer(&mp3buf_size); | ||
64 | if (header.start_addr < mp3buf || header.end_addr > mp3buf + mp3buf_size) | ||
65 | { | ||
66 | rb->close(fh); | ||
67 | rb->splash(2*HZ, true, OVL_DISPLAYNAME | ||
68 | " overlay doesn't fit into memory."); | ||
69 | return PLUGIN_ERROR; | ||
70 | } | ||
71 | rb->lseek(fh, 0, SEEK_SET); | ||
72 | readsize = rb->read(fh, header.start_addr, header.end_addr - header.start_addr); | ||
73 | rb->close(fh); | ||
74 | if (readsize != header.end_addr - header.start_addr) | ||
75 | { | ||
76 | rb->splash(2*HZ, true, "Error loading " OVL_DISPLAYNAME " overlay."); | ||
77 | return PLUGIN_ERROR; | ||
78 | } | ||
79 | return header.entry_point(api, parameter); | ||
80 | } | ||
81 | #endif | ||
diff --git a/apps/plugins/rockboy/COPYING b/apps/plugins/rockboy/COPYING new file mode 100755 index 0000000000..a43ea2126f --- /dev/null +++ b/apps/plugins/rockboy/COPYING | |||
@@ -0,0 +1,339 @@ | |||
1 | GNU GENERAL PUBLIC LICENSE | ||
2 | Version 2, June 1991 | ||
3 | |||
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. | ||
5 | 675 Mass Ave, Cambridge, MA 02139, USA | ||
6 | Everyone is permitted to copy and distribute verbatim copies | ||
7 | of this license document, but changing it is not allowed. | ||
8 | |||
9 | Preamble | ||
10 | |||
11 | The licenses for most software are designed to take away your | ||
12 | freedom to share and change it. By contrast, the GNU General Public | ||
13 | License is intended to guarantee your freedom to share and change free | ||
14 | software--to make sure the software is free for all its users. This | ||
15 | General Public License applies to most of the Free Software | ||
16 | Foundation's software and to any other program whose authors commit to | ||
17 | using it. (Some other Free Software Foundation software is covered by | ||
18 | the GNU Library General Public License instead.) You can apply it to | ||
19 | your programs, too. | ||
20 | |||
21 | When we speak of free software, we are referring to freedom, not | ||
22 | price. Our General Public Licenses are designed to make sure that you | ||
23 | have the freedom to distribute copies of free software (and charge for | ||
24 | this service if you wish), that you receive source code or can get it | ||
25 | if you want it, that you can change the software or use pieces of it | ||
26 | in new free programs; and that you know you can do these things. | ||
27 | |||
28 | To protect your rights, we need to make restrictions that forbid | ||
29 | anyone to deny you these rights or to ask you to surrender the rights. | ||
30 | These restrictions translate to certain responsibilities for you if you | ||
31 | distribute copies of the software, or if you modify it. | ||
32 | |||
33 | For example, if you distribute copies of such a program, whether | ||
34 | gratis or for a fee, you must give the recipients all the rights that | ||
35 | you have. You must make sure that they, too, receive or can get the | ||
36 | source code. And you must show them these terms so they know their | ||
37 | rights. | ||
38 | |||
39 | We protect your rights with two steps: (1) copyright the software, and | ||
40 | (2) offer you this license which gives you legal permission to copy, | ||
41 | distribute and/or modify the software. | ||
42 | |||
43 | Also, for each author's protection and ours, we want to make certain | ||
44 | that everyone understands that there is no warranty for this free | ||
45 | software. If the software is modified by someone else and passed on, we | ||
46 | want its recipients to know that what they have is not the original, so | ||
47 | that any problems introduced by others will not reflect on the original | ||
48 | authors' reputations. | ||
49 | |||
50 | Finally, any free program is threatened constantly by software | ||
51 | patents. We wish to avoid the danger that redistributors of a free | ||
52 | program will individually obtain patent licenses, in effect making the | ||
53 | program proprietary. To prevent this, we have made it clear that any | ||
54 | patent must be licensed for everyone's free use or not licensed at all. | ||
55 | |||
56 | The precise terms and conditions for copying, distribution and | ||
57 | modification follow. | ||
58 | |||
59 | GNU GENERAL PUBLIC LICENSE | ||
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | ||
61 | |||
62 | 0. This License applies to any program or other work which contains | ||
63 | a notice placed by the copyright holder saying it may be distributed | ||
64 | under the terms of this General Public License. The "Program", below, | ||
65 | refers to any such program or work, and a "work based on the Program" | ||
66 | means either the Program or any derivative work under copyright law: | ||
67 | that is to say, a work containing the Program or a portion of it, | ||
68 | either verbatim or with modifications and/or translated into another | ||
69 | language. (Hereinafter, translation is included without limitation in | ||
70 | the term "modification".) Each licensee is addressed as "you". | ||
71 | |||
72 | Activities other than copying, distribution and modification are not | ||
73 | covered by this License; they are outside its scope. The act of | ||
74 | running the Program is not restricted, and the output from the Program | ||
75 | is covered only if its contents constitute a work based on the | ||
76 | Program (independent of having been made by running the Program). | ||
77 | Whether that is true depends on what the Program does. | ||
78 | |||
79 | 1. You may copy and distribute verbatim copies of the Program's | ||
80 | source code as you receive it, in any medium, provided that you | ||
81 | conspicuously and appropriately publish on each copy an appropriate | ||
82 | copyright notice and disclaimer of warranty; keep intact all the | ||
83 | notices that refer to this License and to the absence of any warranty; | ||
84 | and give any other recipients of the Program a copy of this License | ||
85 | along with the Program. | ||
86 | |||
87 | You may charge a fee for the physical act of transferring a copy, and | ||
88 | you may at your option offer warranty protection in exchange for a fee. | ||
89 | |||
90 | 2. You may modify your copy or copies of the Program or any portion | ||
91 | of it, thus forming a work based on the Program, and copy and | ||
92 | distribute such modifications or work under the terms of Section 1 | ||
93 | above, provided that you also meet all of these conditions: | ||
94 | |||
95 | a) You must cause the modified files to carry prominent notices | ||
96 | stating that you changed the files and the date of any change. | ||
97 | |||
98 | b) You must cause any work that you distribute or publish, that in | ||
99 | whole or in part contains or is derived from the Program or any | ||
100 | part thereof, to be licensed as a whole at no charge to all third | ||
101 | parties under the terms of this License. | ||
102 | |||
103 | c) If the modified program normally reads commands interactively | ||
104 | when run, you must cause it, when started running for such | ||
105 | interactive use in the most ordinary way, to print or display an | ||
106 | announcement including an appropriate copyright notice and a | ||
107 | notice that there is no warranty (or else, saying that you provide | ||
108 | a warranty) and that users may redistribute the program under | ||
109 | these conditions, and telling the user how to view a copy of this | ||
110 | License. (Exception: if the Program itself is interactive but | ||
111 | does not normally print such an announcement, your work based on | ||
112 | the Program is not required to print an announcement.) | ||
113 | |||
114 | These requirements apply to the modified work as a whole. If | ||
115 | identifiable sections of that work are not derived from the Program, | ||
116 | and can be reasonably considered independent and separate works in | ||
117 | themselves, then this License, and its terms, do not apply to those | ||
118 | sections when you distribute them as separate works. But when you | ||
119 | distribute the same sections as part of a whole which is a work based | ||
120 | on the Program, the distribution of the whole must be on the terms of | ||
121 | this License, whose permissions for other licensees extend to the | ||
122 | entire whole, and thus to each and every part regardless of who wrote it. | ||
123 | |||
124 | Thus, it is not the intent of this section to claim rights or contest | ||
125 | your rights to work written entirely by you; rather, the intent is to | ||
126 | exercise the right to control the distribution of derivative or | ||
127 | collective works based on the Program. | ||
128 | |||
129 | In addition, mere aggregation of another work not based on the Program | ||
130 | with the Program (or with a work based on the Program) on a volume of | ||
131 | a storage or distribution medium does not bring the other work under | ||
132 | the scope of this License. | ||
133 | |||
134 | 3. You may copy and distribute the Program (or a work based on it, | ||
135 | under Section 2) in object code or executable form under the terms of | ||
136 | Sections 1 and 2 above provided that you also do one of the following: | ||
137 | |||
138 | a) Accompany it with the complete corresponding machine-readable | ||
139 | source code, which must be distributed under the terms of Sections | ||
140 | 1 and 2 above on a medium customarily used for software interchange; or, | ||
141 | |||
142 | b) Accompany it with a written offer, valid for at least three | ||
143 | years, to give any third party, for a charge no more than your | ||
144 | cost of physically performing source distribution, a complete | ||
145 | machine-readable copy of the corresponding source code, to be | ||
146 | distributed under the terms of Sections 1 and 2 above on a medium | ||
147 | customarily used for software interchange; or, | ||
148 | |||
149 | c) Accompany it with the information you received as to the offer | ||
150 | to distribute corresponding source code. (This alternative is | ||
151 | allowed only for noncommercial distribution and only if you | ||
152 | received the program in object code or executable form with such | ||
153 | an offer, in accord with Subsection b above.) | ||
154 | |||
155 | The source code for a work means the preferred form of the work for | ||
156 | making modifications to it. For an executable work, complete source | ||
157 | code means all the source code for all modules it contains, plus any | ||
158 | associated interface definition files, plus the scripts used to | ||
159 | control compilation and installation of the executable. However, as a | ||
160 | special exception, the source code distributed need not include | ||
161 | anything that is normally distributed (in either source or binary | ||
162 | form) with the major components (compiler, kernel, and so on) of the | ||
163 | operating system on which the executable runs, unless that component | ||
164 | itself accompanies the executable. | ||
165 | |||
166 | If distribution of executable or object code is made by offering | ||
167 | access to copy from a designated place, then offering equivalent | ||
168 | access to copy the source code from the same place counts as | ||
169 | distribution of the source code, even though third parties are not | ||
170 | compelled to copy the source along with the object code. | ||
171 | |||
172 | 4. You may not copy, modify, sublicense, or distribute the Program | ||
173 | except as expressly provided under this License. Any attempt | ||
174 | otherwise to copy, modify, sublicense or distribute the Program is | ||
175 | void, and will automatically terminate your rights under this License. | ||
176 | However, parties who have received copies, or rights, from you under | ||
177 | this License will not have their licenses terminated so long as such | ||
178 | parties remain in full compliance. | ||
179 | |||
180 | 5. You are not required to accept this License, since you have not | ||
181 | signed it. However, nothing else grants you permission to modify or | ||
182 | distribute the Program or its derivative works. These actions are | ||
183 | prohibited by law if you do not accept this License. Therefore, by | ||
184 | modifying or distributing the Program (or any work based on the | ||
185 | Program), you indicate your acceptance of this License to do so, and | ||
186 | all its terms and conditions for copying, distributing or modifying | ||
187 | the Program or works based on it. | ||
188 | |||
189 | 6. Each time you redistribute the Program (or any work based on the | ||
190 | Program), the recipient automatically receives a license from the | ||
191 | original licensor to copy, distribute or modify the Program subject to | ||
192 | these terms and conditions. You may not impose any further | ||
193 | restrictions on the recipients' exercise of the rights granted herein. | ||
194 | You are not responsible for enforcing compliance by third parties to | ||
195 | this License. | ||
196 | |||
197 | 7. If, as a consequence of a court judgment or allegation of patent | ||
198 | infringement or for any other reason (not limited to patent issues), | ||
199 | conditions are imposed on you (whether by court order, agreement or | ||
200 | otherwise) that contradict the conditions of this License, they do not | ||
201 | excuse you from the conditions of this License. If you cannot | ||
202 | distribute so as to satisfy simultaneously your obligations under this | ||
203 | License and any other pertinent obligations, then as a consequence you | ||
204 | may not distribute the Program at all. For example, if a patent | ||
205 | license would not permit royalty-free redistribution of the Program by | ||
206 | all those who receive copies directly or indirectly through you, then | ||
207 | the only way you could satisfy both it and this License would be to | ||
208 | refrain entirely from distribution of the Program. | ||
209 | |||
210 | If any portion of this section is held invalid or unenforceable under | ||
211 | any particular circumstance, the balance of the section is intended to | ||
212 | apply and the section as a whole is intended to apply in other | ||
213 | circumstances. | ||
214 | |||
215 | It is not the purpose of this section to induce you to infringe any | ||
216 | patents or other property right claims or to contest validity of any | ||
217 | such claims; this section has the sole purpose of protecting the | ||
218 | integrity of the free software distribution system, which is | ||
219 | implemented by public license practices. Many people have made | ||
220 | generous contributions to the wide range of software distributed | ||
221 | through that system in reliance on consistent application of that | ||
222 | system; it is up to the author/donor to decide if he or she is willing | ||
223 | to distribute software through any other system and a licensee cannot | ||
224 | impose that choice. | ||
225 | |||
226 | This section is intended to make thoroughly clear what is believed to | ||
227 | be a consequence of the rest of this License. | ||
228 | |||
229 | 8. If the distribution and/or use of the Program is restricted in | ||
230 | certain countries either by patents or by copyrighted interfaces, the | ||
231 | original copyright holder who places the Program under this License | ||
232 | may add an explicit geographical distribution limitation excluding | ||
233 | those countries, so that distribution is permitted only in or among | ||
234 | countries not thus excluded. In such case, this License incorporates | ||
235 | the limitation as if written in the body of this License. | ||
236 | |||
237 | 9. The Free Software Foundation may publish revised and/or new versions | ||
238 | of the General Public License from time to time. Such new versions will | ||
239 | be similar in spirit to the present version, but may differ in detail to | ||
240 | address new problems or concerns. | ||
241 | |||
242 | Each version is given a distinguishing version number. If the Program | ||
243 | specifies a version number of this License which applies to it and "any | ||
244 | later version", you have the option of following the terms and conditions | ||
245 | either of that version or of any later version published by the Free | ||
246 | Software Foundation. If the Program does not specify a version number of | ||
247 | this License, you may choose any version ever published by the Free Software | ||
248 | Foundation. | ||
249 | |||
250 | 10. If you wish to incorporate parts of the Program into other free | ||
251 | programs whose distribution conditions are different, write to the author | ||
252 | to ask for permission. For software which is copyrighted by the Free | ||
253 | Software Foundation, write to the Free Software Foundation; we sometimes | ||
254 | make exceptions for this. Our decision will be guided by the two goals | ||
255 | of preserving the free status of all derivatives of our free software and | ||
256 | of promoting the sharing and reuse of software generally. | ||
257 | |||
258 | NO WARRANTY | ||
259 | |||
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | ||
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | ||
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | ||
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | ||
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | ||
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | ||
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | ||
268 | REPAIR OR CORRECTION. | ||
269 | |||
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | ||
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | ||
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | ||
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | ||
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | ||
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | ||
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | ||
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | ||
278 | POSSIBILITY OF SUCH DAMAGES. | ||
279 | |||
280 | END OF TERMS AND CONDITIONS | ||
281 | |||
282 | Appendix: How to Apply These Terms to Your New Programs | ||
283 | |||
284 | If you develop a new program, and you want it to be of the greatest | ||
285 | possible use to the public, the best way to achieve this is to make it | ||
286 | free software which everyone can redistribute and change under these terms. | ||
287 | |||
288 | To do so, attach the following notices to the program. It is safest | ||
289 | to attach them to the start of each source file to most effectively | ||
290 | convey the exclusion of warranty; and each file should have at least | ||
291 | the "copyright" line and a pointer to where the full notice is found. | ||
292 | |||
293 | <one line to give the program's name and a brief idea of what it does.> | ||
294 | Copyright (C) 19yy <name of author> | ||
295 | |||
296 | This program is free software; you can redistribute it and/or modify | ||
297 | it under the terms of the GNU General Public License as published by | ||
298 | the Free Software Foundation; either version 2 of the License, or | ||
299 | (at your option) any later version. | ||
300 | |||
301 | This program is distributed in the hope that it will be useful, | ||
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
304 | GNU General Public License for more details. | ||
305 | |||
306 | You should have received a copy of the GNU General Public License | ||
307 | along with this program; if not, write to the Free Software | ||
308 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
309 | |||
310 | Also add information on how to contact you by electronic and paper mail. | ||
311 | |||
312 | If the program is interactive, make it output a short notice like this | ||
313 | when it starts in an interactive mode: | ||
314 | |||
315 | Gnomovision version 69, Copyright (C) 19yy name of author | ||
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | ||
317 | This is free software, and you are welcome to redistribute it | ||
318 | under certain conditions; type `show c' for details. | ||
319 | |||
320 | The hypothetical commands `show w' and `show c' should show the appropriate | ||
321 | parts of the General Public License. Of course, the commands you use may | ||
322 | be called something other than `show w' and `show c'; they could even be | ||
323 | mouse-clicks or menu items--whatever suits your program. | ||
324 | |||
325 | You should also get your employer (if you work as a programmer) or your | ||
326 | school, if any, to sign a "copyright disclaimer" for the program, if | ||
327 | necessary. Here is a sample; alter the names: | ||
328 | |||
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program | ||
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. | ||
331 | |||
332 | <signature of Ty Coon>, 1 April 1989 | ||
333 | Ty Coon, President of Vice | ||
334 | |||
335 | This General Public License does not permit incorporating your program into | ||
336 | proprietary programs. If your program is a subroutine library, you may | ||
337 | consider it more useful to permit linking proprietary applications with the | ||
338 | library. If this is what you want to do, use the GNU Library General | ||
339 | Public License instead of this License. | ||
diff --git a/apps/plugins/rockboy/Makefile b/apps/plugins/rockboy/Makefile new file mode 100644 index 0000000000..f6042a4b1b --- /dev/null +++ b/apps/plugins/rockboy/Makefile | |||
@@ -0,0 +1,106 @@ | |||
1 | # __________ __ ___. | ||
2 | # Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
3 | # Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
4 | # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
5 | # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
6 | # \/ \/ \/ \/ \/ | ||
7 | # $Id$ | ||
8 | # | ||
9 | |||
10 | INCLUDES = -I$(APPSDIR) -I.. -I. -I$(FIRMDIR)/include -I$(FIRMDIR)/export \ | ||
11 | -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers | ||
12 | CFLAGS = $(GCCOPTS) -O3 $(INCLUDES) $(TARGET) $(EXTRA_DEFINES) \ | ||
13 | -DMEM=${MEMORYSIZE} -DPLUGIN | ||
14 | |||
15 | ifdef APPEXTRA | ||
16 | INCLUDES += -I$(APPSDIR)/$(APPEXTRA) | ||
17 | endif | ||
18 | |||
19 | LINKFILE := $(OBJDIR)/link.lds | ||
20 | DEPFILE = $(OBJDIR)/dep-rockboy | ||
21 | SRC = cpu.c emu.c events.c exports.c fastmem.c hw.c lcd.c lcdc.c loader.c \ | ||
22 | main.c mem.c nosound.c rccmds.c rcvars.c rtc.c save.c sound.c split.c \ | ||
23 | sys_rockbox.c rockboy.c | ||
24 | SOURCES = $(SRC) | ||
25 | OBJS := $(SRC:%.c=$(OBJDIR)/%.o) | ||
26 | DIRS = . | ||
27 | |||
28 | ifndef SIMVER | ||
29 | ifneq (,$(findstring RECORDER,$(TARGET))) ## Archos recorder targets | ||
30 | LDS := archos.lds | ||
31 | OUTPUT = $(OUTDIR)/rockboy.ovl | ||
32 | else ## iRiver target | ||
33 | LDS := ../plugin.lds | ||
34 | OUTPUT = $(OUTDIR)/rockboy.rock | ||
35 | endif | ||
36 | else ## simulators | ||
37 | OUTPUT = $(OUTDIR)/rockboy.rock | ||
38 | endif | ||
39 | |||
40 | all: $(OUTPUT) | ||
41 | |||
42 | ifndef SIMVER | ||
43 | $(OBJDIR)/rockboy.elf: $(OBJS) $(LINKFILE) $(OUTDIR)/libplugin.a | ||
44 | @echo "LD $@" | ||
45 | @$(CC) $(GCCOPTS) -O -nostdlib -o $@ $(OBJS) -L$(OUTDIR) -lplugin -lgcc \ | ||
46 | -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/rockboy.map | ||
47 | |||
48 | $(OUTPUT): $(OBJDIR)/rockboy.elf | ||
49 | @echo "OBJCOPY $<" | ||
50 | @$(OC) -O binary $< $@ | ||
51 | else | ||
52 | |||
53 | ifeq ($(SIMVER), x11) | ||
54 | ################################################### | ||
55 | # This is the X11 simulator version | ||
56 | |||
57 | $(OUTPUT): $(OBJS) $(OUTDIR)/libplugin.a | ||
58 | @echo "LD $@" | ||
59 | @$(CC) $(CFLAGS) -shared $(OBJS) -L$(OUTDIR) -lplugin -o $@ | ||
60 | ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN) | ||
61 | # 'x' must be kept or you'll have "Win32 error 5" | ||
62 | # $ fgrep 5 /usr/include/w32api/winerror.h | head -1 | ||
63 | # #define ERROR_ACCESS_DENIED 5L | ||
64 | else | ||
65 | @chmod -x $@ | ||
66 | endif | ||
67 | |||
68 | else # end of x11-simulator | ||
69 | ################################################### | ||
70 | # This is the win32 simulator version | ||
71 | DLLTOOLFLAGS = --export-all | ||
72 | DLLWRAPFLAGS = -s --entry _DllMain@12 --target=i386-mingw32 -mno-cygwin | ||
73 | |||
74 | $(OUTPUT): $(OBJS) $(OUTDIR)/libplugin.a | ||
75 | @echo "DLL $@" | ||
76 | @$(DLLTOOL) $(DLLTOOLFLAGS) -z $(OBJDIR)/$*.def $(OBJS) | ||
77 | @$(DLLWRAP) $(DLLWRAPFLAGS) --def $(OBJDIR)/$*.def $(OBJS) \ | ||
78 | $(OUTDIR)/libplugin.a -o $@ | ||
79 | ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN) | ||
80 | # 'x' must be kept or you'll have "Win32 error 5" | ||
81 | # $ fgrep 5 /usr/include/w32api/winerror.h | head -1 | ||
82 | # #define ERROR_ACCESS_DENIED 5L | ||
83 | else | ||
84 | @chmod -x $@ | ||
85 | endif | ||
86 | endif # end of win32-simulator | ||
87 | |||
88 | endif # end of simulator section | ||
89 | |||
90 | |||
91 | include $(TOOLSDIR)/make.inc | ||
92 | |||
93 | # MEM should be passed on to this makefile with the chosen memory size given | ||
94 | # in number of MB | ||
95 | $(LINKFILE): $(LDS) | ||
96 | @echo "build $@" | ||
97 | @cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) $(DEFINES) \ | ||
98 | -E -P - >$@ | ||
99 | |||
100 | clean: | ||
101 | @echo "cleaning rockboy" | ||
102 | @rm -rf $(OBJDIR)/rockboy | ||
103 | @rm -f $(OBJDIR)/rockboy.* | ||
104 | |||
105 | -include $(DEPFILE) | ||
106 | |||
diff --git a/apps/plugins/rockboy/README b/apps/plugins/rockboy/README new file mode 100755 index 0000000000..f10a5f08d3 --- /dev/null +++ b/apps/plugins/rockboy/README | |||
@@ -0,0 +1,199 @@ | |||
1 | |||
2 | GNUBOY README | ||
3 | |||
4 | |||
5 | INTRO | ||
6 | |||
7 | Welcome to gnuboy, one of the few pieces of Free Software to emulate | ||
8 | the Game Boy handheld game console. Written in ANSI C with a few | ||
9 | optional assembler optimizations for particular cpus, gnuboy supports | ||
10 | a wide range of host systems, and has been tested successfully on: | ||
11 | |||
12 | GNU/Linux | ||
13 | FreeBSD | ||
14 | OpenBSD | ||
15 | BeOS | ||
16 | Linux/390 (IBM S/390 Mainframe) | ||
17 | SunOS/Sun Ultra60 | ||
18 | IRIX/SGI O2 | ||
19 | IRIX/SGI Indy | ||
20 | AIX/Unknown | ||
21 | DR-DOS | ||
22 | MS-DOS | ||
23 | Windows DOS box | ||
24 | Windows 9x/NT/2k | ||
25 | |||
26 | Additionally, gnuboy should run on any other *nix variants that have | ||
27 | ANSI C compilers and that are remotely POSIX compliant. As gnuboy is | ||
28 | Free Software, you're welcome to fix any problems you encounter | ||
29 | building it for a particular system, or to port it to entirely new | ||
30 | systems. | ||
31 | |||
32 | |||
33 | EMULATION | ||
34 | |||
35 | gnuboy emulates nearly all aspects of the (Color) Gameboy, including | ||
36 | all of the following and much more: | ||
37 | |||
38 | Full GBZ80 instruction set. | ||
39 | Scanline-based LCD engine. | ||
40 | Ten sprites per scanline limit. | ||
41 | Support for all CGB graphics extensions. | ||
42 | Sprite DMA, HDMA, and GDMA. | ||
43 | All four sound channels including digital samples. | ||
44 | MBC1, MBC2, MBC3 (including clock), and MBC5 mappers. | ||
45 | Wave pattern memory corruption when sound channel 3 is played. | ||
46 | Pad, timer, divide counter, and other basic hardware registers. | ||
47 | CGB double-speed CPU mode. | ||
48 | |||
49 | Aspects not emulated at this time include: | ||
50 | |||
51 | * Serial IO (link cable). | ||
52 | Undocumented 'extra' ram in OAM space on Gameboy Color. | ||
53 | All Super Gameboy extensions. | ||
54 | * GBC, HuC1, and HuC3 IR ports. | ||
55 | * Obscure mappers such as TAMA5. | ||
56 | Sorting sprites by X coordinate in DMG mode. | ||
57 | HALT instruction skipping in DMG mode. | ||
58 | CPU stalls during HDMA and GDMA. | ||
59 | |||
60 | Only the two marked by * are known to affect the playability of | ||
61 | actual games or demos; the rest are just listed for completeness' | ||
62 | sake. | ||
63 | |||
64 | |||
65 | FEATURES | ||
66 | |||
67 | In addition to basic emulation, gnuboy provides the following | ||
68 | features: | ||
69 | |||
70 | Highly flexible keybinding and configuration subsystem. | ||
71 | State saving and loading at any point. | ||
72 | Very precise timing/synchronization, preserved across save/load. | ||
73 | Joystick support on Linux, DOS, and all SDL-based ports. | ||
74 | Fully customizable palettes for DMG games. | ||
75 | Screen scaling by a factor of 2, 3, or 4 in all ports. | ||
76 | Hardware-based screen scaling on platforms where it's available. | ||
77 | Debug traces to stdout. | ||
78 | Dynamic palette allocation when run in 256-color modes... | ||
79 | OR simulated 3/3/2 bits per channel in 256-color modes. | ||
80 | |||
81 | For information on configuring and using these features, see the | ||
82 | additional documentation in the "docs" directory. | ||
83 | |||
84 | |||
85 | COMPATIBILITY | ||
86 | |||
87 | Out of over 300 results reported by testers, all games are known to | ||
88 | work perfectly on gnuboy with the following exceptions: | ||
89 | |||
90 | Fighting Phoenix (Japanese) may or may not work since it uses the | ||
91 | HuC1 memory controller, which is not implemented properly. There has | ||
92 | been no report either way so far. | ||
93 | |||
94 | Pocket Bomberman (Japanese version, which uses HuC1) runs, but can | ||
95 | be made to crash if the player jumps into the ceiling in the first | ||
96 | level. It's not clear whether this bug is MBC-related, something | ||
97 | else, or an actual bug in the original game. | ||
98 | |||
99 | Monster Go! Go! Go! (Japanese) is unplayable. The cause of the | ||
100 | problem is not fully known, but it's either a very bad dump or it's | ||
101 | using some sort of specialized MBC that's not documented. | ||
102 | |||
103 | Final Fantasy Adventure has visual problems with the fade between | ||
104 | screens. Does not affect gameplay. | ||
105 | |||
106 | Bubble Bobble 2 has some minor tile glitches right before gameplay | ||
107 | actually begins. Cause unknown. Does not affect gameplay. | ||
108 | |||
109 | Alone in the Dark is reported to have minor visual glitches. I | ||
110 | haven't seen it myself so I can't judge their severity. | ||
111 | |||
112 | Both new Zelda games are reported to have a visual glitch at the | ||
113 | beginning of the game, and on certain other screens. I haven't seen | ||
114 | the problem myself, but supposedly it impacts gameplay to some | ||
115 | extent. | ||
116 | |||
117 | Please report any other incompatibilities discovered directly to | ||
118 | gnuboy@unix-fu.org, so that they can be documented and hopefully | ||
119 | fixed. | ||
120 | |||
121 | |||
122 | FUTURE / WISHLIST | ||
123 | |||
124 | Here's a brief list of what may appear in gnuboy in the future: | ||
125 | |||
126 | Screenshots. | ||
127 | Integrated debugger. | ||
128 | Super Gameboy support. | ||
129 | Serial link over the internet. | ||
130 | Serial link to a real Gameboy with a custom cable. | ||
131 | Configurable color filters to provide more authentic LCD look. | ||
132 | Custom colorization of DMG games on a per-tile basis. | ||
133 | Support for more colorspaces in the hardware scaler. | ||
134 | Recording audio. | ||
135 | GBS player built from the same source tree. | ||
136 | Full recording and playback of emulation. | ||
137 | So-called "high level emulation" of certain typical dumb loops. | ||
138 | |||
139 | Features that are not likely to appear soon or at all include: | ||
140 | |||
141 | Rumble support - this would be nice, but SDL doesn't seem to support | ||
142 | force-feedback yet. We'll see about it in the long-term though. | ||
143 | |||
144 | Eagle/2xSaI/etc. - probably not feasible since these libraries don't | ||
145 | appear to be compatible with the terms of the GPL. We might work on | ||
146 | our own interpolation engine eventually, but that's low priority. | ||
147 | |||
148 | GUI/GUI-like features - such things are best handled by external | ||
149 | front-ends. We might eventually add a mechanism for external | ||
150 | programs to communicate with gnuboy and reconfigure it while it's | ||
151 | running, however. | ||
152 | |||
153 | Plugins - NO! The way I see it, plugins are just an attempt to work | ||
154 | around the GPL. In any case, even if you are adding plugin support | ||
155 | yourself, you are bound by the terms of the GPL when linking ANY | ||
156 | code to gnuboy, including dynamic-linked modules. However we'd | ||
157 | rather not deal with this mess to begin with. | ||
158 | |||
159 | Compressed ROMs/Saves - this one is very iffy. On most systems, this | ||
160 | is redundant; *nix users can just pipe the rom through a | ||
161 | decompression program, and Windows users can just double-click or | ||
162 | drag files from their favorite GUI unzipper program. Linking to zlib | ||
163 | isn't really acceptable since it's massively bloated and we don't | ||
164 | want to include it with gnuboy or add external dependencies. We may, | ||
165 | however, write our own tiny decompressor to use at some point. | ||
166 | |||
167 | Ideas and suggestions for other features are welcome, but won't | ||
168 | necessarily be used. You're of course also free to add features | ||
169 | yourself, and if they fit well into the main tree they may eventually | ||
170 | get included in the official release. See the file HACKING for more | ||
171 | details on modifying and/or contributing. | ||
172 | |||
173 | |||
174 | THANKS | ||
175 | |||
176 | Thanks goes out to everyone who's expressed interest in gnuboy by | ||
177 | writing -- users, porters, authors of other emulators, and so forth. | ||
178 | Apologies if we don't get a personal response out to everyone, but | ||
179 | either way, consider your feedback appreciated. | ||
180 | |||
181 | |||
182 | EPILOGUE | ||
183 | |||
184 | OK, that looks like about it. More to come, stick around... | ||
185 | |||
186 | |||
187 | |||
188 | -Laguna <laguna@aerifal.cx> | ||
189 | |||
190 | |||
191 | |||
192 | |||
193 | |||
194 | |||
195 | |||
196 | |||
197 | |||
198 | |||
199 | |||
diff --git a/apps/plugins/rockboy/Version b/apps/plugins/rockboy/Version new file mode 100755 index 0000000000..0b12c4271d --- /dev/null +++ b/apps/plugins/rockboy/Version | |||
@@ -0,0 +1,5 @@ | |||
1 | #define VERSION "1.0.3" /* | ||
2 | VERSION = 1.0.3 | ||
3 | # */ | ||
4 | |||
5 | |||
diff --git a/apps/plugins/rockboy/archos.lds b/apps/plugins/rockboy/archos.lds new file mode 100755 index 0000000000..23d03c6297 --- /dev/null +++ b/apps/plugins/rockboy/archos.lds | |||
@@ -0,0 +1,46 @@ | |||
1 | #include "config.h" | ||
2 | |||
3 | /* linker script for rockboy as an overlay, | ||
4 | * only used/ necessary for SH-based archos targets */ | ||
5 | |||
6 | OUTPUT_FORMAT(elf32-sh) | ||
7 | |||
8 | #define DRAMORIG 0x09000000 | ||
9 | #define PLUGIN_LENGTH 0x8000 | ||
10 | |||
11 | #define OVERLAY_LENGTH 0x68000 | ||
12 | #define OVERLAY_ORIGIN (DRAMORIG + (MEMORYSIZE * 0x100000) - PLUGIN_LENGTH - OVERLAY_LENGTH) | ||
13 | |||
14 | MEMORY | ||
15 | { | ||
16 | OVERLAY_RAM : ORIGIN = OVERLAY_ORIGIN, LENGTH = OVERLAY_LENGTH | ||
17 | } | ||
18 | |||
19 | SECTIONS | ||
20 | { | ||
21 | .header : { | ||
22 | _ovl_start_addr = .; | ||
23 | *(.header) | ||
24 | } > OVERLAY_RAM | ||
25 | |||
26 | .text : { | ||
27 | *(.entry) | ||
28 | *(.text) | ||
29 | } > OVERLAY_RAM | ||
30 | |||
31 | .data : { | ||
32 | *(.data) | ||
33 | } > OVERLAY_RAM | ||
34 | |||
35 | .bss : { | ||
36 | *(.bss) | ||
37 | } > OVERLAY_RAM | ||
38 | |||
39 | .rodata : { | ||
40 | *(.rodata) | ||
41 | *(.rodata.str1.1) | ||
42 | *(.rodata.str1.4) | ||
43 | . = ALIGN(0x4); | ||
44 | _ovl_end_addr = .; | ||
45 | } > OVERLAY_RAM | ||
46 | } | ||
diff --git a/apps/plugins/rockboy/cpu.c b/apps/plugins/rockboy/cpu.c new file mode 100644 index 0000000000..44a870a6eb --- /dev/null +++ b/apps/plugins/rockboy/cpu.c | |||
@@ -0,0 +1,880 @@ | |||
1 | |||
2 | |||
3 | |||
4 | #include "rockmacros.h" | ||
5 | #include "defs.h" | ||
6 | #include "regs.h" | ||
7 | #include "hw.h" | ||
8 | #include "cpu.h" | ||
9 | #include "lcdc.h" | ||
10 | #include "mem.h" | ||
11 | #include "fastmem.h" | ||
12 | #include "cpuregs.h" | ||
13 | #include "cpucore.h" | ||
14 | |||
15 | #ifdef USE_ASM | ||
16 | #include "asm.h" | ||
17 | #endif | ||
18 | |||
19 | |||
20 | struct cpu cpu; | ||
21 | |||
22 | |||
23 | |||
24 | |||
25 | #define ZFLAG(n) ( (n) ? 0 : FZ ) | ||
26 | |||
27 | |||
28 | #define PUSH(w) ( (SP -= 2), (writew(xSP, (w))) ) | ||
29 | #define POP(w) ( ((w) = readw(xSP)), (SP += 2) ) | ||
30 | |||
31 | |||
32 | #define FETCH_OLD ( mbc.rmap[PC>>12] \ | ||
33 | ? mbc.rmap[PC>>12][PC++] \ | ||
34 | : mem_read(PC++) ) | ||
35 | |||
36 | #define FETCH (readb(PC++)) | ||
37 | |||
38 | |||
39 | #define INC(r) { ((r)++); \ | ||
40 | F = (F & (FL|FC)) | incflag_table[(r)]; } | ||
41 | |||
42 | #define DEC(r) { ((r)--); \ | ||
43 | F = (F & (FL|FC)) | decflag_table[(r)]; } | ||
44 | |||
45 | #define INCW(r) ( (r)++ ) | ||
46 | |||
47 | #define DECW(r) ( (r)-- ) | ||
48 | |||
49 | #define ADD(n) { \ | ||
50 | W(acc) = (un16)A + (un16)(n); \ | ||
51 | F = (ZFLAG(LB(acc))) \ | ||
52 | | (FH & ((A ^ (n) ^ LB(acc)) << 1)) \ | ||
53 | | (HB(acc) << 4); \ | ||
54 | A = LB(acc); } | ||
55 | |||
56 | #define ADC(n) { \ | ||
57 | W(acc) = (un16)A + (un16)(n) + (un16)((F&FC)>>4); \ | ||
58 | F = (ZFLAG(LB(acc))) \ | ||
59 | | (FH & ((A ^ (n) ^ LB(acc)) << 1)) \ | ||
60 | | (HB(acc) << 4); \ | ||
61 | A = LB(acc); } | ||
62 | |||
63 | #define ADDW(n) { \ | ||
64 | DW(acc) = (un32)HL + (un32)(n); \ | ||
65 | F = (F & (FZ)) \ | ||
66 | | (FH & ((H ^ ((n)>>8) ^ HB(acc)) << 1)) \ | ||
67 | | (acc.b[HI][LO] << 4); \ | ||
68 | HL = W(acc); } | ||
69 | |||
70 | #define ADDSP(n) { \ | ||
71 | DW(acc) = (un32)SP + (un32)(n8)(n); \ | ||
72 | F = (FH & (((SP>>8) ^ ((n)>>8) ^ HB(acc)) << 1)) \ | ||
73 | | (acc.b[HI][LO] << 4); \ | ||
74 | SP = W(acc); } | ||
75 | |||
76 | #define LDHLSP(n) { \ | ||
77 | DW(acc) = (un32)SP + (un32)(n8)(n); \ | ||
78 | F = (FH & (((SP>>8) ^ ((n)>>8) ^ HB(acc)) << 1)) \ | ||
79 | | (acc.b[HI][LO] << 4); \ | ||
80 | HL = W(acc); } | ||
81 | |||
82 | #define CP(n) { \ | ||
83 | W(acc) = (un16)A - (un16)(n); \ | ||
84 | F = FN \ | ||
85 | | (ZFLAG(LB(acc))) \ | ||
86 | | (FH & ((A ^ (n) ^ LB(acc)) << 1)) \ | ||
87 | | ((un8)(-(n8)HB(acc)) << 4); } | ||
88 | |||
89 | #define SUB(n) { CP((n)); A = LB(acc); } | ||
90 | |||
91 | #define SBC(n) { \ | ||
92 | W(acc) = (un16)A - (un16)(n) - (un16)((F&FC)>>4); \ | ||
93 | F = FN \ | ||
94 | | (ZFLAG((n8)LB(acc))) \ | ||
95 | | (FH & ((A ^ (n) ^ LB(acc)) << 1)) \ | ||
96 | | ((un8)(-(n8)HB(acc)) << 4); \ | ||
97 | A = LB(acc); } | ||
98 | |||
99 | #define AND(n) { A &= (n); \ | ||
100 | F = ZFLAG(A) | FH; } | ||
101 | |||
102 | #define XOR(n) { A ^= (n); \ | ||
103 | F = ZFLAG(A); } | ||
104 | |||
105 | #define OR(n) { A |= (n); \ | ||
106 | F = ZFLAG(A); } | ||
107 | |||
108 | #define RLCA(r) { (r) = ((r)>>7) | ((r)<<1); \ | ||
109 | F = (((r)&0x01)<<4); } | ||
110 | |||
111 | #define RRCA(r) { (r) = ((r)<<7) | ((r)>>1); \ | ||
112 | F = (((r)&0x80)>>3); } | ||
113 | |||
114 | #define RLA(r) { \ | ||
115 | LB(acc) = (((r)&0x80)>>3); \ | ||
116 | (r) = ((r)<<1) | ((F&FC)>>4); \ | ||
117 | F = LB(acc); } | ||
118 | |||
119 | #define RRA(r) { \ | ||
120 | LB(acc) = (((r)&0x01)<<4); \ | ||
121 | (r) = ((r)>>1) | ((F&FC)<<3); \ | ||
122 | F = LB(acc); } | ||
123 | |||
124 | #define RLC(r) { RLCA(r); F |= ZFLAG(r); } | ||
125 | #define RRC(r) { RRCA(r); F |= ZFLAG(r); } | ||
126 | #define RL(r) { RLA(r); F |= ZFLAG(r); } | ||
127 | #define RR(r) { RRA(r); F |= ZFLAG(r); } | ||
128 | |||
129 | #define SLA(r) { \ | ||
130 | LB(acc) = (((r)&0x80)>>3); \ | ||
131 | (r) <<= 1; \ | ||
132 | F = ZFLAG((r)) | LB(acc); } | ||
133 | |||
134 | #define SRA(r) { \ | ||
135 | LB(acc) = (((r)&0x01)<<4); \ | ||
136 | (r) = (un8)(((n8)(r))>>1); \ | ||
137 | F = ZFLAG((r)) | LB(acc); } | ||
138 | |||
139 | #define SRL(r) { \ | ||
140 | LB(acc) = (((r)&0x01)<<4); \ | ||
141 | (r) >>= 1; \ | ||
142 | F = ZFLAG((r)) | LB(acc); } | ||
143 | |||
144 | #define CPL(r) { \ | ||
145 | (r) = ~(r); \ | ||
146 | F |= (FH|FN); } | ||
147 | |||
148 | #define SCF { F = (F & (FZ)) | FC; } | ||
149 | |||
150 | #define CCF { F = (F & (FZ|FC)) ^ FC; } | ||
151 | |||
152 | #define DAA { \ | ||
153 | A += (LB(acc) = daa_table[((((int)F)&0x70)<<4) | A]); \ | ||
154 | F = (F & (FN)) | ZFLAG(A) | daa_carry_table[LB(acc)>>2]; } | ||
155 | |||
156 | #define SWAP(r) { \ | ||
157 | (r) = swap_table[(r)]; \ | ||
158 | F = ZFLAG((r)); } | ||
159 | |||
160 | #define BIT(n,r) { F = (F & FC) | ZFLAG(((r) & (1 << (n)))) | FH; } | ||
161 | #define RES(n,r) { (r) &= ~(1 << (n)); } | ||
162 | #define SET(n,r) { (r) |= (1 << (n)); } | ||
163 | |||
164 | #define CB_REG_CASES(r, n) \ | ||
165 | case 0x00|(n): RLC(r); break; \ | ||
166 | case 0x08|(n): RRC(r); break; \ | ||
167 | case 0x10|(n): RL(r); break; \ | ||
168 | case 0x18|(n): RR(r); break; \ | ||
169 | case 0x20|(n): SLA(r); break; \ | ||
170 | case 0x28|(n): SRA(r); break; \ | ||
171 | case 0x30|(n): SWAP(r); break; \ | ||
172 | case 0x38|(n): SRL(r); break; \ | ||
173 | case 0x40|(n): BIT(0, r); break; \ | ||
174 | case 0x48|(n): BIT(1, r); break; \ | ||
175 | case 0x50|(n): BIT(2, r); break; \ | ||
176 | case 0x58|(n): BIT(3, r); break; \ | ||
177 | case 0x60|(n): BIT(4, r); break; \ | ||
178 | case 0x68|(n): BIT(5, r); break; \ | ||
179 | case 0x70|(n): BIT(6, r); break; \ | ||
180 | case 0x78|(n): BIT(7, r); break; \ | ||
181 | case 0x80|(n): RES(0, r); break; \ | ||
182 | case 0x88|(n): RES(1, r); break; \ | ||
183 | case 0x90|(n): RES(2, r); break; \ | ||
184 | case 0x98|(n): RES(3, r); break; \ | ||
185 | case 0xA0|(n): RES(4, r); break; \ | ||
186 | case 0xA8|(n): RES(5, r); break; \ | ||
187 | case 0xB0|(n): RES(6, r); break; \ | ||
188 | case 0xB8|(n): RES(7, r); break; \ | ||
189 | case 0xC0|(n): SET(0, r); break; \ | ||
190 | case 0xC8|(n): SET(1, r); break; \ | ||
191 | case 0xD0|(n): SET(2, r); break; \ | ||
192 | case 0xD8|(n): SET(3, r); break; \ | ||
193 | case 0xE0|(n): SET(4, r); break; \ | ||
194 | case 0xE8|(n): SET(5, r); break; \ | ||
195 | case 0xF0|(n): SET(6, r); break; \ | ||
196 | case 0xF8|(n): SET(7, r); break; | ||
197 | |||
198 | |||
199 | #define ALU_CASES(base, imm, op, label) \ | ||
200 | case (imm): b = FETCH; goto label; \ | ||
201 | case (base): b = B; goto label; \ | ||
202 | case (base)+1: b = C; goto label; \ | ||
203 | case (base)+2: b = D; goto label; \ | ||
204 | case (base)+3: b = E; goto label; \ | ||
205 | case (base)+4: b = H; goto label; \ | ||
206 | case (base)+5: b = L; goto label; \ | ||
207 | case (base)+6: b = readb(HL); goto label; \ | ||
208 | case (base)+7: b = A; \ | ||
209 | label: op(b); break; | ||
210 | |||
211 | |||
212 | |||
213 | |||
214 | |||
215 | |||
216 | |||
217 | |||
218 | #define JR ( PC += 1+(n8)readb(PC) ) | ||
219 | #define JP ( PC = readw(PC) ) | ||
220 | |||
221 | #define CALL ( PUSH(PC+2), JP ) | ||
222 | |||
223 | #define NOJR ( clen--, PC++ ) | ||
224 | #define NOJP ( clen--, PC+=2 ) | ||
225 | #define NOCALL ( clen-=3, PC+=2 ) | ||
226 | #define NORET ( clen-=3 ) | ||
227 | |||
228 | #define RST(n) { PUSH(PC); PC = (n); } | ||
229 | |||
230 | #define RET ( POP(PC) ) | ||
231 | |||
232 | #define EI ( IMA = 1 ) | ||
233 | #define DI ( cpu.halt = IMA = IME = 0 ) | ||
234 | |||
235 | |||
236 | |||
237 | #define PRE_INT ( DI, PUSH(PC) ) | ||
238 | #define THROW_INT(n) ( (IF &= ~(1<<(n))), (PC = 0x40+((n)<<3)) ) | ||
239 | |||
240 | |||
241 | |||
242 | |||
243 | void cpu_reset(void) | ||
244 | { | ||
245 | cpu.speed = 0; | ||
246 | cpu.halt = 0; | ||
247 | cpu.div = 0; | ||
248 | cpu.tim = 0; | ||
249 | cpu.lcdc = 40; | ||
250 | |||
251 | IME = 0; | ||
252 | IMA = 0; | ||
253 | |||
254 | PC = 0x0100; | ||
255 | SP = 0xFFFE; | ||
256 | AF = 0x01B0; | ||
257 | BC = 0x0013; | ||
258 | DE = 0x00D8; | ||
259 | HL = 0x014D; | ||
260 | |||
261 | if (hw.cgb) A = 0x11; | ||
262 | if (hw.gba) B = 0x01; | ||
263 | } | ||
264 | |||
265 | |||
266 | void div_advance(int cnt) | ||
267 | { | ||
268 | cpu.div += (cnt<<1); | ||
269 | if (cpu.div >= 256) | ||
270 | { | ||
271 | R_DIV += (cpu.div >> 8); | ||
272 | cpu.div &= 0xff; | ||
273 | } | ||
274 | } | ||
275 | |||
276 | void timer_advance(int cnt) | ||
277 | { | ||
278 | int unit, tima; | ||
279 | |||
280 | if (!(R_TAC & 0x04)) return; | ||
281 | |||
282 | unit = ((-R_TAC) & 3) << 1; | ||
283 | cpu.tim += (cnt<<unit); | ||
284 | |||
285 | if (cpu.tim >= 512) | ||
286 | { | ||
287 | tima = R_TIMA + (cpu.tim >> 9); | ||
288 | cpu.tim &= 0x1ff; | ||
289 | if (tima >= 256) | ||
290 | { | ||
291 | hw_interrupt(IF_TIMER, IF_TIMER); | ||
292 | hw_interrupt(0, IF_TIMER); | ||
293 | } | ||
294 | while (tima >= 256) | ||
295 | tima = tima - 256 + R_TMA; | ||
296 | R_TIMA = tima; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | void lcdc_advance(int cnt) | ||
301 | { | ||
302 | cpu.lcdc -= cnt; | ||
303 | if (cpu.lcdc <= 0) lcdc_trans(); | ||
304 | } | ||
305 | |||
306 | void sound_advance(int cnt) | ||
307 | { | ||
308 | cpu.snd += cnt; | ||
309 | } | ||
310 | |||
311 | void cpu_timers(int cnt) | ||
312 | { | ||
313 | div_advance(cnt << cpu.speed); | ||
314 | timer_advance(cnt << cpu.speed); | ||
315 | lcdc_advance(cnt); | ||
316 | sound_advance(cnt); | ||
317 | } | ||
318 | |||
319 | int cpu_idle(int max) | ||
320 | { | ||
321 | int cnt, unit; | ||
322 | |||
323 | if (!(cpu.halt && IME)) return 0; | ||
324 | if (R_IF & R_IE) | ||
325 | { | ||
326 | cpu.halt = 0; | ||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | /* Make sure we don't miss lcdc status events! */ | ||
331 | if ((R_IE & (IF_VBLANK | IF_STAT)) && (max > cpu.lcdc)) | ||
332 | max = cpu.lcdc; | ||
333 | |||
334 | /* If timer interrupt cannot happen, this is very simple! */ | ||
335 | if (!((R_IE & IF_TIMER) && (R_TAC & 0x04))) | ||
336 | { | ||
337 | cpu_timers(max); | ||
338 | return max; | ||
339 | } | ||
340 | |||
341 | /* Figure out when the next timer interrupt will happen */ | ||
342 | unit = ((-R_TAC) & 3) << 1; | ||
343 | cnt = (511 - cpu.tim + (1<<unit)) >> unit; | ||
344 | cnt += (255 - R_TIMA) << (9 - unit); | ||
345 | |||
346 | if (max < cnt) | ||
347 | cnt = max; | ||
348 | |||
349 | cpu_timers(cnt); | ||
350 | return cnt; | ||
351 | } | ||
352 | |||
353 | #ifndef ASM_CPU_EMULATE | ||
354 | |||
355 | extern int debug_trace; | ||
356 | |||
357 | int cpu_emulate(int cycles) | ||
358 | { | ||
359 | int i; | ||
360 | byte op, cbop; | ||
361 | int clen; | ||
362 | static union reg acc; | ||
363 | static byte b; | ||
364 | static word w; | ||
365 | |||
366 | i = cycles; | ||
367 | next: | ||
368 | if ((clen = cpu_idle(i))) | ||
369 | { | ||
370 | i -= clen; | ||
371 | if (i > 0) goto next; | ||
372 | return cycles-i; | ||
373 | } | ||
374 | |||
375 | if (IME && (IF & IE)) | ||
376 | { | ||
377 | PRE_INT; | ||
378 | switch ((byte)(IF & IE)) | ||
379 | { | ||
380 | case 0x01: case 0x03: case 0x05: case 0x07: | ||
381 | case 0x09: case 0x0B: case 0x0D: case 0x0F: | ||
382 | case 0x11: case 0x13: case 0x15: case 0x17: | ||
383 | case 0x19: case 0x1B: case 0x1D: case 0x1F: | ||
384 | THROW_INT(0); break; | ||
385 | case 0x02: case 0x06: case 0x0A: case 0x0E: | ||
386 | case 0x12: case 0x16: case 0x1A: case 0x1E: | ||
387 | THROW_INT(1); break; | ||
388 | case 0x04: case 0x0C: case 0x14: case 0x1C: | ||
389 | THROW_INT(2); break; | ||
390 | case 0x08: case 0x18: | ||
391 | THROW_INT(3); break; | ||
392 | case 0x10: | ||
393 | THROW_INT(4); break; | ||
394 | } | ||
395 | } | ||
396 | IME = IMA; | ||
397 | |||
398 | // if (debug_trace) debug_disassemble(PC, 1); | ||
399 | |||
400 | op = FETCH; | ||
401 | clen = cycles_table[op]; | ||
402 | |||
403 | switch(op) | ||
404 | { | ||
405 | case 0x00: /* NOP */ | ||
406 | case 0x40: /* LD B,B */ | ||
407 | case 0x49: /* LD C,C */ | ||
408 | case 0x52: /* LD D,D */ | ||
409 | case 0x5B: /* LD E,E */ | ||
410 | case 0x64: /* LD H,H */ | ||
411 | case 0x6D: /* LD L,L */ | ||
412 | case 0x7F: /* LD A,A */ | ||
413 | break; | ||
414 | |||
415 | case 0x41: /* LD B,C */ | ||
416 | B = C; break; | ||
417 | case 0x42: /* LD B,D */ | ||
418 | B = D; break; | ||
419 | case 0x43: /* LD B,E */ | ||
420 | B = E; break; | ||
421 | case 0x44: /* LD B,H */ | ||
422 | B = H; break; | ||
423 | case 0x45: /* LD B,L */ | ||
424 | B = L; break; | ||
425 | case 0x46: /* LD B,(HL) */ | ||
426 | B = readb(xHL); break; | ||
427 | case 0x47: /* LD B,A */ | ||
428 | B = A; break; | ||
429 | |||
430 | case 0x48: /* LD C,B */ | ||
431 | C = B; break; | ||
432 | case 0x4A: /* LD C,D */ | ||
433 | C = D; break; | ||
434 | case 0x4B: /* LD C,E */ | ||
435 | C = E; break; | ||
436 | case 0x4C: /* LD C,H */ | ||
437 | C = H; break; | ||
438 | case 0x4D: /* LD C,L */ | ||
439 | C = L; break; | ||
440 | case 0x4E: /* LD C,(HL) */ | ||
441 | C = readb(xHL); break; | ||
442 | case 0x4F: /* LD C,A */ | ||
443 | C = A; break; | ||
444 | |||
445 | case 0x50: /* LD D,B */ | ||
446 | D = B; break; | ||
447 | case 0x51: /* LD D,C */ | ||
448 | D = C; break; | ||
449 | case 0x53: /* LD D,E */ | ||
450 | D = E; break; | ||
451 | case 0x54: /* LD D,H */ | ||
452 | D = H; break; | ||
453 | case 0x55: /* LD D,L */ | ||
454 | D = L; break; | ||
455 | case 0x56: /* LD D,(HL) */ | ||
456 | D = readb(xHL); break; | ||
457 | case 0x57: /* LD D,A */ | ||
458 | D = A; break; | ||
459 | |||
460 | case 0x58: /* LD E,B */ | ||
461 | E = B; break; | ||
462 | case 0x59: /* LD E,C */ | ||
463 | E = C; break; | ||
464 | case 0x5A: /* LD E,D */ | ||
465 | E = D; break; | ||
466 | case 0x5C: /* LD E,H */ | ||
467 | E = H; break; | ||
468 | case 0x5D: /* LD E,L */ | ||
469 | E = L; break; | ||
470 | case 0x5E: /* LD E,(HL) */ | ||
471 | E = readb(xHL); break; | ||
472 | case 0x5F: /* LD E,A */ | ||
473 | E = A; break; | ||
474 | |||
475 | case 0x60: /* LD H,B */ | ||
476 | H = B; break; | ||
477 | case 0x61: /* LD H,C */ | ||
478 | H = C; break; | ||
479 | case 0x62: /* LD H,D */ | ||
480 | H = D; break; | ||
481 | case 0x63: /* LD H,E */ | ||
482 | H = E; break; | ||
483 | case 0x65: /* LD H,L */ | ||
484 | H = L; break; | ||
485 | case 0x66: /* LD H,(HL) */ | ||
486 | H = readb(xHL); break; | ||
487 | case 0x67: /* LD H,A */ | ||
488 | H = A; break; | ||
489 | |||
490 | case 0x68: /* LD L,B */ | ||
491 | L = B; break; | ||
492 | case 0x69: /* LD L,C */ | ||
493 | L = C; break; | ||
494 | case 0x6A: /* LD L,D */ | ||
495 | L = D; break; | ||
496 | case 0x6B: /* LD L,E */ | ||
497 | L = E; break; | ||
498 | case 0x6C: /* LD L,H */ | ||
499 | L = H; break; | ||
500 | case 0x6E: /* LD L,(HL) */ | ||
501 | L = readb(xHL); break; | ||
502 | case 0x6F: /* LD L,A */ | ||
503 | L = A; break; | ||
504 | |||
505 | case 0x70: /* LD (HL),B */ | ||
506 | b = B; goto __LD_HL; | ||
507 | case 0x71: /* LD (HL),C */ | ||
508 | b = C; goto __LD_HL; | ||
509 | case 0x72: /* LD (HL),D */ | ||
510 | b = D; goto __LD_HL; | ||
511 | case 0x73: /* LD (HL),E */ | ||
512 | b = E; goto __LD_HL; | ||
513 | case 0x74: /* LD (HL),H */ | ||
514 | b = H; goto __LD_HL; | ||
515 | case 0x75: /* LD (HL),L */ | ||
516 | b = L; goto __LD_HL; | ||
517 | case 0x77: /* LD (HL),A */ | ||
518 | b = A; | ||
519 | __LD_HL: | ||
520 | writeb(xHL,b); | ||
521 | break; | ||
522 | |||
523 | case 0x78: /* LD A,B */ | ||
524 | A = B; break; | ||
525 | case 0x79: /* LD A,C */ | ||
526 | A = C; break; | ||
527 | case 0x7A: /* LD A,D */ | ||
528 | A = D; break; | ||
529 | case 0x7B: /* LD A,E */ | ||
530 | A = E; break; | ||
531 | case 0x7C: /* LD A,H */ | ||
532 | A = H; break; | ||
533 | case 0x7D: /* LD A,L */ | ||
534 | A = L; break; | ||
535 | case 0x7E: /* LD A,(HL) */ | ||
536 | A = readb(xHL); break; | ||
537 | |||
538 | case 0x01: /* LD BC,imm */ | ||
539 | BC = readw(xPC); PC += 2; break; | ||
540 | case 0x11: /* LD DE,imm */ | ||
541 | DE = readw(xPC); PC += 2; break; | ||
542 | case 0x21: /* LD HL,imm */ | ||
543 | HL = readw(xPC); PC += 2; break; | ||
544 | case 0x31: /* LD SP,imm */ | ||
545 | SP = readw(xPC); PC += 2; break; | ||
546 | |||
547 | case 0x02: /* LD (BC),A */ | ||
548 | writeb(xBC, A); break; | ||
549 | case 0x0A: /* LD A,(BC) */ | ||
550 | A = readb(xBC); break; | ||
551 | case 0x12: /* LD (DE),A */ | ||
552 | writeb(xDE, A); break; | ||
553 | case 0x1A: /* LD A,(DE) */ | ||
554 | A = readb(xDE); break; | ||
555 | |||
556 | case 0x22: /* LDI (HL),A */ | ||
557 | writeb(xHL, A); HL++; break; | ||
558 | case 0x2A: /* LDI A,(HL) */ | ||
559 | A = readb(xHL); HL++; break; | ||
560 | case 0x32: /* LDD (HL),A */ | ||
561 | writeb(xHL, A); HL--; break; | ||
562 | case 0x3A: /* LDD A,(HL) */ | ||
563 | A = readb(xHL); HL--; break; | ||
564 | |||
565 | case 0x06: /* LD B,imm */ | ||
566 | B = FETCH; break; | ||
567 | case 0x0E: /* LD C,imm */ | ||
568 | C = FETCH; break; | ||
569 | case 0x16: /* LD D,imm */ | ||
570 | D = FETCH; break; | ||
571 | case 0x1E: /* LD E,imm */ | ||
572 | E = FETCH; break; | ||
573 | case 0x26: /* LD H,imm */ | ||
574 | H = FETCH; break; | ||
575 | case 0x2E: /* LD L,imm */ | ||
576 | L = FETCH; break; | ||
577 | case 0x36: /* LD (HL),imm */ | ||
578 | b = FETCH; writeb(xHL, b); break; | ||
579 | case 0x3E: /* LD A,imm */ | ||
580 | A = FETCH; break; | ||
581 | |||
582 | case 0x08: /* LD (imm),SP */ | ||
583 | writew(readw(xPC), SP); PC += 2; break; | ||
584 | case 0xEA: /* LD (imm),A */ | ||
585 | writeb(readw(xPC), A); PC += 2; break; | ||
586 | |||
587 | case 0xE0: /* LDH (imm),A */ | ||
588 | writehi(FETCH, A); break; | ||
589 | case 0xE2: /* LDH (C),A */ | ||
590 | writehi(C, A); break; | ||
591 | case 0xF0: /* LDH A,(imm) */ | ||
592 | A = readhi(FETCH); break; | ||
593 | case 0xF2: /* LDH A,(C) (undocumented) */ | ||
594 | A = readhi(C); break; | ||
595 | |||
596 | |||
597 | case 0xF8: /* LD HL,SP+imm */ | ||
598 | b = FETCH; LDHLSP(b); break; | ||
599 | case 0xF9: /* LD SP,HL */ | ||
600 | SP = HL; break; | ||
601 | case 0xFA: /* LD A,(imm) */ | ||
602 | A = readb(readw(xPC)); PC += 2; break; | ||
603 | |||
604 | ALU_CASES(0x80, 0xC6, ADD, __ADD) | ||
605 | ALU_CASES(0x88, 0xCE, ADC, __ADC) | ||
606 | ALU_CASES(0x90, 0xD6, SUB, __SUB) | ||
607 | ALU_CASES(0x98, 0xDE, SBC, __SBC) | ||
608 | ALU_CASES(0xA0, 0xE6, AND, __AND) | ||
609 | ALU_CASES(0xA8, 0xEE, XOR, __XOR) | ||
610 | ALU_CASES(0xB0, 0xF6, OR, __OR) | ||
611 | ALU_CASES(0xB8, 0xFE, CP, __CP) | ||
612 | |||
613 | case 0x09: /* ADD HL,BC */ | ||
614 | w = BC; goto __ADDW; | ||
615 | case 0x19: /* ADD HL,DE */ | ||
616 | w = DE; goto __ADDW; | ||
617 | case 0x39: /* ADD HL,SP */ | ||
618 | w = SP; goto __ADDW; | ||
619 | case 0x29: /* ADD HL,HL */ | ||
620 | w = HL; | ||
621 | __ADDW: | ||
622 | ADDW(w); | ||
623 | break; | ||
624 | |||
625 | case 0x04: /* INC B */ | ||
626 | INC(B); break; | ||
627 | case 0x0C: /* INC C */ | ||
628 | INC(C); break; | ||
629 | case 0x14: /* INC D */ | ||
630 | INC(D); break; | ||
631 | case 0x1C: /* INC E */ | ||
632 | INC(E); break; | ||
633 | case 0x24: /* INC H */ | ||
634 | INC(H); break; | ||
635 | case 0x2C: /* INC L */ | ||
636 | INC(L); break; | ||
637 | case 0x34: /* INC (HL) */ | ||
638 | b = readb(xHL); | ||
639 | INC(b); | ||
640 | writeb(xHL, b); | ||
641 | break; | ||
642 | case 0x3C: /* INC A */ | ||
643 | INC(A); break; | ||
644 | |||
645 | case 0x03: /* INC BC */ | ||
646 | INCW(BC); break; | ||
647 | case 0x13: /* INC DE */ | ||
648 | INCW(DE); break; | ||
649 | case 0x23: /* INC HL */ | ||
650 | INCW(HL); break; | ||
651 | case 0x33: /* INC SP */ | ||
652 | INCW(SP); break; | ||
653 | |||
654 | case 0x05: /* DEC B */ | ||
655 | DEC(B); break; | ||
656 | case 0x0D: /* DEC C */ | ||
657 | DEC(C); break; | ||
658 | case 0x15: /* DEC D */ | ||
659 | DEC(D); break; | ||
660 | case 0x1D: /* DEC E */ | ||
661 | DEC(E); break; | ||
662 | case 0x25: /* DEC H */ | ||
663 | DEC(H); break; | ||
664 | case 0x2D: /* DEC L */ | ||
665 | DEC(L); break; | ||
666 | case 0x35: /* DEC (HL) */ | ||
667 | b = readb(xHL); | ||
668 | DEC(b); | ||
669 | writeb(xHL, b); | ||
670 | break; | ||
671 | case 0x3D: /* DEC A */ | ||
672 | DEC(A); break; | ||
673 | |||
674 | case 0x0B: /* DEC BC */ | ||
675 | DECW(BC); break; | ||
676 | case 0x1B: /* DEC DE */ | ||
677 | DECW(DE); break; | ||
678 | case 0x2B: /* DEC HL */ | ||
679 | DECW(HL); break; | ||
680 | case 0x3B: /* DEC SP */ | ||
681 | DECW(SP); break; | ||
682 | |||
683 | case 0x07: /* RLCA */ | ||
684 | RLCA(A); break; | ||
685 | case 0x0F: /* RRCA */ | ||
686 | RRCA(A); break; | ||
687 | case 0x17: /* RLA */ | ||
688 | RLA(A); break; | ||
689 | case 0x1F: /* RRA */ | ||
690 | RRA(A); break; | ||
691 | |||
692 | case 0x27: /* DAA */ | ||
693 | DAA; break; | ||
694 | case 0x2F: /* CPL */ | ||
695 | CPL(A); break; | ||
696 | |||
697 | case 0x18: /* JR */ | ||
698 | __JR: | ||
699 | JR; break; | ||
700 | case 0x20: /* JR NZ */ | ||
701 | if (!(F&FZ)) goto __JR; NOJR; break; | ||
702 | case 0x28: /* JR Z */ | ||
703 | if (F&FZ) goto __JR; NOJR; break; | ||
704 | case 0x30: /* JR NC */ | ||
705 | if (!(F&FC)) goto __JR; NOJR; break; | ||
706 | case 0x38: /* JR C */ | ||
707 | if (F&FC) goto __JR; NOJR; break; | ||
708 | |||
709 | case 0xC3: /* JP */ | ||
710 | __JP: | ||
711 | JP; break; | ||
712 | case 0xC2: /* JP NZ */ | ||
713 | if (!(F&FZ)) goto __JP; NOJP; break; | ||
714 | case 0xCA: /* JP Z */ | ||
715 | if (F&FZ) goto __JP; NOJP; break; | ||
716 | case 0xD2: /* JP NC */ | ||
717 | if (!(F&FC)) goto __JP; NOJP; break; | ||
718 | case 0xDA: /* JP C */ | ||
719 | if (F&FC) goto __JP; NOJP; break; | ||
720 | case 0xE9: /* JP HL */ | ||
721 | PC = HL; break; | ||
722 | |||
723 | case 0xC9: /* RET */ | ||
724 | __RET: | ||
725 | RET; break; | ||
726 | case 0xC0: /* RET NZ */ | ||
727 | if (!(F&FZ)) goto __RET; NORET; break; | ||
728 | case 0xC8: /* RET Z */ | ||
729 | if (F&FZ) goto __RET; NORET; break; | ||
730 | case 0xD0: /* RET NC */ | ||
731 | if (!(F&FC)) goto __RET; NORET; break; | ||
732 | case 0xD8: /* RET C */ | ||
733 | if (F&FC) goto __RET; NORET; break; | ||
734 | case 0xD9: /* RETI */ | ||
735 | IME = IMA = 1; goto __RET; | ||
736 | |||
737 | case 0xCD: /* CALL */ | ||
738 | __CALL: | ||
739 | CALL; break; | ||
740 | case 0xC4: /* CALL NZ */ | ||
741 | if (!(F&FZ)) goto __CALL; NOCALL; break; | ||
742 | case 0xCC: /* CALL Z */ | ||
743 | if (F&FZ) goto __CALL; NOCALL; break; | ||
744 | case 0xD4: /* CALL NC */ | ||
745 | if (!(F&FC)) goto __CALL; NOCALL; break; | ||
746 | case 0xDC: /* CALL C */ | ||
747 | if (F&FC) goto __CALL; NOCALL; break; | ||
748 | |||
749 | case 0xC7: /* RST 0 */ | ||
750 | b = 0x00; goto __RST; | ||
751 | case 0xCF: /* RST 8 */ | ||
752 | b = 0x08; goto __RST; | ||
753 | case 0xD7: /* RST 10 */ | ||
754 | b = 0x10; goto __RST; | ||
755 | case 0xDF: /* RST 18 */ | ||
756 | b = 0x18; goto __RST; | ||
757 | case 0xE7: /* RST 20 */ | ||
758 | b = 0x20; goto __RST; | ||
759 | case 0xEF: /* RST 28 */ | ||
760 | b = 0x28; goto __RST; | ||
761 | case 0xF7: /* RST 30 */ | ||
762 | b = 0x30; goto __RST; | ||
763 | case 0xFF: /* RST 38 */ | ||
764 | b = 0x38; | ||
765 | __RST: | ||
766 | RST(b); break; | ||
767 | |||
768 | case 0xC1: /* POP BC */ | ||
769 | POP(BC); break; | ||
770 | case 0xC5: /* PUSH BC */ | ||
771 | PUSH(BC); break; | ||
772 | case 0xD1: /* POP DE */ | ||
773 | POP(DE); break; | ||
774 | case 0xD5: /* PUSH DE */ | ||
775 | PUSH(DE); break; | ||
776 | case 0xE1: /* POP HL */ | ||
777 | POP(HL); break; | ||
778 | case 0xE5: /* PUSH HL */ | ||
779 | PUSH(HL); break; | ||
780 | case 0xF1: /* POP AF */ | ||
781 | POP(AF); break; | ||
782 | case 0xF5: /* PUSH AF */ | ||
783 | PUSH(AF); break; | ||
784 | |||
785 | case 0xE8: /* ADD SP,imm */ | ||
786 | b = FETCH; ADDSP(b); break; | ||
787 | |||
788 | case 0xF3: /* DI */ | ||
789 | DI; break; | ||
790 | case 0xFB: /* EI */ | ||
791 | EI; break; | ||
792 | |||
793 | case 0x37: /* SCF */ | ||
794 | SCF; break; | ||
795 | case 0x3F: /* CCF */ | ||
796 | CCF; break; | ||
797 | |||
798 | case 0x10: /* STOP */ | ||
799 | PC++; | ||
800 | if (R_KEY1 & 1) | ||
801 | { | ||
802 | cpu.speed = cpu.speed ^ 1; | ||
803 | R_KEY1 = (R_KEY1 & 0x7E) | (cpu.speed << 7); | ||
804 | break; | ||
805 | } | ||
806 | /* NOTE - we do not implement dmg STOP whatsoever */ | ||
807 | break; | ||
808 | |||
809 | case 0x76: /* HALT */ | ||
810 | cpu.halt = 1; | ||
811 | break; | ||
812 | |||
813 | case 0xCB: /* CB prefix */ | ||
814 | cbop = FETCH; | ||
815 | clen = cb_cycles_table[cbop]; | ||
816 | switch (cbop) | ||
817 | { | ||
818 | CB_REG_CASES(B, 0); | ||
819 | CB_REG_CASES(C, 1); | ||
820 | CB_REG_CASES(D, 2); | ||
821 | CB_REG_CASES(E, 3); | ||
822 | CB_REG_CASES(H, 4); | ||
823 | CB_REG_CASES(L, 5); | ||
824 | CB_REG_CASES(A, 7); | ||
825 | default: | ||
826 | b = readb(xHL); | ||
827 | switch(cbop) | ||
828 | { | ||
829 | CB_REG_CASES(b, 6); | ||
830 | } | ||
831 | if ((cbop & 0xC0) != 0x40) /* exclude BIT */ | ||
832 | writeb(xHL, b); | ||
833 | break; | ||
834 | } | ||
835 | break; | ||
836 | |||
837 | default: | ||
838 | die( | ||
839 | "invalid opcode 0x%02X at address 0x%04X, rombank = %d\n", | ||
840 | op, (PC-1) & 0xffff, mbc.rombank); | ||
841 | break; | ||
842 | } | ||
843 | |||
844 | clen <<= 1; | ||
845 | div_advance(clen); | ||
846 | timer_advance(clen); | ||
847 | clen >>= cpu.speed; | ||
848 | lcdc_advance(clen); | ||
849 | sound_advance(clen); | ||
850 | |||
851 | i -= clen; | ||
852 | if (i > 0) goto next; | ||
853 | return cycles-i; | ||
854 | } | ||
855 | |||
856 | #endif /* ASM_CPU_EMULATE */ | ||
857 | |||
858 | |||
859 | #ifndef ASM_CPU_STEP | ||
860 | |||
861 | int cpu_step(int max) | ||
862 | { | ||
863 | int cnt; | ||
864 | if ((cnt = cpu_idle(max))) return cnt; | ||
865 | return cpu_emulate(1); | ||
866 | } | ||
867 | |||
868 | #endif /* ASM_CPU_STEP */ | ||
869 | |||
870 | |||
871 | |||
872 | |||
873 | |||
874 | |||
875 | |||
876 | |||
877 | |||
878 | |||
879 | |||
880 | |||
diff --git a/apps/plugins/rockboy/cpu.h b/apps/plugins/rockboy/cpu.h new file mode 100644 index 0000000000..22d58b0db0 --- /dev/null +++ b/apps/plugins/rockboy/cpu.h | |||
@@ -0,0 +1,41 @@ | |||
1 | |||
2 | |||
3 | #ifndef __CPU_H__ | ||
4 | #define __CPU_H__ | ||
5 | |||
6 | |||
7 | |||
8 | #include "defs.h" | ||
9 | |||
10 | |||
11 | union reg | ||
12 | { | ||
13 | byte b[2][2]; | ||
14 | word w[2]; | ||
15 | un32 d; /* padding for alignment, carry */ | ||
16 | }; | ||
17 | |||
18 | struct cpu | ||
19 | { | ||
20 | union reg pc, sp, bc, de, hl, af; | ||
21 | int ime, ima; | ||
22 | int speed; | ||
23 | int halt; | ||
24 | int div, tim; | ||
25 | int lcdc; | ||
26 | int snd; | ||
27 | }; | ||
28 | |||
29 | extern struct cpu cpu; | ||
30 | |||
31 | |||
32 | void cpu_reset(void); | ||
33 | void div_advance(int cnt); | ||
34 | void timer_advance(int cnt); | ||
35 | void lcdc_advance(int cnt); | ||
36 | void sound_advance(int cnt); | ||
37 | void cpu_timers(int cnt); | ||
38 | int cpu_emulate(int cycles); | ||
39 | |||
40 | |||
41 | #endif | ||
diff --git a/apps/plugins/rockboy/cpucore.h b/apps/plugins/rockboy/cpucore.h new file mode 100644 index 0000000000..361c106dab --- /dev/null +++ b/apps/plugins/rockboy/cpucore.h | |||
@@ -0,0 +1,290 @@ | |||
1 | |||
2 | #include "defs.h" | ||
3 | |||
4 | |||
5 | static const byte cycles_table[256] = | ||
6 | { | ||
7 | 1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1, | ||
8 | 1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1, | ||
9 | 3, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1, | ||
10 | 3, 3, 2, 2, 1, 3, 3, 3, 3, 2, 2, 2, 1, 1, 2, 1, | ||
11 | |||
12 | 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, | ||
13 | 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, | ||
14 | 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, | ||
15 | 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, | ||
16 | |||
17 | 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, | ||
18 | 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, | ||
19 | 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, | ||
20 | 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, | ||
21 | |||
22 | 5, 3, 4, 4, 6, 4, 2, 4, 5, 4, 4, 1, 6, 6, 2, 4, | ||
23 | 5, 3, 4, 0, 6, 4, 2, 4, 5, 4, 4, 0, 6, 0, 2, 4, | ||
24 | 3, 3, 2, 0, 0, 4, 2, 4, 4, 1, 4, 0, 0, 0, 2, 4, | ||
25 | 3, 3, 2, 1, 0, 4, 2, 4, 3, 2, 4, 1, 0, 0, 2, 4, | ||
26 | }; | ||
27 | |||
28 | static const byte cb_cycles_table[256] = | ||
29 | { | ||
30 | 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, | ||
31 | 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, | ||
32 | 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, | ||
33 | 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, | ||
34 | |||
35 | 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, | ||
36 | 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, | ||
37 | 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, | ||
38 | 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, | ||
39 | |||
40 | 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, | ||
41 | 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, | ||
42 | 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, | ||
43 | 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, | ||
44 | |||
45 | 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, | ||
46 | 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, | ||
47 | 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, | ||
48 | 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2, | ||
49 | }; | ||
50 | |||
51 | |||
52 | |||
53 | static const byte zflag_table[256] = | ||
54 | { | ||
55 | FZ, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
56 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
57 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
58 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
59 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
60 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
61 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
62 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
63 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
64 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
65 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
66 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
67 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
68 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
69 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
70 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
71 | }; | ||
72 | |||
73 | static const byte incflag_table[256] = | ||
74 | { | ||
75 | FZ|FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
76 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
77 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
78 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
79 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
80 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
81 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
82 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
83 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
84 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
85 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
86 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
87 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
88 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
89 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
90 | FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
91 | }; | ||
92 | |||
93 | static const byte decflag_table[256] = | ||
94 | { | ||
95 | FZ|FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
96 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
97 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
98 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
99 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
100 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
101 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
102 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
103 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
104 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
105 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
106 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
107 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
108 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
109 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH, | ||
110 | FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH | ||
111 | }; | ||
112 | |||
113 | static const byte swap_table[256] = | ||
114 | { | ||
115 | 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, | ||
116 | 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1, | ||
117 | 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2, | ||
118 | 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3, | ||
119 | 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4, | ||
120 | 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, | ||
121 | 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, | ||
122 | 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, | ||
123 | 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, | ||
124 | 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, | ||
125 | 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA, | ||
126 | 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB, | ||
127 | 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, | ||
128 | 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, | ||
129 | 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, | ||
130 | 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF, | ||
131 | }; | ||
132 | |||
133 | static const byte daa_table[4096] = | ||
134 | { | ||
135 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
136 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
137 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
138 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
139 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
140 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
141 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
142 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
143 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
144 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
145 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
146 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
147 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
148 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
149 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
150 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
151 | |||
152 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
153 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
154 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
155 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
156 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
157 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
158 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
159 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
160 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
161 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
162 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
163 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
164 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
165 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
166 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
167 | 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
168 | |||
169 | 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
170 | 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
171 | 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
172 | 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
173 | 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
174 | 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
175 | 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
176 | 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
177 | 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
178 | 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, | ||
179 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
180 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
181 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
182 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
183 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
184 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
185 | |||
186 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
187 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
188 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
189 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
190 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
191 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
192 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
193 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
194 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
195 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
196 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
197 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
198 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
199 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
200 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
201 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
202 | |||
203 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
204 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
205 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
206 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
207 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
208 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
209 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
210 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
211 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
212 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
213 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
214 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
215 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
216 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
217 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
218 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
219 | |||
220 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
221 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
222 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
223 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
224 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
225 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
226 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
227 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
228 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
229 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
230 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
231 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
232 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
233 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
234 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
235 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, | ||
236 | |||
237 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
238 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
239 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
240 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
241 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
242 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
243 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
244 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
245 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
246 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
247 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
248 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
249 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
250 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
251 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
252 | 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, | ||
253 | |||
254 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
255 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
256 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
257 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
258 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
259 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
260 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
261 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
262 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
263 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
264 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
265 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
266 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
267 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
268 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
269 | 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, | ||
270 | }; | ||
271 | |||
272 | static const byte daa_carry_table[64] = | ||
273 | { | ||
274 | 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, | ||
275 | 00, 00, 00, 00, 00, 00, 00, 00, FC, FC, 00, 00, 00, 00, 00, 00, | ||
276 | FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, | ||
277 | FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, 00, FC, | ||
278 | }; | ||
279 | |||
280 | |||
281 | |||
282 | |||
283 | |||
284 | |||
285 | |||
286 | |||
287 | |||
288 | |||
289 | |||
290 | |||
diff --git a/apps/plugins/rockboy/cpuregs.h b/apps/plugins/rockboy/cpuregs.h new file mode 100644 index 0000000000..0d09908cc3 --- /dev/null +++ b/apps/plugins/rockboy/cpuregs.h | |||
@@ -0,0 +1,56 @@ | |||
1 | |||
2 | |||
3 | #ifndef __CPUREGS_H__ | ||
4 | |||
5 | #define __CPUREGS_H__ | ||
6 | |||
7 | |||
8 | |||
9 | #include "defs.h" | ||
10 | #include "cpu.h" | ||
11 | |||
12 | #define LB(r) ((r).b[LO][LO]) | ||
13 | #define HB(r) ((r).b[LO][HI]) | ||
14 | #define W(r) ((r).w[LO]) | ||
15 | #define DW(r) ((r).d) | ||
16 | |||
17 | #define A HB(cpu.af) | ||
18 | #define F LB(cpu.af) | ||
19 | #define B HB(cpu.bc) | ||
20 | #define C LB(cpu.bc) | ||
21 | #define D HB(cpu.de) | ||
22 | #define E LB(cpu.de) | ||
23 | #define H HB(cpu.hl) | ||
24 | #define L LB(cpu.hl) | ||
25 | |||
26 | #define AF W(cpu.af) | ||
27 | #define BC W(cpu.bc) | ||
28 | #define DE W(cpu.de) | ||
29 | #define HL W(cpu.hl) | ||
30 | |||
31 | #define PC W(cpu.pc) | ||
32 | #define SP W(cpu.sp) | ||
33 | |||
34 | #define xAF DW(cpu.af) | ||
35 | #define xBC DW(cpu.bc) | ||
36 | #define xDE DW(cpu.de) | ||
37 | #define xHL DW(cpu.hl) | ||
38 | |||
39 | #define xPC DW(cpu.pc) | ||
40 | #define xSP DW(cpu.sp) | ||
41 | |||
42 | #define IMA cpu.ima | ||
43 | #define IME cpu.ime | ||
44 | #define IF R_IF | ||
45 | #define IE R_IE | ||
46 | |||
47 | #define FZ 0x80 | ||
48 | #define FN 0x40 | ||
49 | #define FH 0x20 | ||
50 | #define FC 0x10 | ||
51 | #define FL 0x0F /* low unused portion of flags */ | ||
52 | |||
53 | |||
54 | #endif /* __CPUREGS_H__ */ | ||
55 | |||
56 | |||
diff --git a/apps/plugins/rockboy/debug.c b/apps/plugins/rockboy/debug.c new file mode 100644 index 0000000000..d0e106ba94 --- /dev/null +++ b/apps/plugins/rockboy/debug.c | |||
@@ -0,0 +1,699 @@ | |||
1 | |||
2 | |||
3 | #include <stdio.h> | ||
4 | |||
5 | #include "rockmacros.h" | ||
6 | #include "defs.h" | ||
7 | #include "cpu.h" | ||
8 | #include "mem.h" | ||
9 | #include "fastmem.h" | ||
10 | #include "regs.h" | ||
11 | #include "rc.h" | ||
12 | |||
13 | #include "cpuregs.h" | ||
14 | |||
15 | |||
16 | static char *mnemonic_table[256] = | ||
17 | { | ||
18 | "NOP", | ||
19 | "LD BC,%w", | ||
20 | "LD (BC),A", | ||
21 | "INC BC", | ||
22 | "INC B", | ||
23 | "DEC B", | ||
24 | "LD B,%b", | ||
25 | "RLCA", | ||
26 | "LD (%w),SP", | ||
27 | "ADD HL,BC", | ||
28 | "LD A,(BC)", | ||
29 | "DEC BC", | ||
30 | "INC C", | ||
31 | "DEC C", | ||
32 | "LD C,%b", | ||
33 | "RRCA", | ||
34 | "STOP", | ||
35 | "LD DE,%w", | ||
36 | "LD (DE),A", | ||
37 | "INC DE", | ||
38 | "INC D", | ||
39 | "DEC D", | ||
40 | "LD D,%b", | ||
41 | "RLA", | ||
42 | "JR %o", | ||
43 | "ADD HL,DE", | ||
44 | "LD A,(DE)", | ||
45 | "DEC DE", | ||
46 | "INC E", | ||
47 | "DEC E", | ||
48 | "LD E,%b", | ||
49 | "RRA", | ||
50 | "JR NZ,%o", | ||
51 | "LD HL,%w", | ||
52 | "LD (HLI),A", | ||
53 | "INC HL", | ||
54 | "INC H", | ||
55 | "DEC H", | ||
56 | "LD H,%b", | ||
57 | "DAA", | ||
58 | "JR Z,%o", | ||
59 | "ADD HL,HL", | ||
60 | "LD A,(HLI)", | ||
61 | "DEC HL", | ||
62 | "INC L", | ||
63 | "DEC L", | ||
64 | "LD L,%b", | ||
65 | "CPL", | ||
66 | "JR NC,%o", | ||
67 | "LD SP,%w", | ||
68 | "LD (HLD),A", | ||
69 | "INC SP", | ||
70 | "INC (HL)", | ||
71 | "DEC (HL)", | ||
72 | "LD (HL),%b", | ||
73 | "SCF", | ||
74 | "JR C,%o", | ||
75 | "ADD HL,SP", | ||
76 | "LD A,(HLD)", | ||
77 | "DEC SP", | ||
78 | "INC A", | ||
79 | "DEC A", | ||
80 | "LD A,%b", | ||
81 | "CCF", | ||
82 | "LD B,B", | ||
83 | "LD B,C", | ||
84 | "LD B,D", | ||
85 | "LD B,E", | ||
86 | "LD B,H", | ||
87 | "LD B,L", | ||
88 | "LD B,(HL)", | ||
89 | "LD B,A", | ||
90 | "LD C,B", | ||
91 | "LD C,C", | ||
92 | "LD C,D", | ||
93 | "LD C,E", | ||
94 | "LD C,H", | ||
95 | "LD C,L", | ||
96 | "LD C,(HL)", | ||
97 | "LD C,A", | ||
98 | "LD D,B", | ||
99 | "LD D,C", | ||
100 | "LD D,D", | ||
101 | "LD D,E", | ||
102 | "LD D,H", | ||
103 | "LD D,L", | ||
104 | "LD D,(HL)", | ||
105 | "LD D,A", | ||
106 | "LD E,B", | ||
107 | "LD E,C", | ||
108 | "LD E,D", | ||
109 | "LD E,E", | ||
110 | "LD E,H", | ||
111 | "LD E,L", | ||
112 | "LD E,(HL)", | ||
113 | "LD E,A", | ||
114 | "LD H,B", | ||
115 | "LD H,C", | ||
116 | "LD H,D", | ||
117 | "LD H,E", | ||
118 | "LD H,H", | ||
119 | "LD H,L", | ||
120 | "LD H,(HL)", | ||
121 | "LD H,A", | ||
122 | "LD L,B", | ||
123 | "LD L,C", | ||
124 | "LD L,D", | ||
125 | "LD L,E", | ||
126 | "LD L,H", | ||
127 | "LD L,L", | ||
128 | "LD L,(HL)", | ||
129 | "LD L,A", | ||
130 | "LD (HL),B", | ||
131 | "LD (HL),C", | ||
132 | "LD (HL),D", | ||
133 | "LD (HL),E", | ||
134 | "LD (HL),H", | ||
135 | "LD (HL),L", | ||
136 | "HALT", | ||
137 | "LD (HL),A", | ||
138 | "LD A,B", | ||
139 | "LD A,C", | ||
140 | "LD A,D", | ||
141 | "LD A,E", | ||
142 | "LD A,H", | ||
143 | "LD A,L", | ||
144 | "LD A,(HL)", | ||
145 | "LD A,A", | ||
146 | "ADD A,B", | ||
147 | "ADD A,C", | ||
148 | "ADD A,D", | ||
149 | "ADD A,E", | ||
150 | "ADD A,H", | ||
151 | "ADD A,L", | ||
152 | "ADD A,(HL)", | ||
153 | "ADD A,A", | ||
154 | "ADC A,B", | ||
155 | "ADC A,C", | ||
156 | "ADC A,D", | ||
157 | "ADC A,E", | ||
158 | "ADC A,H", | ||
159 | "ADC A,L", | ||
160 | "ADC A,(HL)", | ||
161 | "ADC A", | ||
162 | "SUB B", | ||
163 | "SUB C", | ||
164 | "SUB D", | ||
165 | "SUB E", | ||
166 | "SUB H", | ||
167 | "SUB L", | ||
168 | "SUB (HL)", | ||
169 | "SUB A", | ||
170 | "SBC A,B", | ||
171 | "SBC A,C", | ||
172 | "SBC A,D", | ||
173 | "SBC A,E", | ||
174 | "SBC A,H", | ||
175 | "SBC A,L", | ||
176 | "SBC A,(HL)", | ||
177 | "SBC A,A", | ||
178 | "AND B", | ||
179 | "AND C", | ||
180 | "AND D", | ||
181 | "AND E", | ||
182 | "AND H", | ||
183 | "AND L", | ||
184 | "AND (HL)", | ||
185 | "AND A", | ||
186 | "XOR B", | ||
187 | "XOR C", | ||
188 | "XOR D", | ||
189 | "XOR E", | ||
190 | "XOR H", | ||
191 | "XOR L", | ||
192 | "XOR (HL)", | ||
193 | "XOR A", | ||
194 | "OR B", | ||
195 | "OR C", | ||
196 | "OR D", | ||
197 | "OR E", | ||
198 | "OR H", | ||
199 | "OR L", | ||
200 | "OR (HL)", | ||
201 | "OR A", | ||
202 | "CP B", | ||
203 | "CP C", | ||
204 | "CP D", | ||
205 | "CP E", | ||
206 | "CP H", | ||
207 | "CP L", | ||
208 | "CP (HL)", | ||
209 | "CP A", | ||
210 | "RET NZ", | ||
211 | "POP BC", | ||
212 | "JP NZ,%w", | ||
213 | "JP %w", | ||
214 | "CALL NZ,%w", | ||
215 | "PUSH BC", | ||
216 | "ADD A,%b", | ||
217 | "RST 0h", | ||
218 | "RET Z", | ||
219 | "RET", | ||
220 | "JP Z,%w", | ||
221 | NULL, | ||
222 | "CALL Z,%w", | ||
223 | "CALL %w", | ||
224 | "ADC A,%b", | ||
225 | "RST 8h", | ||
226 | "RET NC", | ||
227 | "POP DE", | ||
228 | "JP NC,%w", | ||
229 | NULL, | ||
230 | "CALL NC,%w", | ||
231 | "PUSH DE", | ||
232 | "SUB %b", | ||
233 | "RST 10h", | ||
234 | "RET C", | ||
235 | "RETI", | ||
236 | "JP C,%w", | ||
237 | NULL, | ||
238 | "CALL C,%w", | ||
239 | NULL, | ||
240 | "SBC A,%b", | ||
241 | "RST 18h", | ||
242 | "LD (FF00+%b),A", | ||
243 | "POP HL", | ||
244 | "LD (FF00+C),A", | ||
245 | NULL, | ||
246 | NULL, | ||
247 | "PUSH HL", | ||
248 | "AND %b", | ||
249 | "RST 20h", | ||
250 | "ADD SP,%o", | ||
251 | "JP HL", | ||
252 | "LD (%w),A", | ||
253 | NULL, | ||
254 | NULL, | ||
255 | NULL, | ||
256 | "XOR %b", | ||
257 | "RST 28h", | ||
258 | "LD A,(FF00+%b)", | ||
259 | "POP AF", | ||
260 | "LD A,(FF00+C)", | ||
261 | "DI", | ||
262 | NULL, | ||
263 | "PUSH AF", | ||
264 | "OR %b", | ||
265 | "RST 30h", | ||
266 | "LD HL,SP%o", | ||
267 | "LD SP,HL", | ||
268 | "LD A,(%w)", | ||
269 | "EI", | ||
270 | NULL, | ||
271 | NULL, | ||
272 | "CP %b", | ||
273 | "RST 38h" | ||
274 | }; | ||
275 | |||
276 | static char *cb_mnemonic_table[256] = | ||
277 | { | ||
278 | "RLC B", | ||
279 | "RLC C", | ||
280 | "RLC D", | ||
281 | "RLC E", | ||
282 | "RLC H", | ||
283 | "RLC L", | ||
284 | "RLC (HL)", | ||
285 | "RLC A", | ||
286 | "RRC B", | ||
287 | "RRC C", | ||
288 | "RRC D", | ||
289 | "RRC E", | ||
290 | "RRC H", | ||
291 | "RRC L", | ||
292 | "RRC (HL)", | ||
293 | "RRC A", | ||
294 | "RL B", | ||
295 | "RL C", | ||
296 | "RL D", | ||
297 | "RL E", | ||
298 | "RL H", | ||
299 | "RL L", | ||
300 | "RL (HL)", | ||
301 | "RL A", | ||
302 | "RR B", | ||
303 | "RR C", | ||
304 | "RR D", | ||
305 | "RR E", | ||
306 | "RR H", | ||
307 | "RR L", | ||
308 | "RR (HL)", | ||
309 | "RR A", | ||
310 | "SLA B", | ||
311 | "SLA C", | ||
312 | "SLA D", | ||
313 | "SLA E", | ||
314 | "SLA H", | ||
315 | "SLA L", | ||
316 | "SLA (HL)", | ||
317 | "SLA A", | ||
318 | "SRA B", | ||
319 | "SRA C", | ||
320 | "SRA D", | ||
321 | "SRA E", | ||
322 | "SRA H", | ||
323 | "SRA L", | ||
324 | "SRA (HL)", | ||
325 | "SRA A", | ||
326 | "SWAP B", | ||
327 | "SWAP C", | ||
328 | "SWAP D", | ||
329 | "SWAP E", | ||
330 | "SWAP H", | ||
331 | "SWAP L", | ||
332 | "SWAP (HL)", | ||
333 | "SWAP A", | ||
334 | "SRL B", | ||
335 | "SRL C", | ||
336 | "SRL D", | ||
337 | "SRL E", | ||
338 | "SRL H", | ||
339 | "SRL L", | ||
340 | "SRL (HL)", | ||
341 | "SRL A", | ||
342 | "BIT 0,B", | ||
343 | "BIT 0,C", | ||
344 | "BIT 0,D", | ||
345 | "BIT 0,E", | ||
346 | "BIT 0,H", | ||
347 | "BIT 0,L", | ||
348 | "BIT 0,(HL)", | ||
349 | "BIT 0,A", | ||
350 | "BIT 1,B", | ||
351 | "BIT 1,C", | ||
352 | "BIT 1,D", | ||
353 | "BIT 1,E", | ||
354 | "BIT 1,H", | ||
355 | "BIT 1,L", | ||
356 | "BIT 1,(HL)", | ||
357 | "BIT 1,A", | ||
358 | "BIT 2,B", | ||
359 | "BIT 2,C", | ||
360 | "BIT 2,D", | ||
361 | "BIT 2,E", | ||
362 | "BIT 2,H", | ||
363 | "BIT 2,L", | ||
364 | "BIT 2,(HL)", | ||
365 | "BIT 2,A", | ||
366 | "BIT 3,B", | ||
367 | "BIT 3,C", | ||
368 | "BIT 3,D", | ||
369 | "BIT 3,E", | ||
370 | "BIT 3,H", | ||
371 | "BIT 3,L", | ||
372 | "BIT 3,(HL)", | ||
373 | "BIT 3,A", | ||
374 | "BIT 4,B", | ||
375 | "BIT 4,C", | ||
376 | "BIT 4,D", | ||
377 | "BIT 4,E", | ||
378 | "BIT 4,H", | ||
379 | "BIT 4,L", | ||
380 | "BIT 4,(HL)", | ||
381 | "BIT 4,A", | ||
382 | "BIT 5,B", | ||
383 | "BIT 5,C", | ||
384 | "BIT 5,D", | ||
385 | "BIT 5,E", | ||
386 | "BIT 5,H", | ||
387 | "BIT 5,L", | ||
388 | "BIT 5,(HL)", | ||
389 | "BIT 5,A", | ||
390 | "BIT 6,B", | ||
391 | "BIT 6,C", | ||
392 | "BIT 6,D", | ||
393 | "BIT 6,E", | ||
394 | "BIT 6,H", | ||
395 | "BIT 6,L", | ||
396 | "BIT 6,(HL)", | ||
397 | "BIT 6,A", | ||
398 | "BIT 7,B", | ||
399 | "BIT 7,C", | ||
400 | "BIT 7,D", | ||
401 | "BIT 7,E", | ||
402 | "BIT 7,H", | ||
403 | "BIT 7,L", | ||
404 | "BIT 7,(HL)", | ||
405 | "BIT 7,A", | ||
406 | "RES 0,B", | ||
407 | "RES 0,C", | ||
408 | "RES 0,D", | ||
409 | "RES 0,E", | ||
410 | "RES 0,H", | ||
411 | "RES 0,L", | ||
412 | "RES 0,(HL)", | ||
413 | "RES 0,A", | ||
414 | "RES 1,B", | ||
415 | "RES 1,C", | ||
416 | "RES 1,D", | ||
417 | "RES 1,E", | ||
418 | "RES 1,H", | ||
419 | "RES 1,L", | ||
420 | "RES 1,(HL)", | ||
421 | "RES 1,A", | ||
422 | "RES 2,B", | ||
423 | "RES 2,C", | ||
424 | "RES 2,D", | ||
425 | "RES 2,E", | ||
426 | "RES 2,H", | ||
427 | "RES 2,L", | ||
428 | "RES 2,(HL)", | ||
429 | "RES 2,A", | ||
430 | "RES 3,B", | ||
431 | "RES 3,C", | ||
432 | "RES 3,D", | ||
433 | "RES 3,E", | ||
434 | "RES 3,H", | ||
435 | "RES 3,L", | ||
436 | "RES 3,(HL)", | ||
437 | "RES 3,A", | ||
438 | "RES 4,B", | ||
439 | "RES 4,C", | ||
440 | "RES 4,D", | ||
441 | "RES 4,E", | ||
442 | "RES 4,H", | ||
443 | "RES 4,L", | ||
444 | "RES 4,(HL)", | ||
445 | "RES 4,A", | ||
446 | "RES 5,B", | ||
447 | "RES 5,C", | ||
448 | "RES 5,D", | ||
449 | "RES 5,E", | ||
450 | "RES 5,H", | ||
451 | "RES 5,L", | ||
452 | "RES 5,(HL)", | ||
453 | "RES 5,A", | ||
454 | "RES 6,B", | ||
455 | "RES 6,C", | ||
456 | "RES 6,D", | ||
457 | "RES 6,E", | ||
458 | "RES 6,H", | ||
459 | "RES 6,L", | ||
460 | "RES 6,(HL)", | ||
461 | "RES 6,A", | ||
462 | "RES 7,B", | ||
463 | "RES 7,C", | ||
464 | "RES 7,D", | ||
465 | "RES 7,E", | ||
466 | "RES 7,H", | ||
467 | "RES 7,L", | ||
468 | "RES 7,(HL)", | ||
469 | "RES 7,A", | ||
470 | "SET 0,B", | ||
471 | "SET 0,C", | ||
472 | "SET 0,D", | ||
473 | "SET 0,E", | ||
474 | "SET 0,H", | ||
475 | "SET 0,L", | ||
476 | "SET 0,(HL)", | ||
477 | "SET 0,A", | ||
478 | "SET 1,B", | ||
479 | "SET 1,C", | ||
480 | "SET 1,D", | ||
481 | "SET 1,E", | ||
482 | "SET 1,H", | ||
483 | "SET 1,L", | ||
484 | "SET 1,(HL)", | ||
485 | "SET 1,A", | ||
486 | "SET 2,B", | ||
487 | "SET 2,C", | ||
488 | "SET 2,D", | ||
489 | "SET 2,E", | ||
490 | "SET 2,H", | ||
491 | "SET 2,L", | ||
492 | "SET 2,(HL)", | ||
493 | "SET 2,A", | ||
494 | "SET 3,B", | ||
495 | "SET 3,C", | ||
496 | "SET 3,D", | ||
497 | "SET 3,E", | ||
498 | "SET 3,H", | ||
499 | "SET 3,L", | ||
500 | "SET 3,(HL)", | ||
501 | "SET 3,A", | ||
502 | "SET 4,B", | ||
503 | "SET 4,C", | ||
504 | "SET 4,D", | ||
505 | "SET 4,E", | ||
506 | "SET 4,H", | ||
507 | "SET 4,L", | ||
508 | "SET 4,(HL)", | ||
509 | "SET 4,A", | ||
510 | "SET 5,B", | ||
511 | "SET 5,C", | ||
512 | "SET 5,D", | ||
513 | "SET 5,E", | ||
514 | "SET 5,H", | ||
515 | "SET 5,L", | ||
516 | "SET 5,(HL)", | ||
517 | "SET 5,A", | ||
518 | "SET 6,B", | ||
519 | "SET 6,C", | ||
520 | "SET 6,D", | ||
521 | "SET 6,E", | ||
522 | "SET 6,H", | ||
523 | "SET 6,L", | ||
524 | "SET 6,(HL)", | ||
525 | "SET 6,A", | ||
526 | "SET 7,B", | ||
527 | "SET 7,C", | ||
528 | "SET 7,D", | ||
529 | "SET 7,E", | ||
530 | "SET 7,H", | ||
531 | "SET 7,L", | ||
532 | "SET 7,(HL)", | ||
533 | "SET 7,A" | ||
534 | }; | ||
535 | |||
536 | static byte operand_count[256] = | ||
537 | { | ||
538 | 1, 3, 1, 1, 1, 1, 2, 1, 3, 1, 1, 1, 1, 1, 2, 1, | ||
539 | 1, 3, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1, | ||
540 | 2, 3, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1, | ||
541 | 2, 3, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1, | ||
542 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
543 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
544 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
545 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
546 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
547 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
548 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
549 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
550 | 1, 1, 3, 3, 3, 1, 2, 1, 1, 1, 3, 2, 3, 3, 2, 1, | ||
551 | 1, 1, 3, 1, 3, 1, 2, 1, 1, 1, 3, 1, 3, 1, 2, 1, | ||
552 | 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 1, 1, 2, 1, | ||
553 | 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 1, 1, 2, 1 | ||
554 | }; | ||
555 | |||
556 | |||
557 | /* replace with a real interactive debugger eventually... */ | ||
558 | |||
559 | int debug_trace = 0; | ||
560 | |||
561 | rcvar_t debug_exports[] = | ||
562 | { | ||
563 | RCV_BOOL("trace", &debug_trace), | ||
564 | RCV_END | ||
565 | }; | ||
566 | |||
567 | void debug_disassemble(addr a, int c) | ||
568 | { | ||
569 | static int i, j, k; | ||
570 | static byte code; | ||
571 | static byte ops[3]; | ||
572 | static int opaddr; | ||
573 | static char mnemonic[256]; | ||
574 | static char *pattern; | ||
575 | char meow[500],buf[300]; | ||
576 | // int fd; | ||
577 | if(!debug_trace) return; | ||
578 | // fd=open("/rockboy.trace",O_WRONLY|O_APPEND); | ||
579 | // if(fd<0) | ||
580 | // return; | ||
581 | |||
582 | while (c > 0) | ||
583 | { | ||
584 | k = 0; | ||
585 | opaddr = a; | ||
586 | code = ops[k++] = readb(a); a++; | ||
587 | if (code != 0xCB) | ||
588 | { | ||
589 | pattern = mnemonic_table[code]; | ||
590 | if (!pattern) | ||
591 | pattern = "***INVALID***"; | ||
592 | } | ||
593 | else | ||
594 | { | ||
595 | code = ops[k++] = readb(a); a++; | ||
596 | pattern = cb_mnemonic_table[code]; | ||
597 | } | ||
598 | i = j = 0; | ||
599 | while (pattern[i]) | ||
600 | { | ||
601 | if (pattern[i] == '%') | ||
602 | { | ||
603 | switch (pattern[++i]) | ||
604 | { | ||
605 | case 'B': | ||
606 | case 'b': | ||
607 | ops[k] = readb(a); a++; | ||
608 | j += snprintf(mnemonic + j,255-j, | ||
609 | "%02Xh", ops[k++]); | ||
610 | break; | ||
611 | case 'W': | ||
612 | case 'w': | ||
613 | ops[k] = readb(a); a++; | ||
614 | ops[k+1] = readb(a); a++; | ||
615 | j += snprintf(mnemonic + j, 255-j,"%04Xh", | ||
616 | ((ops[k+1] << 8) | ops[k])); | ||
617 | k += 2; | ||
618 | break; | ||
619 | case 'O': | ||
620 | case 'o': | ||
621 | ops[k] = readb(a); a++; | ||
622 | j += snprintf(mnemonic + j, 255-j,"%+d", | ||
623 | (n8)(ops[k++])); | ||
624 | break; | ||
625 | } | ||
626 | i++; | ||
627 | } | ||
628 | else | ||
629 | { | ||
630 | mnemonic[j++] = pattern[i++]; | ||
631 | } | ||
632 | } | ||
633 | mnemonic[j] = 0; | ||
634 | snprintf(buf,299,"%04X ", opaddr); | ||
635 | strcpy(meow,buf); | ||
636 | switch (operand_count[ops[0]]) { | ||
637 | case 1: | ||
638 | snprintf(buf,299,"%02X ", ops[0]); | ||
639 | strcat(meow,buf); | ||
640 | break; | ||
641 | case 2: | ||
642 | snprintf(buf,299,"%02X %02X ", ops[0], ops[1]); | ||
643 | strcat(meow,buf); | ||
644 | break; | ||
645 | case 3: | ||
646 | snprintf(buf,299,"%02X %02X %02X ", ops[0], ops[1], ops[2]); | ||
647 | strcat(meow,buf); | ||
648 | break; | ||
649 | } | ||
650 | snprintf(buf,"%-16.16s", mnemonic); | ||
651 | strcat(meow,buf); | ||
652 | rb->lcd_putsxy(0,0,meow); | ||
653 | rb->lcd_update(); | ||
654 | /* fprintf(fd, | ||
655 | " SP=%04X.%04X BC=%04X.%02X.%02X DE=%04X.%02X " | ||
656 | "HL=%04X.%02X A=%02X F=%02X %c%c%c%c%c", | ||
657 | SP, readw(SP), | ||
658 | BC, readb(BC), readb(0xFF00 | C), | ||
659 | DE, readb(DE), | ||
660 | HL, readb(HL), A, | ||
661 | F, (IME ? 'I' : '-'), | ||
662 | ((F & 0x80) ? 'Z' : '-'), | ||
663 | ((F & 0x40) ? 'N' : '-'), | ||
664 | ((F & 0x20) ? 'H' : '-'), | ||
665 | ((F & 0x10) ? 'C' : '-') | ||
666 | ); | ||
667 | fprintf(fd, | ||
668 | " IE=%02X IF=%02X LCDC=%02X STAT=%02X LY=%02X LYC=%02X", | ||
669 | R_IE, R_IF, R_LCDC, R_STAT, R_LY, R_LYC | ||
670 | );*/ | ||
671 | c--; | ||
672 | } | ||
673 | } | ||
674 | |||
675 | |||
676 | |||
677 | |||
678 | |||
679 | |||
680 | |||
681 | |||
682 | |||
683 | |||
684 | |||
685 | |||
686 | |||
687 | |||
688 | |||
689 | |||
690 | |||
691 | |||
692 | |||
693 | |||
694 | |||
695 | |||
696 | |||
697 | |||
698 | |||
699 | |||
diff --git a/apps/plugins/rockboy/defs.h b/apps/plugins/rockboy/defs.h new file mode 100644 index 0000000000..4c520ef698 --- /dev/null +++ b/apps/plugins/rockboy/defs.h | |||
@@ -0,0 +1,36 @@ | |||
1 | |||
2 | |||
3 | |||
4 | #ifndef __DEFS_H__ | ||
5 | #define __DEFS_H__ | ||
6 | |||
7 | #include "rockmacros.h" | ||
8 | |||
9 | #ifdef LITTLE_ENDIAN | ||
10 | #define LO 0 | ||
11 | #define HI 1 | ||
12 | #else | ||
13 | #define LO 1 | ||
14 | #define HI 0 | ||
15 | #endif | ||
16 | |||
17 | |||
18 | typedef unsigned char byte; | ||
19 | |||
20 | typedef unsigned char un8; | ||
21 | typedef unsigned short un16; | ||
22 | typedef unsigned int un32; | ||
23 | |||
24 | typedef signed char n8; | ||
25 | typedef signed short n16; | ||
26 | typedef signed int n32; | ||
27 | |||
28 | typedef un16 word; | ||
29 | typedef word addr; | ||
30 | |||
31 | |||
32 | |||
33 | |||
34 | |||
35 | #endif | ||
36 | |||
diff --git a/apps/plugins/rockboy/emu.c b/apps/plugins/rockboy/emu.c new file mode 100644 index 0000000000..b6f2de779a --- /dev/null +++ b/apps/plugins/rockboy/emu.c | |||
@@ -0,0 +1,117 @@ | |||
1 | |||
2 | |||
3 | |||
4 | #include "rockmacros.h" | ||
5 | #include "defs.h" | ||
6 | #include "regs.h" | ||
7 | #include "hw.h" | ||
8 | #include "cpu.h" | ||
9 | #include "mem.h" | ||
10 | #include "lcd.h" | ||
11 | #include "rc.h" | ||
12 | #include "sound.h" | ||
13 | #include "rtc.h" | ||
14 | |||
15 | static int framelen = 16743; | ||
16 | static int framecount; | ||
17 | |||
18 | rcvar_t emu_exports[] = | ||
19 | { | ||
20 | RCV_INT("framelen", &framelen), | ||
21 | RCV_INT("framecount", &framecount), | ||
22 | RCV_END | ||
23 | }; | ||
24 | |||
25 | |||
26 | |||
27 | |||
28 | |||
29 | |||
30 | |||
31 | void emu_init(void) | ||
32 | { | ||
33 | |||
34 | } | ||
35 | |||
36 | |||
37 | /* | ||
38 | * emu_reset is called to initialize the state of the emulated | ||
39 | * system. It should set cpu registers, hardware registers, etc. to | ||
40 | * their appropriate values at powerup time. | ||
41 | */ | ||
42 | |||
43 | void emu_reset(void) | ||
44 | { | ||
45 | hw_reset(); | ||
46 | lcd_reset(); | ||
47 | cpu_reset(); | ||
48 | mbc_reset(); | ||
49 | sound_reset(); | ||
50 | } | ||
51 | |||
52 | |||
53 | |||
54 | |||
55 | |||
56 | void emu_step(void) | ||
57 | { | ||
58 | cpu_emulate(cpu.lcdc); | ||
59 | } | ||
60 | |||
61 | |||
62 | |||
63 | /* This mess needs to be moved to another module; it's just here to | ||
64 | * make things work in the mean time. */ | ||
65 | |||
66 | void emu_run(void) | ||
67 | { | ||
68 | void *timer = sys_timer(); | ||
69 | char meow[500]; | ||
70 | int delay; | ||
71 | int framecount=0; | ||
72 | |||
73 | vid_begin(); | ||
74 | lcd_begin(); | ||
75 | while(shut==0) | ||
76 | { | ||
77 | cpu_emulate(2280); | ||
78 | while (R_LY > 0 && R_LY < 144) | ||
79 | emu_step(); | ||
80 | |||
81 | vid_end(); | ||
82 | rtc_tick(); | ||
83 | sound_mix(); | ||
84 | if (!pcm_submit()) | ||
85 | { | ||
86 | delay = framelen - sys_elapsed(timer); | ||
87 | sys_sleep(delay); | ||
88 | sys_elapsed(timer); | ||
89 | } | ||
90 | doevents(); | ||
91 | vid_begin(); | ||
92 | // if (framecount) { if (!--framecount) die("finished\n"); } | ||
93 | |||
94 | if (!(R_LCDC & 0x80)) | ||
95 | cpu_emulate(32832); | ||
96 | |||
97 | while (R_LY > 0) /* wait for next frame */ | ||
98 | emu_step(); | ||
99 | framecount++; | ||
100 | snprintf(meow,499,"%d",framecount); | ||
101 | rb->lcd_putsxy(0,0,meow); | ||
102 | rb->lcd_update_rect(0,0,LCD_WIDTH,8); | ||
103 | rb->yield(); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | |||
108 | |||
109 | |||
110 | |||
111 | |||
112 | |||
113 | |||
114 | |||
115 | |||
116 | |||
117 | |||
diff --git a/apps/plugins/rockboy/emu.h b/apps/plugins/rockboy/emu.h new file mode 100644 index 0000000000..979b33cc54 --- /dev/null +++ b/apps/plugins/rockboy/emu.h | |||
@@ -0,0 +1,2 @@ | |||
1 | void emu_reset(void); | ||
2 | void emu_run(void); | ||
diff --git a/apps/plugins/rockboy/events.c b/apps/plugins/rockboy/events.c new file mode 100644 index 0000000000..5558dd86b2 --- /dev/null +++ b/apps/plugins/rockboy/events.c | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * events.c | ||
3 | * | ||
4 | * Event queue. | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include "rockmacros.h" | ||
9 | #include "input.h" | ||
10 | |||
11 | |||
12 | char keystates[MAX_KEYS]; | ||
13 | int nkeysdown; | ||
14 | |||
15 | #define MAX_EVENTS 32 | ||
16 | |||
17 | static event_t eventqueue[MAX_EVENTS]; | ||
18 | static int eventhead, eventpos; | ||
19 | |||
20 | |||
21 | int ev_postevent(event_t *ev) | ||
22 | { | ||
23 | int nextevent; | ||
24 | nextevent = (eventhead+1)%MAX_EVENTS; | ||
25 | if (nextevent == eventpos) | ||
26 | return 0; | ||
27 | eventqueue[eventhead] = *ev; | ||
28 | eventhead = nextevent; | ||
29 | return 1; | ||
30 | } | ||
31 | |||
32 | int ev_getevent(event_t *ev) | ||
33 | { | ||
34 | if (eventpos == eventhead) | ||
35 | { | ||
36 | ev->type = EV_NONE; | ||
37 | return 0; | ||
38 | } | ||
39 | *ev = eventqueue[eventpos]; | ||
40 | eventpos = (eventpos+1)%MAX_EVENTS; | ||
41 | if (ev->type == EV_PRESS) | ||
42 | { | ||
43 | keystates[ev->code] = 1; | ||
44 | nkeysdown++; | ||
45 | } | ||
46 | if (ev->type == EV_RELEASE) | ||
47 | { | ||
48 | keystates[ev->code] = 0; | ||
49 | nkeysdown--; | ||
50 | if (nkeysdown < 0) nkeysdown = 0; | ||
51 | } | ||
52 | return 1; | ||
53 | } | ||
54 | |||
55 | |||
56 | |||
57 | |||
58 | |||
59 | |||
60 | |||
61 | |||
diff --git a/apps/plugins/rockboy/exports.c b/apps/plugins/rockboy/exports.c new file mode 100644 index 0000000000..43504f4b4f --- /dev/null +++ b/apps/plugins/rockboy/exports.c | |||
@@ -0,0 +1,42 @@ | |||
1 | |||
2 | |||
3 | #include "rockmacros.h" | ||
4 | |||
5 | #include "rc.h" | ||
6 | |||
7 | extern rcvar_t emu_exports[], loader_exports[], | ||
8 | lcd_exports[], rtc_exports[], sound_exports[], | ||
9 | vid_exports[], joy_exports[], pcm_exports[]; | ||
10 | |||
11 | |||
12 | rcvar_t *sources[] = | ||
13 | { | ||
14 | emu_exports, | ||
15 | loader_exports, | ||
16 | lcd_exports, | ||
17 | rtc_exports, | ||
18 | sound_exports, | ||
19 | vid_exports, | ||
20 | joy_exports, | ||
21 | pcm_exports, | ||
22 | NULL | ||
23 | }; | ||
24 | |||
25 | |||
26 | void init_exports(void) | ||
27 | { | ||
28 | rcvar_t **s = sources; | ||
29 | |||
30 | while (*s) | ||
31 | rc_exportvars(*(s++)); | ||
32 | } | ||
33 | |||
34 | |||
35 | void show_exports(void) | ||
36 | { | ||
37 | // TODO | ||
38 | /*int i, j; | ||
39 | for (i = 0; sources[i]; i++) | ||
40 | for (j = 0; sources[i][j].name; j++) | ||
41 | printf("%s\n", sources[i][j].name);*/ | ||
42 | } | ||
diff --git a/apps/plugins/rockboy/exports.h b/apps/plugins/rockboy/exports.h new file mode 100644 index 0000000000..8d787c0945 --- /dev/null +++ b/apps/plugins/rockboy/exports.h | |||
@@ -0,0 +1,2 @@ | |||
1 | void init_exports(void); | ||
2 | void show_exports(void); | ||
diff --git a/apps/plugins/rockboy/fastmem.c b/apps/plugins/rockboy/fastmem.c new file mode 100644 index 0000000000..ffb0ed5371 --- /dev/null +++ b/apps/plugins/rockboy/fastmem.c | |||
@@ -0,0 +1,138 @@ | |||
1 | |||
2 | |||
3 | #include "rockmacros.h" | ||
4 | #include "fastmem.h" | ||
5 | |||
6 | |||
7 | #define D 0 /* direct */ | ||
8 | #define C 1 /* direct cgb-only */ | ||
9 | #define R 2 /* io register */ | ||
10 | #define S 3 /* sound register */ | ||
11 | #define W 4 /* wave pattern */ | ||
12 | |||
13 | #define F 0xFF /* fail */ | ||
14 | |||
15 | const byte himask[256]; | ||
16 | |||
17 | const byte hi_rmap[256] = | ||
18 | { | ||
19 | 0, 0, R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
20 | S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, | ||
21 | S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, | ||
22 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
23 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, C, 0, C, | ||
24 | 0, C, C, C, C, C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
25 | 0, 0, 0, 0, 0, 0, 0, 0, C, C, C, C, 0, 0, 0, 0, | ||
26 | C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
27 | }; | ||
28 | |||
29 | const byte hi_wmap[256] = | ||
30 | { | ||
31 | R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, | ||
32 | S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, | ||
33 | S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, | ||
34 | S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, | ||
35 | R, R, R, R, R, R, R, R, R, R, R, R, 0, R, 0, R, | ||
36 | 0, C, C, C, C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
37 | 0, 0, 0, 0, 0, 0, 0, 0, R, R, R, R, 0, 0, 0, 0, | ||
38 | R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
39 | |||
40 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
41 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
42 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
43 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
44 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
45 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
46 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
47 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R | ||
48 | }; | ||
49 | |||
50 | |||
51 | byte readb(int a) | ||
52 | { | ||
53 | byte *p = mbc.rmap[a>>12]; | ||
54 | if (p) return p[a]; | ||
55 | else return mem_read(a); | ||
56 | } | ||
57 | |||
58 | void writeb(int a, byte b) | ||
59 | { | ||
60 | byte *p = mbc.wmap[a>>12]; | ||
61 | if (p) p[a] = b; | ||
62 | else mem_write(a, b); | ||
63 | } | ||
64 | |||
65 | int readw(int a) | ||
66 | { | ||
67 | if ((a+1) & 0xfff) | ||
68 | { | ||
69 | byte *p = mbc.rmap[a>>12]; | ||
70 | if (p) | ||
71 | { | ||
72 | #ifdef LITTLE_ENDIAN | ||
73 | #ifndef ALLOW_UNALIGNED_IO | ||
74 | if (a&1) return p[a] | (p[a+1]<<8); | ||
75 | #endif | ||
76 | return *(word *)(p+a); | ||
77 | #else | ||
78 | return p[a] | (p[a+1]<<8); | ||
79 | #endif | ||
80 | } | ||
81 | } | ||
82 | return mem_read(a) | (mem_read(a+1)<<8); | ||
83 | } | ||
84 | |||
85 | void writew(int a, int w) | ||
86 | { | ||
87 | if ((a+1) & 0xfff) | ||
88 | { | ||
89 | byte *p = mbc.wmap[a>>12]; | ||
90 | if (p) | ||
91 | { | ||
92 | #ifdef LITTLE_ENDIAN | ||
93 | #ifndef ALLOW_UNALIGNED_IO | ||
94 | if (a&1) | ||
95 | { | ||
96 | p[a] = w; | ||
97 | p[a+1] = w >> 8; | ||
98 | return; | ||
99 | } | ||
100 | #endif | ||
101 | *(word *)(p+a) = w; | ||
102 | return; | ||
103 | #else | ||
104 | p[a] = w; | ||
105 | p[a+1] = w >> 8; | ||
106 | return; | ||
107 | #endif | ||
108 | } | ||
109 | } | ||
110 | mem_write(a, w); | ||
111 | mem_write(a+1, w>>8); | ||
112 | } | ||
113 | |||
114 | byte readhi(int a) | ||
115 | { | ||
116 | return readb(a | 0xff00); | ||
117 | } | ||
118 | |||
119 | void writehi(int a, byte b) | ||
120 | { | ||
121 | writeb(a | 0xff00, b); | ||
122 | } | ||
123 | |||
124 | #if 0 | ||
125 | byte readhi(int a) | ||
126 | { | ||
127 | byte (*rd)() = hi_read[a]; | ||
128 | return rd ? rd(a) : (ram.hi[a] | himask[a]); | ||
129 | } | ||
130 | |||
131 | void writehi(int a, byte b) | ||
132 | { | ||
133 | byte (*wr)() = hi_write[a]; | ||
134 | if (wr) wr(a, b); | ||
135 | else ram.hi[a] = b & ~himask[a]; | ||
136 | } | ||
137 | #endif | ||
138 | |||
diff --git a/apps/plugins/rockboy/fastmem.h b/apps/plugins/rockboy/fastmem.h new file mode 100644 index 0000000000..7ab447fd2a --- /dev/null +++ b/apps/plugins/rockboy/fastmem.h | |||
@@ -0,0 +1,22 @@ | |||
1 | |||
2 | #ifndef __FASTMEM_H__ | ||
3 | #define __FASTMEM_H__ | ||
4 | |||
5 | |||
6 | #include "defs.h" | ||
7 | #include "mem.h" | ||
8 | |||
9 | |||
10 | byte readb(int a); | ||
11 | void writeb(int a, byte b); | ||
12 | int readw(int a); | ||
13 | void writew(int a, int w); | ||
14 | byte readhi(int a); | ||
15 | void writehi(int a, byte b); | ||
16 | #if 0 | ||
17 | byte readhi(int a); | ||
18 | void writehi(int a, byte b); | ||
19 | #endif | ||
20 | |||
21 | |||
22 | #endif | ||
diff --git a/apps/plugins/rockboy/fb.h b/apps/plugins/rockboy/fb.h new file mode 100644 index 0000000000..97d16ae1b1 --- /dev/null +++ b/apps/plugins/rockboy/fb.h | |||
@@ -0,0 +1,35 @@ | |||
1 | |||
2 | |||
3 | #ifndef __FB_H__ | ||
4 | #define __FB_H__ | ||
5 | |||
6 | |||
7 | #include "defs.h" | ||
8 | |||
9 | |||
10 | |||
11 | struct fb | ||
12 | { | ||
13 | byte *ptr; | ||
14 | int w, h; | ||
15 | int pelsize; | ||
16 | int pitch; | ||
17 | int indexed; | ||
18 | struct | ||
19 | { | ||
20 | int l, r; | ||
21 | } cc[4]; | ||
22 | int yuv; | ||
23 | int enabled; | ||
24 | int dirty; | ||
25 | }; | ||
26 | |||
27 | |||
28 | extern struct fb fb; | ||
29 | |||
30 | |||
31 | #endif | ||
32 | |||
33 | |||
34 | |||
35 | |||
diff --git a/apps/plugins/rockboy/hw.c b/apps/plugins/rockboy/hw.c new file mode 100644 index 0000000000..c287e24f8a --- /dev/null +++ b/apps/plugins/rockboy/hw.c | |||
@@ -0,0 +1,183 @@ | |||
1 | |||
2 | |||
3 | |||
4 | #include "rockmacros.h" | ||
5 | #include "defs.h" | ||
6 | #include "cpu.h" | ||
7 | #include "hw.h" | ||
8 | #include "regs.h" | ||
9 | #include "lcd.h" | ||
10 | #include "mem.h" | ||
11 | #include "fastmem.h" | ||
12 | |||
13 | |||
14 | struct hw hw; | ||
15 | |||
16 | |||
17 | |||
18 | /* | ||
19 | * hw_interrupt changes the virtual interrupt lines included in the | ||
20 | * specified mask to the values the corresponding bits in i take, and | ||
21 | * in doing so, raises the appropriate bit of R_IF for any interrupt | ||
22 | * lines that transition from low to high. | ||
23 | */ | ||
24 | |||
25 | void hw_interrupt(byte i, byte mask) | ||
26 | { | ||
27 | byte oldif = R_IF; | ||
28 | i &= 0x1F & mask; | ||
29 | R_IF |= i & (hw.ilines ^ i); | ||
30 | |||
31 | /* FIXME - is this correct? not sure the docs understand... */ | ||
32 | if ((R_IF & (R_IF ^ oldif) & R_IE) && cpu.ime) cpu.halt = 0; | ||
33 | /* if ((i & (hw.ilines ^ i) & R_IE) && cpu.ime) cpu.halt = 0; */ | ||
34 | /* if ((i & R_IE) && cpu.ime) cpu.halt = 0; */ | ||
35 | |||
36 | hw.ilines &= ~mask; | ||
37 | hw.ilines |= i; | ||
38 | } | ||
39 | |||
40 | |||
41 | /* | ||
42 | * hw_dma performs plain old memory-to-oam dma, the original dmg | ||
43 | * dma. Although on the hardware it takes a good deal of time, the cpu | ||
44 | * continues running during this mode of dma, so no special tricks to | ||
45 | * stall the cpu are necessary. | ||
46 | */ | ||
47 | |||
48 | void hw_dma(byte b) | ||
49 | { | ||
50 | int i; | ||
51 | addr a; | ||
52 | |||
53 | a = ((addr)b) << 8; | ||
54 | for (i = 0; i < 160; i++, a++) | ||
55 | lcd.oam.mem[i] = readb(a); | ||
56 | } | ||
57 | |||
58 | |||
59 | |||
60 | void hw_hdma_cmd(byte c) | ||
61 | { | ||
62 | int cnt; | ||
63 | addr sa; | ||
64 | int da; | ||
65 | |||
66 | /* Begin or cancel HDMA */ | ||
67 | if ((hw.hdma|c) & 0x80) | ||
68 | { | ||
69 | hw.hdma = c; | ||
70 | R_HDMA5 = c & 0x7f; | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | /* Perform GDMA */ | ||
75 | sa = ((addr)R_HDMA1 << 8) | (R_HDMA2&0xf0); | ||
76 | da = 0x8000 | ((int)(R_HDMA3&0x1f) << 8) | (R_HDMA4&0xf0); | ||
77 | cnt = ((int)c)+1; | ||
78 | /* FIXME - this should use cpu time! */ | ||
79 | /*cpu_timers(102 * cnt);*/ | ||
80 | cnt <<= 4; | ||
81 | while (cnt--) | ||
82 | writeb(da++, readb(sa++)); | ||
83 | R_HDMA1 = sa >> 8; | ||
84 | R_HDMA2 = sa & 0xF0; | ||
85 | R_HDMA3 = 0x1F & (da >> 8); | ||
86 | R_HDMA4 = da & 0xF0; | ||
87 | R_HDMA5 = 0xFF; | ||
88 | } | ||
89 | |||
90 | |||
91 | void hw_hdma(void) | ||
92 | { | ||
93 | int cnt; | ||
94 | addr sa; | ||
95 | int da; | ||
96 | |||
97 | sa = ((addr)R_HDMA1 << 8) | (R_HDMA2&0xf0); | ||
98 | da = 0x8000 | ((int)(R_HDMA3&0x1f) << 8) | (R_HDMA4&0xf0); | ||
99 | cnt = 16; | ||
100 | while (cnt--) | ||
101 | writeb(da++, readb(sa++)); | ||
102 | R_HDMA1 = sa >> 8; | ||
103 | R_HDMA2 = sa & 0xF0; | ||
104 | R_HDMA3 = 0x1F & (da >> 8); | ||
105 | R_HDMA4 = da & 0xF0; | ||
106 | R_HDMA5--; | ||
107 | hw.hdma--; | ||
108 | } | ||
109 | |||
110 | |||
111 | /* | ||
112 | * pad_refresh updates the P1 register from the pad states, generating | ||
113 | * the appropriate interrupts (by quickly raising and lowering the | ||
114 | * interrupt line) if a transition has been made. | ||
115 | */ | ||
116 | |||
117 | void pad_refresh() | ||
118 | { | ||
119 | byte oldp1; | ||
120 | oldp1 = R_P1; | ||
121 | R_P1 &= 0x30; | ||
122 | R_P1 |= 0xc0; | ||
123 | if (!(R_P1 & 0x10)) | ||
124 | R_P1 |= (hw.pad & 0x0F); | ||
125 | if (!(R_P1 & 0x20)) | ||
126 | R_P1 |= (hw.pad >> 4); | ||
127 | R_P1 ^= 0x0F; | ||
128 | if (oldp1 & ~R_P1 & 0x0F) | ||
129 | { | ||
130 | hw_interrupt(IF_PAD, IF_PAD); | ||
131 | hw_interrupt(0, IF_PAD); | ||
132 | } | ||
133 | } | ||
134 | |||
135 | |||
136 | /* | ||
137 | * These simple functions just update the state of a button on the | ||
138 | * pad. | ||
139 | */ | ||
140 | |||
141 | void pad_press(byte k) | ||
142 | { | ||
143 | if (hw.pad & k) | ||
144 | return; | ||
145 | hw.pad |= k; | ||
146 | pad_refresh(); | ||
147 | } | ||
148 | |||
149 | void pad_release(byte k) | ||
150 | { | ||
151 | if (!(hw.pad & k)) | ||
152 | return; | ||
153 | hw.pad &= ~k; | ||
154 | pad_refresh(); | ||
155 | } | ||
156 | |||
157 | void pad_set(byte k, int st) | ||
158 | { | ||
159 | st ? pad_press(k) : pad_release(k); | ||
160 | } | ||
161 | |||
162 | void hw_reset() | ||
163 | { | ||
164 | hw.ilines = hw.pad = 0; | ||
165 | |||
166 | memset(ram.hi, 0, sizeof ram.hi); | ||
167 | |||
168 | R_P1 = 0xFF; | ||
169 | R_LCDC = 0x91; | ||
170 | R_BGP = 0xFC; | ||
171 | R_OBP0 = 0xFF; | ||
172 | R_OBP1 = 0xFF; | ||
173 | R_SVBK = 0x01; | ||
174 | R_HDMA5 = 0xFF; | ||
175 | R_VBK = 0xFE; | ||
176 | } | ||
177 | |||
178 | |||
179 | |||
180 | |||
181 | |||
182 | |||
183 | |||
diff --git a/apps/plugins/rockboy/hw.h b/apps/plugins/rockboy/hw.h new file mode 100644 index 0000000000..d05fb51194 --- /dev/null +++ b/apps/plugins/rockboy/hw.h | |||
@@ -0,0 +1,47 @@ | |||
1 | |||
2 | |||
3 | |||
4 | #ifndef __HW_H__ | ||
5 | #define __HW_H__ | ||
6 | |||
7 | |||
8 | #include "defs.h" | ||
9 | |||
10 | |||
11 | #define PAD_RIGHT 0x01 | ||
12 | #define PAD_LEFT 0x02 | ||
13 | #define PAD_UP 0x04 | ||
14 | #define PAD_DOWN 0x08 | ||
15 | #define PAD_A 0x10 | ||
16 | #define PAD_B 0x20 | ||
17 | #define PAD_SELECT 0x40 | ||
18 | #define PAD_START 0x80 | ||
19 | |||
20 | #define IF_VBLANK 0x01 | ||
21 | #define IF_STAT 0x02 | ||
22 | #define IF_TIMER 0x04 | ||
23 | #define IF_SERIAL 0x08 | ||
24 | #define IF_PAD 0x10 | ||
25 | |||
26 | struct hw | ||
27 | { | ||
28 | byte ilines; | ||
29 | byte pad; | ||
30 | int hdma; | ||
31 | int cgb,gba; | ||
32 | }; | ||
33 | |||
34 | |||
35 | extern struct hw hw; | ||
36 | |||
37 | void hw_interrupt(byte i, byte mask); | ||
38 | void hw_dma(byte b); | ||
39 | void hw_hdma_cmd(byte c); | ||
40 | void hw_hdma(void); | ||
41 | void pad_refresh(void); | ||
42 | void pad_press(byte k); | ||
43 | void pad_release(byte k); | ||
44 | void pad_set(byte k, int st); | ||
45 | void hw_reset(void); | ||
46 | |||
47 | #endif | ||
diff --git a/apps/plugins/rockboy/inflate.c b/apps/plugins/rockboy/inflate.c new file mode 100644 index 0000000000..6818749187 --- /dev/null +++ b/apps/plugins/rockboy/inflate.c | |||
@@ -0,0 +1,514 @@ | |||
1 | |||
2 | /* Slightly modified from its original form so as not to exit the | ||
3 | * program on errors. The resulting file remains in the public | ||
4 | * domain for all to use. */ | ||
5 | |||
6 | /* --- GZIP file format uncompression routines --- */ | ||
7 | |||
8 | /* The following routines (notably the unzip()) function below | ||
9 | * uncompress gzipped data. They are terribly slow at the task, but | ||
10 | * it is presumed that they work reasonably well. They don't do any | ||
11 | * error checking, but they're probably not too vulnerable to buggy | ||
12 | * data either. Another important limitation (but it would be pretty | ||
13 | * easy to get around) is that the data must reside in memory, it is | ||
14 | * not read as a stream. They have been very little tested. Anyway, | ||
15 | * whatever these functions are good for, I put them in the public | ||
16 | * domain. -- David Madore <david.madore@ens.fr> 1999/11/21 */ | ||
17 | |||
18 | #include "rockmacros.h" | ||
19 | |||
20 | static unsigned int | ||
21 | peek_bits (const unsigned char *data, long p, int q) | ||
22 | /* Read q bits starting from bit p from the data pointed to by | ||
23 | * data. Data is in little-endian format. */ | ||
24 | { | ||
25 | unsigned int answer; | ||
26 | int cnt; /* Number of bits already placed in answer */ | ||
27 | char ob, lb; /* Offset and length of bit field within current byte */ | ||
28 | |||
29 | answer = 0; | ||
30 | for ( cnt=0 ; cnt<q ; /* cnt updated in body */ ) | ||
31 | { | ||
32 | ob = (p+cnt)%8; | ||
33 | lb = 8-ob; | ||
34 | if ( cnt+lb > q ) | ||
35 | lb = q-cnt; | ||
36 | answer |= ((unsigned int)((data[(p+cnt)/8]>>ob)&((1U<<lb)-1)))<<cnt; | ||
37 | cnt += lb; | ||
38 | } | ||
39 | return answer; | ||
40 | } | ||
41 | |||
42 | static unsigned int | ||
43 | read_bits (const unsigned char *data, long *p, int q) | ||
44 | /* Read q bits as per peek_bits(), but also increase p by q. */ | ||
45 | { | ||
46 | unsigned int answer; | ||
47 | |||
48 | answer = peek_bits (data, *p, q); | ||
49 | *p += q; | ||
50 | return answer; | ||
51 | } | ||
52 | |||
53 | static void | ||
54 | make_code_table (const char size_table[], int table_length, | ||
55 | unsigned int code_table[], int maxbits) | ||
56 | /* Make a code table from a length table. See rfc1951, section | ||
57 | * 3.2.2, for details on what this means. The size_table | ||
58 | * contains the length of the Huffman codes for each letter, and | ||
59 | * the code_table receives the computed codes themselves. | ||
60 | * table_length is the size of the tables (alphabet length) and | ||
61 | * maxbits is the maximal allowed code length. */ | ||
62 | { | ||
63 | int i, j; | ||
64 | unsigned int code; | ||
65 | |||
66 | code = 0; | ||
67 | for ( i=1 ; i<=maxbits ; i++ ) | ||
68 | { | ||
69 | for ( j=0 ; j<table_length ; j++ ) | ||
70 | { | ||
71 | if ( size_table[j]==i ) | ||
72 | code_table[j] = code++; | ||
73 | } | ||
74 | code <<= 1; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | static int | ||
79 | decode_one (const unsigned char *data, long *p, | ||
80 | const char size_table[], int table_length, | ||
81 | const unsigned int code_table[], int maxbits) | ||
82 | /* Decode one alphabet letter from the data, starting at bit p | ||
83 | * (which will be increased by the appropriate amount) using | ||
84 | * size_table and code_table to decipher the Huffman encoding. */ | ||
85 | { | ||
86 | unsigned int code; | ||
87 | int i, j; | ||
88 | |||
89 | code = 0; | ||
90 | /* Read as many bits as are likely to be necessary - backward, of | ||
91 | * course. */ | ||
92 | for ( i=0 ; i<maxbits ; i++ ) | ||
93 | code = (code<<1) + peek_bits (data, (*p)+i, 1); | ||
94 | /* Now examine each symbol of the table to find one that matches the | ||
95 | * first bits of the code read. */ | ||
96 | for ( j=0 ; j<table_length ; j++ ) | ||
97 | { | ||
98 | if ( size_table[j] | ||
99 | && ( (code>>(maxbits-size_table[j])) == code_table[j] ) ) | ||
100 | { | ||
101 | *p += size_table[j]; | ||
102 | return j; | ||
103 | } | ||
104 | } | ||
105 | return -1; | ||
106 | } | ||
107 | |||
108 | /* I don't know what these should be. The rfc1951 doesn't seem to say | ||
109 | * (it only mentions them in the last paragraph of section 3.2.1). 15 | ||
110 | * is almost certainly safe, and it is the largest I can put given the | ||
111 | * constraints on the size of integers in the C standard. */ | ||
112 | #define CLEN_MAXBITS 15 | ||
113 | #define HLIT_MAXBITS 15 | ||
114 | #define HDIST_MAXBITS 15 | ||
115 | |||
116 | /* The magical table sizes... */ | ||
117 | #define CLEN_TSIZE 19 | ||
118 | #define HLIT_TSIZE 288 | ||
119 | #define HDIST_TSIZE 30 | ||
120 | |||
121 | static int | ||
122 | get_tables (const unsigned char *data, long *p, | ||
123 | char hlit_size_table[HLIT_TSIZE], | ||
124 | unsigned int hlit_code_table[HLIT_TSIZE], | ||
125 | char hdist_size_table[HDIST_TSIZE], | ||
126 | unsigned int hdist_code_table[HDIST_TSIZE]) | ||
127 | /* Fill the Huffman tables (first the code lengths table, and | ||
128 | * then, using it, the literal/length table and the distance | ||
129 | * table). See section 3.2.7 of rfc1951 for details. */ | ||
130 | { | ||
131 | char hlit, hdist, hclen; | ||
132 | const int clen_weird_tangle[CLEN_TSIZE] | ||
133 | = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; | ||
134 | char clen_size_table[CLEN_TSIZE]; | ||
135 | unsigned int clen_code_table[CLEN_TSIZE]; | ||
136 | int j; | ||
137 | unsigned int b; | ||
138 | int remainder; /* See note at end of section 3.2.7 of rfc1951. */ | ||
139 | char rem_val; | ||
140 | |||
141 | hlit = read_bits (data, p, 5); | ||
142 | hdist = read_bits (data, p, 5); | ||
143 | hclen = read_bits (data, p, 4); | ||
144 | for ( j=0 ; j<4+hclen ; j++ ) | ||
145 | clen_size_table[clen_weird_tangle[j]] | ||
146 | = read_bits (data, p, 3); | ||
147 | for ( ; j<CLEN_TSIZE ; j++ ) | ||
148 | clen_size_table[clen_weird_tangle[j]] = 0; | ||
149 | make_code_table (clen_size_table, CLEN_TSIZE, | ||
150 | clen_code_table, CLEN_MAXBITS); | ||
151 | remainder = 0; | ||
152 | rem_val = 0; | ||
153 | for ( j=0 ; j<257+hlit ; j++ ) | ||
154 | { | ||
155 | b = decode_one (data, p, clen_size_table, CLEN_TSIZE, | ||
156 | clen_code_table, CLEN_MAXBITS); | ||
157 | if ( b<0 ) return -1; | ||
158 | if ( b<16 ) | ||
159 | hlit_size_table[j] = b; | ||
160 | else if ( b == 16 ) | ||
161 | { | ||
162 | int k, l; | ||
163 | |||
164 | k = read_bits (data, p, 2); | ||
165 | for ( l=0 ; l<k+3 && j+l<257+hlit ; l++ ) | ||
166 | hlit_size_table[j+l] = hlit_size_table[j-1]; | ||
167 | j += l-1; | ||
168 | remainder = k+3-l; /* THIS IS SO UGLY! */ | ||
169 | rem_val = hlit_size_table[j-1]; | ||
170 | } | ||
171 | else if ( b == 17 ) | ||
172 | { | ||
173 | int k, l; | ||
174 | |||
175 | k = read_bits (data, p, 3); | ||
176 | for ( l=0 ; l<k+3 && j+l<257+hlit ; l++ ) | ||
177 | hlit_size_table[j+l] = 0; | ||
178 | j += l-1; | ||
179 | remainder = k+3-l; | ||
180 | rem_val = 0; | ||
181 | } | ||
182 | else if ( b == 18 ) | ||
183 | { | ||
184 | int k, l; | ||
185 | |||
186 | k = read_bits (data, p, 7); | ||
187 | for ( l=0 ; l<k+11 && j+l<257+hlit ; l++ ) | ||
188 | hlit_size_table[j+l] = 0; | ||
189 | j += l-1; | ||
190 | remainder = k+11-l; | ||
191 | rem_val = 0; | ||
192 | } | ||
193 | } | ||
194 | for ( ; j<HLIT_TSIZE ; j++ ) | ||
195 | hlit_size_table[j] = 0; | ||
196 | make_code_table (hlit_size_table, HLIT_TSIZE, | ||
197 | hlit_code_table, HLIT_MAXBITS); | ||
198 | for ( j=0 ; j<remainder ; j++ ) | ||
199 | hdist_size_table[j] = rem_val; | ||
200 | for ( ; j<1+hdist ; j++ ) | ||
201 | /* Can you spell: ``copy-paste''? */ | ||
202 | { | ||
203 | b = decode_one (data, p, clen_size_table, CLEN_TSIZE, | ||
204 | clen_code_table, CLEN_MAXBITS); | ||
205 | if ( b<0 ) return -1; | ||
206 | if ( b<16 ) | ||
207 | hdist_size_table[j] = b; | ||
208 | else if ( b == 16 ) | ||
209 | { | ||
210 | int k, l; | ||
211 | |||
212 | k = read_bits (data, p, 2); | ||
213 | for ( l=0 ; l<k+3 && j+l<1+hdist ; l++ ) | ||
214 | hdist_size_table[j+l] = hdist_size_table[j-1]; | ||
215 | j += l-1; | ||
216 | } | ||
217 | else if ( b == 17 ) | ||
218 | { | ||
219 | int k, l; | ||
220 | |||
221 | k = read_bits (data, p, 3); | ||
222 | for ( l=0 ; l<k+3 && j+l<1+hdist ; l++ ) | ||
223 | hdist_size_table[j+l] = 0; | ||
224 | j += l-1; | ||
225 | } | ||
226 | else if ( b == 18 ) | ||
227 | { | ||
228 | int k, l; | ||
229 | |||
230 | k = read_bits (data, p, 7); | ||
231 | for ( l=0 ; l<k+11 && j+l<1+hdist ; l++ ) | ||
232 | hdist_size_table[j+l] = 0; | ||
233 | j += l-1; | ||
234 | } | ||
235 | } | ||
236 | for ( ; j<HDIST_TSIZE ; j++ ) | ||
237 | hdist_size_table[j] = 0; | ||
238 | make_code_table (hdist_size_table, HDIST_TSIZE, | ||
239 | hdist_code_table, HDIST_MAXBITS); | ||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | /* The (circular) output buffer. This lets us track | ||
244 | * backreferences. */ | ||
245 | |||
246 | /* Minimal buffer size. Also the only useful value. */ | ||
247 | #define BUFFER_SIZE 32768 | ||
248 | |||
249 | /* Pointer to the character to be added to the buffer */ | ||
250 | static unsigned int buffer_ptr = 0; | ||
251 | |||
252 | /* The buffer itself */ | ||
253 | static unsigned char buffer[BUFFER_SIZE]; | ||
254 | |||
255 | static void | ||
256 | pushout (unsigned char ch) | ||
257 | /* Store one byte in the output buffer so it may be retrieved if | ||
258 | * it is referenced again. */ | ||
259 | { | ||
260 | buffer[buffer_ptr++] = ch; | ||
261 | buffer_ptr %= BUFFER_SIZE; | ||
262 | } | ||
263 | |||
264 | static unsigned char | ||
265 | pushin (unsigned int dist) | ||
266 | /* Retrieve one byte, dist bytes away, from the output buffer. */ | ||
267 | { | ||
268 | return buffer[(buffer_ptr+(BUFFER_SIZE-dist))%BUFFER_SIZE]; | ||
269 | } | ||
270 | |||
271 | static int | ||
272 | get_data (const unsigned char *data, long *p, | ||
273 | const char hlit_size_table[HLIT_TSIZE], | ||
274 | const unsigned int hlit_code_table[HLIT_TSIZE], | ||
275 | const char hdist_size_table[HDIST_TSIZE], | ||
276 | const unsigned int hdist_code_table[HDIST_TSIZE], | ||
277 | void (* callback) (unsigned char d)) | ||
278 | /* Do the actual uncompressing. Call callback on each character | ||
279 | * uncompressed. */ | ||
280 | { | ||
281 | unsigned int b; | ||
282 | |||
283 | while ( 1 ) { | ||
284 | b = decode_one (data, p, hlit_size_table, HLIT_TSIZE, | ||
285 | hlit_code_table, HLIT_MAXBITS); | ||
286 | if ( b<0 ) return -1; | ||
287 | if ( b < 256 ) | ||
288 | /* Literal */ | ||
289 | { | ||
290 | pushout ((unsigned char) b); | ||
291 | callback ((unsigned char) b); | ||
292 | } | ||
293 | else if ( b == 256 ) | ||
294 | /* End of block */ | ||
295 | return 0; | ||
296 | else if ( b >= 257 ) | ||
297 | /* Back reference */ | ||
298 | { | ||
299 | unsigned int bb; | ||
300 | unsigned int length, dist; | ||
301 | unsigned int l; | ||
302 | |||
303 | switch ( b ) | ||
304 | { | ||
305 | case 257: length = 3; break; | ||
306 | case 258: length = 4; break; | ||
307 | case 259: length = 5; break; | ||
308 | case 260: length = 6; break; | ||
309 | case 261: length = 7; break; | ||
310 | case 262: length = 8; break; | ||
311 | case 263: length = 9; break; | ||
312 | case 264: length = 10; break; | ||
313 | case 265: length = 11 + read_bits (data, p, 1); break; | ||
314 | case 266: length = 13 + read_bits (data, p, 1); break; | ||
315 | case 267: length = 15 + read_bits (data, p, 1); break; | ||
316 | case 268: length = 17 + read_bits (data, p, 1); break; | ||
317 | case 269: length = 19 + read_bits (data, p, 2); break; | ||
318 | case 270: length = 23 + read_bits (data, p, 2); break; | ||
319 | case 271: length = 27 + read_bits (data, p, 2); break; | ||
320 | case 272: length = 31 + read_bits (data, p, 2); break; | ||
321 | case 273: length = 35 + read_bits (data, p, 3); break; | ||
322 | case 274: length = 43 + read_bits (data, p, 3); break; | ||
323 | case 275: length = 51 + read_bits (data, p, 3); break; | ||
324 | case 276: length = 59 + read_bits (data, p, 3); break; | ||
325 | case 277: length = 67 + read_bits (data, p, 4); break; | ||
326 | case 278: length = 83 + read_bits (data, p, 4); break; | ||
327 | case 279: length = 99 + read_bits (data, p, 4); break; | ||
328 | case 280: length = 115 + read_bits (data, p, 4); break; | ||
329 | case 281: length = 131 + read_bits (data, p, 5); break; | ||
330 | case 282: length = 163 + read_bits (data, p, 5); break; | ||
331 | case 283: length = 195 + read_bits (data, p, 5); break; | ||
332 | case 284: length = 227 + read_bits (data, p, 5); break; | ||
333 | case 285: length = 258; break; | ||
334 | default: | ||
335 | return -1; | ||
336 | } | ||
337 | bb = decode_one (data, p, hdist_size_table, HDIST_TSIZE, | ||
338 | hdist_code_table, HDIST_MAXBITS); | ||
339 | switch ( bb ) | ||
340 | { | ||
341 | case 0: dist = 1; break; | ||
342 | case 1: dist = 2; break; | ||
343 | case 2: dist = 3; break; | ||
344 | case 3: dist = 4; break; | ||
345 | case 4: dist = 5 + read_bits (data, p, 1); break; | ||
346 | case 5: dist = 7 + read_bits (data, p, 1); break; | ||
347 | case 6: dist = 9 + read_bits (data, p, 2); break; | ||
348 | case 7: dist = 13 + read_bits (data, p, 2); break; | ||
349 | case 8: dist = 17 + read_bits (data, p, 3); break; | ||
350 | case 9: dist = 25 + read_bits (data, p, 3); break; | ||
351 | case 10: dist = 33 + read_bits (data, p, 4); break; | ||
352 | case 11: dist = 49 + read_bits (data, p, 4); break; | ||
353 | case 12: dist = 65 + read_bits (data, p, 5); break; | ||
354 | case 13: dist = 97 + read_bits (data, p, 5); break; | ||
355 | case 14: dist = 129 + read_bits (data, p, 6); break; | ||
356 | case 15: dist = 193 + read_bits (data, p, 6); break; | ||
357 | case 16: dist = 257 + read_bits (data, p, 7); break; | ||
358 | case 17: dist = 385 + read_bits (data, p, 7); break; | ||
359 | case 18: dist = 513 + read_bits (data, p, 8); break; | ||
360 | case 19: dist = 769 + read_bits (data, p, 8); break; | ||
361 | case 20: dist = 1025 + read_bits (data, p, 9); break; | ||
362 | case 21: dist = 1537 + read_bits (data, p, 9); break; | ||
363 | case 22: dist = 2049 + read_bits (data, p, 10); break; | ||
364 | case 23: dist = 3073 + read_bits (data, p, 10); break; | ||
365 | case 24: dist = 4097 + read_bits (data, p, 11); break; | ||
366 | case 25: dist = 6145 + read_bits (data, p, 11); break; | ||
367 | case 26: dist = 8193 + read_bits (data, p, 12); break; | ||
368 | case 27: dist = 12289 + read_bits (data, p, 12); break; | ||
369 | case 28: dist = 16385 + read_bits (data, p, 13); break; | ||
370 | case 29: dist = 24577 + read_bits (data, p, 13); break; | ||
371 | default: | ||
372 | return -1; | ||
373 | } | ||
374 | for ( l=0 ; l<length ; l++ ) | ||
375 | { | ||
376 | unsigned char ch; | ||
377 | |||
378 | ch = pushin (dist); | ||
379 | pushout (ch); | ||
380 | callback (ch); | ||
381 | } | ||
382 | } | ||
383 | } | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static int | ||
388 | inflate (const unsigned char *data, long *p, | ||
389 | void (* callback) (unsigned char d)) | ||
390 | /* Main uncompression function for the deflate method */ | ||
391 | { | ||
392 | char blast, btype; | ||
393 | char hlit_size_table[HLIT_TSIZE]; | ||
394 | unsigned int hlit_code_table[HLIT_TSIZE]; | ||
395 | char hdist_size_table[HDIST_TSIZE]; | ||
396 | unsigned int hdist_code_table[HDIST_TSIZE]; | ||
397 | |||
398 | again: | ||
399 | blast = read_bits (data, p, 1); | ||
400 | btype = read_bits (data, p, 2); | ||
401 | if ( btype == 1 || btype == 2 ) | ||
402 | { | ||
403 | if ( btype == 2 ) | ||
404 | { | ||
405 | /* Dynamic Huffman tables */ | ||
406 | if (get_tables (data, p, | ||
407 | hlit_size_table, hlit_code_table, | ||
408 | hdist_size_table, hdist_code_table) < 0) return -1; | ||
409 | } | ||
410 | else | ||
411 | /* Fixed Huffman codes */ | ||
412 | { | ||
413 | int j; | ||
414 | |||
415 | for ( j=0 ; j<144 ; j++ ) | ||
416 | hlit_size_table[j] = 8; | ||
417 | for ( ; j<256 ; j++ ) | ||
418 | hlit_size_table[j] = 9; | ||
419 | for ( ; j<280 ; j++ ) | ||
420 | hlit_size_table[j] = 7; | ||
421 | for ( ; j<HLIT_TSIZE ; j++ ) | ||
422 | hlit_size_table[j] = 8; | ||
423 | make_code_table (hlit_size_table, HLIT_TSIZE, | ||
424 | hlit_code_table, HLIT_MAXBITS); | ||
425 | for ( j=0 ; j<HDIST_TSIZE ; j++ ) | ||
426 | hdist_size_table[j] = 5; | ||
427 | make_code_table (hdist_size_table, HDIST_TSIZE, | ||
428 | hdist_code_table, HDIST_MAXBITS); | ||
429 | } | ||
430 | if (get_data (data, p, | ||
431 | hlit_size_table, hlit_code_table, | ||
432 | hdist_size_table, hdist_code_table, | ||
433 | callback) < 0) return -1;; | ||
434 | } | ||
435 | else if ( btype == 0 ) | ||
436 | /* Non compressed block */ | ||
437 | { | ||
438 | unsigned int len, nlen; | ||
439 | unsigned int l; | ||
440 | unsigned char b; | ||
441 | |||
442 | *p = (*p+7)/8; /* Jump to next byte boundary */ | ||
443 | len = read_bits (data, p, 16); | ||
444 | nlen = read_bits (data, p, 16); | ||
445 | for ( l=0 ; l<len ; l++ ) | ||
446 | { | ||
447 | b = read_bits (data, p, 8); | ||
448 | pushout (b); | ||
449 | callback (b); | ||
450 | } | ||
451 | } | ||
452 | else | ||
453 | { | ||
454 | return -1; | ||
455 | } | ||
456 | if ( ! blast ) | ||
457 | goto again; | ||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | int | ||
462 | unzip (const unsigned char *data, long *p, | ||
463 | void (* callback) (unsigned char d)) | ||
464 | /* Uncompress gzipped data. data is a pointer to the data, p is | ||
465 | * a pointer to a long that is initialized to 0 (unless for some | ||
466 | * reason you want to start uncompressing further down the data), | ||
467 | * and callback is a function taking an unsigned char and | ||
468 | * returning void that will be called successively for every | ||
469 | * uncompressed byte. */ | ||
470 | { | ||
471 | unsigned char cm, flg; | ||
472 | |||
473 | if ( read_bits (data, p, 8) != 0x1f | ||
474 | || read_bits (data, p, 8) != 0x8b ) | ||
475 | { | ||
476 | return -1; | ||
477 | } | ||
478 | cm = read_bits (data, p, 8); | ||
479 | if ( cm != 0x8 ) | ||
480 | { | ||
481 | return -1; | ||
482 | } | ||
483 | flg = read_bits (data, p, 8); | ||
484 | if ( flg & 0xe0 ) | ||
485 | /* fprintf (stderr, "Warning: unknown bits are set in flags.\n") */ ; | ||
486 | read_bits (data, p, 32); /* Ignore modification time */ | ||
487 | read_bits (data, p, 8); /* Ignore extra flags */ | ||
488 | read_bits (data, p, 8); /* Ignore OS type */ | ||
489 | if ( flg & 0x4 ) | ||
490 | { | ||
491 | /* Skip over extra data */ | ||
492 | unsigned int xlen; | ||
493 | |||
494 | xlen = read_bits (data, p, 16); | ||
495 | *p += ((long)xlen)*8; | ||
496 | } | ||
497 | if ( flg & 0x8 ) | ||
498 | { | ||
499 | /* Skip over file name */ | ||
500 | while ( read_bits (data, p, 8) ); | ||
501 | } | ||
502 | if ( flg & 0x10 ) | ||
503 | { | ||
504 | /* Skip over comment */ | ||
505 | while ( read_bits (data, p, 8) ); | ||
506 | } | ||
507 | if ( flg & 0x2 ) | ||
508 | /* Ignore CRC16 */ | ||
509 | read_bits (data, p, 16); | ||
510 | return inflate (data, p, callback); | ||
511 | /* CRC32 and ISIZE are at the end. We don't even bother to look at | ||
512 | * them. */ | ||
513 | } | ||
514 | |||
diff --git a/apps/plugins/rockboy/input.h b/apps/plugins/rockboy/input.h new file mode 100644 index 0000000000..8c5fdf9352 --- /dev/null +++ b/apps/plugins/rockboy/input.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * input.h | ||
3 | * | ||
4 | * Definitions for input device stuff - buttons, keys, etc. | ||
5 | */ | ||
6 | |||
7 | |||
8 | #define MAX_KEYS 10 | ||
9 | |||
10 | typedef struct event_s | ||
11 | { | ||
12 | int type; | ||
13 | int code; | ||
14 | } event_t; | ||
15 | |||
16 | #define EV_NONE 0 | ||
17 | #define EV_PRESS 1 | ||
18 | #define EV_RELEASE 2 | ||
19 | #define EV_REPEAT 3 | ||
20 | |||
21 | int ev_postevent(event_t *ev); | ||
22 | int ev_getevent(event_t *ev); | ||
23 | |||
24 | |||
diff --git a/apps/plugins/rockboy/lcd.c b/apps/plugins/rockboy/lcd.c new file mode 100644 index 0000000000..6351cb93ed --- /dev/null +++ b/apps/plugins/rockboy/lcd.c | |||
@@ -0,0 +1,956 @@ | |||
1 | |||
2 | |||
3 | #include "config.h" | ||
4 | #include "rockmacros.h" | ||
5 | #include "defs.h" | ||
6 | #include "regs.h" | ||
7 | #include "hw.h" | ||
8 | #include "mem.h" | ||
9 | #include "lcd.h" | ||
10 | #include "rc.h" | ||
11 | #include "fb.h" | ||
12 | #include "palette.h" | ||
13 | #ifdef USE_ASM | ||
14 | #include "asm.h" | ||
15 | #endif | ||
16 | |||
17 | struct lcd lcd; | ||
18 | |||
19 | struct scan scan; | ||
20 | |||
21 | #define BG (scan.bg) | ||
22 | #define WND (scan.wnd) | ||
23 | #define BUF (scan.buf[scanline_ind]) | ||
24 | #define PRI (scan.pri) | ||
25 | |||
26 | #define PAL1 (scan.pal1) | ||
27 | #define PAL2 (scan.pal2) | ||
28 | #define PAL4 (scan.pal4) | ||
29 | |||
30 | #define VS (scan.vs) /* vissprites */ | ||
31 | #define NS (scan.ns) | ||
32 | |||
33 | #define L (scan.l) /* line */ | ||
34 | #define X (scan.x) /* screen position */ | ||
35 | #define Y (scan.y) | ||
36 | #define S (scan.s) /* tilemap position */ | ||
37 | #define T (scan.t) | ||
38 | #define U (scan.u) /* position within tile */ | ||
39 | #define V (scan.v) | ||
40 | #define WX (scan.wx) | ||
41 | #define WY (scan.wy) | ||
42 | #define WT (scan.wt) | ||
43 | #define WV (scan.wv) | ||
44 | |||
45 | byte patpix[4096][8][8]; | ||
46 | byte patdirty[1024]; | ||
47 | byte anydirty; | ||
48 | |||
49 | // static int scale = 1; | ||
50 | |||
51 | static int rgb332; | ||
52 | |||
53 | static int sprsort = 1; | ||
54 | static int sprdebug; | ||
55 | static int scanline_ind=0; | ||
56 | |||
57 | #define DEF_PAL { 0x98d0e0, 0x68a0b0, 0x60707C, 0x2C3C3C } | ||
58 | |||
59 | static int dmg_pal[4][4] = { DEF_PAL, DEF_PAL, DEF_PAL, DEF_PAL }; | ||
60 | |||
61 | static int usefilter, filterdmg; | ||
62 | static int filter[3][4] = { | ||
63 | { 195, 25, 0, 35 }, | ||
64 | { 25, 170, 25, 35 }, | ||
65 | { 25, 60, 125, 40 } | ||
66 | }; | ||
67 | |||
68 | rcvar_t lcd_exports[] = | ||
69 | { | ||
70 | RCV_BOOL("rgb332", &rgb332), | ||
71 | RCV_VECTOR("dmg_bgp", dmg_pal[0], 4), | ||
72 | RCV_VECTOR("dmg_wndp", dmg_pal[1], 4), | ||
73 | RCV_VECTOR("dmg_obp0", dmg_pal[2], 4), | ||
74 | RCV_VECTOR("dmg_obp1", dmg_pal[3], 4), | ||
75 | RCV_BOOL("sprsort", &sprsort), | ||
76 | RCV_BOOL("sprdebug", &sprdebug), | ||
77 | RCV_BOOL("colorfilter", &usefilter), | ||
78 | RCV_BOOL("filterdmg", &filterdmg), | ||
79 | RCV_VECTOR("red", filter[0], 4), | ||
80 | RCV_VECTOR("green", filter[1], 4), | ||
81 | RCV_VECTOR("blue", filter[2], 4), | ||
82 | RCV_END | ||
83 | }; | ||
84 | |||
85 | static byte *vdest; | ||
86 | |||
87 | #ifdef ALLOW_UNALIGNED_IO /* long long is ok since this is i386-only anyway? */ | ||
88 | #define MEMCPY8(d, s) ((*(long long *)(d)) = (*(long long *)(s))) | ||
89 | #else | ||
90 | #define MEMCPY8(d, s) memcpy((d), (s), 8) | ||
91 | #endif | ||
92 | |||
93 | |||
94 | |||
95 | |||
96 | #ifndef ASM_UPDATEPATPIX | ||
97 | void updatepatpix(void) | ||
98 | { | ||
99 | int i, j; | ||
100 | #if CONFIG_CPU != SH7034 || defined(SIMULATOR) | ||
101 | int k, a, c; | ||
102 | #endif | ||
103 | byte *vram = lcd.vbank[0]; | ||
104 | |||
105 | if (!anydirty) return; | ||
106 | for (i = 0; i < 1024; i++) | ||
107 | { | ||
108 | if (i == 384) i = 512; | ||
109 | if (i == 896) break; | ||
110 | if (!patdirty[i]) continue; | ||
111 | patdirty[i] = 0; | ||
112 | for (j = 0; j < 8; j++) | ||
113 | { | ||
114 | #if CONFIG_CPU == SH7034 && !defined(SIMULATOR) | ||
115 | asm volatile ( | ||
116 | "mov.w @%2,r1 \n" | ||
117 | "swap.b r1,r2 \n" | ||
118 | |||
119 | "mov #0,r0 \n" | ||
120 | "shlr r1 \n" | ||
121 | "rotcl r0 \n" | ||
122 | "shlr r2 \n" | ||
123 | "rotcl r0 \n" | ||
124 | "mov.b r0,@%0 \n" | ||
125 | "mov.b r0,@(7,%1) \n" | ||
126 | "mov #0,r0 \n" | ||
127 | "shlr r1 \n" | ||
128 | "rotcl r0 \n" | ||
129 | "shlr r2 \n" | ||
130 | "rotcl r0 \n" | ||
131 | "mov.b r0,@(1,%0) \n" | ||
132 | "mov.b r0,@(6,%1) \n" | ||
133 | "mov #0,r0 \n" | ||
134 | "shlr r1 \n" | ||
135 | "rotcl r0 \n" | ||
136 | "shlr r2 \n" | ||
137 | "rotcl r0 \n" | ||
138 | "mov.b r0,@(2,%0) \n" | ||
139 | "mov.b r0,@(5,%1) \n" | ||
140 | "mov #0,r0 \n" | ||
141 | "shlr r1 \n" | ||
142 | "rotcl r0 \n" | ||
143 | "shlr r2 \n" | ||
144 | "rotcl r0 \n" | ||
145 | "mov.b r0,@(3,%0) \n" | ||
146 | "mov.b r0,@(4,%1) \n" | ||
147 | "mov #0,r0 \n" | ||
148 | "shlr r1 \n" | ||
149 | "rotcl r0 \n" | ||
150 | "shlr r2 \n" | ||
151 | "rotcl r0 \n" | ||
152 | "mov.b r0,@(4,%0) \n" | ||
153 | "mov.b r0,@(3,%1) \n" | ||
154 | "mov #0,r0 \n" | ||
155 | "shlr r1 \n" | ||
156 | "rotcl r0 \n" | ||
157 | "shlr r2 \n" | ||
158 | "rotcl r0 \n" | ||
159 | "mov.b r0,@(5,%0) \n" | ||
160 | "mov.b r0,@(2,%1) \n" | ||
161 | "mov #0,r0 \n" | ||
162 | "shlr r1 \n" | ||
163 | "rotcl r0 \n" | ||
164 | "shlr r2 \n" | ||
165 | "rotcl r0 \n" | ||
166 | "mov.b r0,@(6,%0) \n" | ||
167 | "mov.b r0,@(1,%1) \n" | ||
168 | "mov #0,r0 \n" | ||
169 | "shlr r1 \n" | ||
170 | "rotcl r0 \n" | ||
171 | "shlr r2 \n" | ||
172 | "rotcl r0 \n" | ||
173 | "mov.b r0,@(7,%0) \n" | ||
174 | "mov.b r0,@%1 \n" | ||
175 | : /* outputs */ | ||
176 | : /* inputs */ | ||
177 | /* %0 */ "r"(patpix[i+1024][j]), | ||
178 | /* %1 */ "r"(patpix[i][j]), | ||
179 | /* %2 */ "r"(&vram[(i<<4)|(j<<1)]) | ||
180 | : /* clobbers */ | ||
181 | "r0", "r1", "r2" | ||
182 | ); | ||
183 | #else | ||
184 | a = ((i<<4) | (j<<1)); | ||
185 | for (k = 0; k < 8; k++) | ||
186 | { | ||
187 | c = vram[a] & (1<<k) ? 1 : 0; | ||
188 | c |= vram[a+1] & (1<<k) ? 2 : 0; | ||
189 | patpix[i+1024][j][k] = c; | ||
190 | } | ||
191 | for (k = 0; k < 8; k++) | ||
192 | patpix[i][j][k] = | ||
193 | patpix[i+1024][j][7-k]; | ||
194 | #endif | ||
195 | } | ||
196 | #if CONFIG_CPU == SH7034 && !defined(SIMULATOR) | ||
197 | asm volatile ( | ||
198 | "mov.l @%0,r0 \n" | ||
199 | "mov.l @(4,%0),r1 \n" | ||
200 | "mov.l r0,@(56,%1) \n" | ||
201 | "mov.l r1,@(60,%1) \n" | ||
202 | "mov.l @(8,%0),r0 \n" | ||
203 | "mov.l @(12,%0),r1 \n" | ||
204 | "mov.l r0,@(48,%1) \n" | ||
205 | "mov.l r1,@(52,%1) \n" | ||
206 | "mov.l @(16,%0),r0 \n" | ||
207 | "mov.l @(20,%0),r1 \n" | ||
208 | "mov.l r0,@(40,%1) \n" | ||
209 | "mov.l r1,@(44,%1) \n" | ||
210 | "mov.l @(24,%0),r0 \n" | ||
211 | "mov.l @(28,%0),r1 \n" | ||
212 | "mov.l r0,@(32,%1) \n" | ||
213 | "mov.l r1,@(36,%1) \n" | ||
214 | "mov.l @(32,%0),r0 \n" | ||
215 | "mov.l @(36,%0),r1 \n" | ||
216 | "mov.l r0,@(24,%1) \n" | ||
217 | "mov.l r1,@(28,%1) \n" | ||
218 | "mov.l @(40,%0),r0 \n" | ||
219 | "mov.l @(44,%0),r1 \n" | ||
220 | "mov.l r0,@(16,%1) \n" | ||
221 | "mov.l r1,@(20,%1) \n" | ||
222 | "mov.l @(48,%0),r0 \n" | ||
223 | "mov.l @(52,%0),r1 \n" | ||
224 | "mov.l r0,@(8,%1) \n" | ||
225 | "mov.l r1,@(12,%1) \n" | ||
226 | "mov.l @(56,%0),r0 \n" | ||
227 | "mov.l @(60,%0),r1 \n" | ||
228 | "mov.l r0,@%1 \n" | ||
229 | "mov.l r1,@(4,%1) \n" | ||
230 | |||
231 | "add %2,%0 \n" | ||
232 | "add %2,%1 \n" | ||
233 | |||
234 | "mov.l @%0,r0 \n" | ||
235 | "mov.l @(4,%0),r1 \n" | ||
236 | "mov.l r0,@(56,%1) \n" | ||
237 | "mov.l r1,@(60,%1) \n" | ||
238 | "mov.l @(8,%0),r0 \n" | ||
239 | "mov.l @(12,%0),r1 \n" | ||
240 | "mov.l r0,@(48,%1) \n" | ||
241 | "mov.l r1,@(52,%1) \n" | ||
242 | "mov.l @(16,%0),r0 \n" | ||
243 | "mov.l @(20,%0),r1 \n" | ||
244 | "mov.l r0,@(40,%1) \n" | ||
245 | "mov.l r1,@(44,%1) \n" | ||
246 | "mov.l @(24,%0),r0 \n" | ||
247 | "mov.l @(28,%0),r1 \n" | ||
248 | "mov.l r0,@(32,%1) \n" | ||
249 | "mov.l r1,@(36,%1) \n" | ||
250 | "mov.l @(32,%0),r0 \n" | ||
251 | "mov.l @(36,%0),r1 \n" | ||
252 | "mov.l r0,@(24,%1) \n" | ||
253 | "mov.l r1,@(28,%1) \n" | ||
254 | "mov.l @(40,%0),r0 \n" | ||
255 | "mov.l @(44,%0),r1 \n" | ||
256 | "mov.l r0,@(16,%1) \n" | ||
257 | "mov.l r1,@(20,%1) \n" | ||
258 | "mov.l @(48,%0),r0 \n" | ||
259 | "mov.l @(52,%0),r1 \n" | ||
260 | "mov.l r0,@(8,%1) \n" | ||
261 | "mov.l r1,@(12,%1) \n" | ||
262 | "mov.l @(56,%0),r0 \n" | ||
263 | "mov.l @(60,%0),r1 \n" | ||
264 | "mov.l r0,@%1 \n" | ||
265 | "mov.l r1,@(4,%1) \n" | ||
266 | : /* outputs */ | ||
267 | : /* inputs */ | ||
268 | /* %0 */ "r"(patpix[i][0]), | ||
269 | /* %1 */ "r"(patpix[i+2048][0]), | ||
270 | /* %2 */ "r"(1024*64) | ||
271 | : /* clobbers */ | ||
272 | "r0", "r1" | ||
273 | ); | ||
274 | #else | ||
275 | for (j = 0; j < 8; j++) | ||
276 | { | ||
277 | for (k = 0; k < 8; k++) | ||
278 | { | ||
279 | patpix[i+2048][j][k] = | ||
280 | patpix[i][7-j][k]; | ||
281 | patpix[i+3072][j][k] = | ||
282 | patpix[i+1024][7-j][k]; | ||
283 | } | ||
284 | } | ||
285 | #endif | ||
286 | } | ||
287 | anydirty = 0; | ||
288 | } | ||
289 | #endif /* ASM_UPDATEPATPIX */ | ||
290 | |||
291 | |||
292 | |||
293 | void tilebuf(void) | ||
294 | { | ||
295 | int i, cnt; | ||
296 | int base; | ||
297 | byte *tilemap, *attrmap; | ||
298 | int *tilebuf; | ||
299 | int *wrap; | ||
300 | static int wraptable[64] = | ||
301 | { | ||
302 | 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, | ||
303 | 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,-32 | ||
304 | }; | ||
305 | |||
306 | base = ((R_LCDC&0x08)?0x1C00:0x1800) + (T<<5) + S; | ||
307 | tilemap = lcd.vbank[0] + base; | ||
308 | attrmap = lcd.vbank[1] + base; | ||
309 | tilebuf = BG; | ||
310 | wrap = wraptable + S; | ||
311 | cnt = ((WX + 7) >> 3) + 1; | ||
312 | |||
313 | if (hw.cgb) { | ||
314 | if (R_LCDC & 0x10) | ||
315 | for (i = cnt; i > 0; i--) | ||
316 | { | ||
317 | *(tilebuf++) = *tilemap | ||
318 | | (((int)*attrmap & 0x08) << 6) | ||
319 | | (((int)*attrmap & 0x60) << 5); | ||
320 | *(tilebuf++) = (((int)*attrmap & 0x07) << 2); | ||
321 | attrmap += *wrap + 1; | ||
322 | tilemap += *(wrap++) + 1; | ||
323 | } | ||
324 | else | ||
325 | for (i = cnt; i > 0; i--) | ||
326 | { | ||
327 | *(tilebuf++) = (256 + ((n8)*tilemap)) | ||
328 | | (((int)*attrmap & 0x08) << 6) | ||
329 | | (((int)*attrmap & 0x60) << 5); | ||
330 | *(tilebuf++) = (((int)*attrmap & 0x07) << 2); | ||
331 | attrmap += *wrap + 1; | ||
332 | tilemap += *(wrap++) + 1; | ||
333 | } | ||
334 | } | ||
335 | else | ||
336 | { | ||
337 | if (R_LCDC & 0x10) | ||
338 | for (i = cnt; i > 0; i--) | ||
339 | { | ||
340 | *(tilebuf++) = *(tilemap++); | ||
341 | tilemap += *(wrap++); | ||
342 | } | ||
343 | else | ||
344 | for (i = cnt; i > 0; i--) | ||
345 | { | ||
346 | *(tilebuf++) = (256 + ((n8)*(tilemap++))); | ||
347 | tilemap += *(wrap++); | ||
348 | } | ||
349 | } | ||
350 | |||
351 | if (WX >= 160) return; | ||
352 | |||
353 | base = ((R_LCDC&0x40)?0x1C00:0x1800) + (WT<<5); | ||
354 | tilemap = lcd.vbank[0] + base; | ||
355 | attrmap = lcd.vbank[1] + base; | ||
356 | tilebuf = WND; | ||
357 | cnt = ((160 - WX) >> 3) + 1; | ||
358 | |||
359 | if (hw.cgb) | ||
360 | { | ||
361 | if (R_LCDC & 0x10) | ||
362 | for (i = cnt; i > 0; i--) | ||
363 | { | ||
364 | *(tilebuf++) = *(tilemap++) | ||
365 | | (((int)*attrmap & 0x08) << 6) | ||
366 | | (((int)*attrmap & 0x60) << 5); | ||
367 | *(tilebuf++) = (((int)*(attrmap++)&7) << 2); | ||
368 | } | ||
369 | else | ||
370 | for (i = cnt; i > 0; i--) | ||
371 | { | ||
372 | *(tilebuf++) = (256 + ((n8)*(tilemap++))) | ||
373 | | (((int)*attrmap & 0x08) << 6) | ||
374 | | (((int)*attrmap & 0x60) << 5); | ||
375 | *(tilebuf++) = (((int)*(attrmap++)&7) << 2); | ||
376 | } | ||
377 | } | ||
378 | else | ||
379 | |||
380 | { | ||
381 | if (R_LCDC & 0x10) | ||
382 | for (i = cnt; i > 0; i--) | ||
383 | *(tilebuf++) = *(tilemap++); | ||
384 | else | ||
385 | for (i = cnt; i > 0; i--) | ||
386 | *(tilebuf++) = (256 + ((n8)*(tilemap++))); | ||
387 | } | ||
388 | } | ||
389 | |||
390 | |||
391 | // V = vertical line | ||
392 | // WX = WND start (if 0, no need to do anything) -> WY | ||
393 | // U = start...something...thingy... 7 at most | ||
394 | void bg_scan(void) | ||
395 | { | ||
396 | int cnt; | ||
397 | byte *src, *dest; | ||
398 | int *tile; | ||
399 | |||
400 | if (WX <= 0) return; | ||
401 | cnt = WX; | ||
402 | tile = BG; | ||
403 | dest = BUF; | ||
404 | |||
405 | src = patpix[*(tile++)][V] + U; | ||
406 | memcpy(dest, src, 8-U); | ||
407 | dest += 8-U; | ||
408 | cnt -= 8-U; | ||
409 | if (cnt <= 0) return; | ||
410 | while (cnt >= 8) | ||
411 | { | ||
412 | src = patpix[*(tile++)][V]; | ||
413 | MEMCPY8(dest, src); | ||
414 | dest += 8; | ||
415 | cnt -= 8; | ||
416 | } | ||
417 | src = patpix[*tile][V]; | ||
418 | while (cnt--) | ||
419 | *(dest++) = *(src++); | ||
420 | } | ||
421 | |||
422 | void wnd_scan(void) | ||
423 | { | ||
424 | int cnt; | ||
425 | byte *src, *dest; | ||
426 | int *tile; | ||
427 | |||
428 | if (WX >= 160) return; | ||
429 | cnt = 160 - WX; | ||
430 | tile = WND; | ||
431 | dest = BUF + WX; | ||
432 | |||
433 | while (cnt >= 8) | ||
434 | { | ||
435 | src = patpix[*(tile++)][WV]; | ||
436 | MEMCPY8(dest, src); | ||
437 | dest += 8; | ||
438 | cnt -= 8; | ||
439 | } | ||
440 | src = patpix[*tile][WV]; | ||
441 | while (cnt--) | ||
442 | *(dest++) = *(src++); | ||
443 | } | ||
444 | |||
445 | static void blendcpy(byte *dest, byte *src, byte b, int cnt) | ||
446 | { | ||
447 | while (cnt--) *(dest++) = *(src++) | b; | ||
448 | } | ||
449 | |||
450 | static int priused(void *attr) | ||
451 | { | ||
452 | un32 *a = attr; | ||
453 | return (int)((a[0]|a[1]|a[2]|a[3]|a[4]|a[5]|a[6]|a[7])&0x80808080); | ||
454 | } | ||
455 | |||
456 | void bg_scan_pri(void) | ||
457 | { | ||
458 | int cnt, i; | ||
459 | byte *src, *dest; | ||
460 | |||
461 | if (WX <= 0) return; | ||
462 | i = S; | ||
463 | cnt = WX; | ||
464 | dest = PRI; | ||
465 | src = lcd.vbank[1] + ((R_LCDC&0x08)?0x1C00:0x1800) + (T<<5); | ||
466 | |||
467 | if (!priused(src)) | ||
468 | { | ||
469 | memset(dest, 0, cnt); | ||
470 | return; | ||
471 | } | ||
472 | |||
473 | memset(dest, src[i++&31]&128, 8-U); | ||
474 | dest += 8-U; | ||
475 | cnt -= 8-U; | ||
476 | if (cnt <= 0) return; | ||
477 | while (cnt >= 8) | ||
478 | { | ||
479 | memset(dest, src[i++&31]&128, 8); | ||
480 | dest += 8; | ||
481 | cnt -= 8; | ||
482 | } | ||
483 | memset(dest, src[i&31]&128, cnt); | ||
484 | } | ||
485 | |||
486 | void wnd_scan_pri(void) | ||
487 | { | ||
488 | int cnt, i; | ||
489 | byte *src, *dest; | ||
490 | |||
491 | if (WX >= 160) return; | ||
492 | i = 0; | ||
493 | cnt = 160 - WX; | ||
494 | dest = PRI + WX; | ||
495 | src = lcd.vbank[1] + ((R_LCDC&0x40)?0x1C00:0x1800) + (WT<<5); | ||
496 | |||
497 | if (!priused(src)) | ||
498 | { | ||
499 | memset(dest, 0, cnt); | ||
500 | return; | ||
501 | } | ||
502 | |||
503 | while (cnt >= 8) | ||
504 | { | ||
505 | memset(dest, src[i++]&128, 8); | ||
506 | dest += 8; | ||
507 | cnt -= 8; | ||
508 | } | ||
509 | memset(dest, src[i]&128, cnt); | ||
510 | } | ||
511 | |||
512 | void bg_scan_color(void) | ||
513 | { | ||
514 | int cnt; | ||
515 | byte *src, *dest; | ||
516 | int *tile; | ||
517 | |||
518 | if (WX <= 0) return; | ||
519 | cnt = WX; | ||
520 | tile = BG; | ||
521 | dest = BUF; | ||
522 | |||
523 | src = patpix[*(tile++)][V] + U; | ||
524 | blendcpy(dest, src, *(tile++), 8-U); | ||
525 | dest += 8-U; | ||
526 | cnt -= 8-U; | ||
527 | if (cnt <= 0) return; | ||
528 | while (cnt >= 8) | ||
529 | { | ||
530 | src = patpix[*(tile++)][V]; | ||
531 | blendcpy(dest, src, *(tile++), 8); | ||
532 | dest += 8; | ||
533 | cnt -= 8; | ||
534 | } | ||
535 | src = patpix[*(tile++)][V]; | ||
536 | blendcpy(dest, src, *(tile++), cnt); | ||
537 | } | ||
538 | |||
539 | // blend in window source WND target BUF | ||
540 | // WX = starting X in buf where WND starts | ||
541 | // WV = vertical line selected for this scanline | ||
542 | // reverse: | ||
543 | // WY = starting y in buf where WND starts ? | ||
544 | // W?? = horizontal line selected for this scanline | ||
545 | void wnd_scan_color(void) | ||
546 | { | ||
547 | int cnt; | ||
548 | byte *src, *dest; | ||
549 | int *tile; | ||
550 | |||
551 | if (WX >= 160) return; | ||
552 | cnt = 160 - WX; | ||
553 | tile = WND; | ||
554 | dest = BUF + WX; | ||
555 | |||
556 | while (cnt >= 8) | ||
557 | { | ||
558 | src = patpix[*(tile++)][WV]; | ||
559 | blendcpy(dest, src, *(tile++), 8); | ||
560 | dest += 8; | ||
561 | cnt -= 8; | ||
562 | } | ||
563 | src = patpix[*(tile++)][WV]; | ||
564 | blendcpy(dest, src, *(tile++), cnt); | ||
565 | } | ||
566 | |||
567 | static void recolor(byte *buf, byte fill, int cnt) | ||
568 | { | ||
569 | while (cnt--) *(buf++) |= fill; | ||
570 | } | ||
571 | |||
572 | void spr_count(void) | ||
573 | { | ||
574 | int i; | ||
575 | struct obj *o; | ||
576 | |||
577 | NS = 0; | ||
578 | if (!(R_LCDC & 0x02)) return; | ||
579 | |||
580 | o = lcd.oam.obj; | ||
581 | |||
582 | for (i = 40; i; i--, o++) | ||
583 | { | ||
584 | if (L >= o->y || L + 16 < o->y) | ||
585 | continue; | ||
586 | if (L + 8 >= o->y && !(R_LCDC & 0x04)) | ||
587 | continue; | ||
588 | if (++NS == 10) break; | ||
589 | } | ||
590 | } | ||
591 | |||
592 | void spr_enum(void) | ||
593 | { | ||
594 | int i, j; | ||
595 | struct obj *o; | ||
596 | struct vissprite ts[10]; | ||
597 | int v, pat; | ||
598 | int l, x; | ||
599 | |||
600 | NS = 0; | ||
601 | if (!(R_LCDC & 0x02)) return; | ||
602 | |||
603 | o = lcd.oam.obj; | ||
604 | |||
605 | for (i = 40; i; i--, o++) | ||
606 | { | ||
607 | if (L >= o->y || L + 16 < o->y) | ||
608 | continue; | ||
609 | if (L + 8 >= o->y && !(R_LCDC & 0x04)) | ||
610 | continue; | ||
611 | VS[NS].x = (int)o->x - 8; | ||
612 | v = L - (int)o->y + 16; | ||
613 | if (hw.cgb) | ||
614 | { | ||
615 | pat = o->pat | (((int)o->flags & 0x60) << 5) | ||
616 | | (((int)o->flags & 0x08) << 6); | ||
617 | VS[NS].pal = 32 + ((o->flags & 0x07) << 2); | ||
618 | } | ||
619 | else | ||
620 | { | ||
621 | pat = o->pat | (((int)o->flags & 0x60) << 5); | ||
622 | VS[NS].pal = 32 + ((o->flags & 0x10) >> 2); | ||
623 | } | ||
624 | VS[NS].pri = (o->flags & 0x80) >> 7; | ||
625 | if ((R_LCDC & 0x04)) | ||
626 | { | ||
627 | pat &= ~1; | ||
628 | if (v >= 8) | ||
629 | { | ||
630 | v -= 8; | ||
631 | pat++; | ||
632 | } | ||
633 | if (o->flags & 0x40) pat ^= 1; | ||
634 | } | ||
635 | VS[NS].buf = patpix[pat][v]; | ||
636 | if (++NS == 10) break; | ||
637 | } | ||
638 | if (!sprsort||hw.cgb) return; | ||
639 | /* not quite optimal but it finally works! */ | ||
640 | for (i = 0; i < NS; i++) | ||
641 | { | ||
642 | l = 0; | ||
643 | x = VS[0].x; | ||
644 | for (j = 1; j < NS; j++) | ||
645 | { | ||
646 | if (VS[j].x < x) | ||
647 | { | ||
648 | l = j; | ||
649 | x = VS[j].x; | ||
650 | } | ||
651 | } | ||
652 | ts[i] = VS[l]; | ||
653 | VS[l].x = 160; | ||
654 | } | ||
655 | memcpy(VS, ts, sizeof VS); | ||
656 | } | ||
657 | |||
658 | void spr_scan(void) | ||
659 | { | ||
660 | int i, x; | ||
661 | byte pal, b, ns = NS; | ||
662 | byte *src, *dest, *bg, *pri; | ||
663 | struct vissprite *vs; | ||
664 | static byte bgdup[256]; | ||
665 | |||
666 | if (!ns) return; | ||
667 | |||
668 | memcpy(bgdup, BUF, 256); | ||
669 | vs = &VS[ns-1]; | ||
670 | |||
671 | for (; ns; ns--, vs--) | ||
672 | { | ||
673 | x = vs->x; | ||
674 | if (x >= 160) continue; | ||
675 | if (x <= -8) continue; | ||
676 | if (x < 0) | ||
677 | { | ||
678 | src = vs->buf - x; | ||
679 | dest = BUF; | ||
680 | i = 8 + x; | ||
681 | } | ||
682 | else | ||
683 | { | ||
684 | src = vs->buf; | ||
685 | dest = BUF + x; | ||
686 | if (x > 152) i = 160 - x; | ||
687 | else i = 8; | ||
688 | } | ||
689 | pal = vs->pal; | ||
690 | if (vs->pri) | ||
691 | { | ||
692 | bg = bgdup + (dest - BUF); | ||
693 | while (i--) | ||
694 | { | ||
695 | b = src[i]; | ||
696 | if (b && !(bg[i]&3)) dest[i] = pal|b; | ||
697 | } | ||
698 | } | ||
699 | else if (hw.cgb) | ||
700 | { | ||
701 | bg = bgdup + (dest - BUF); | ||
702 | pri = PRI + (dest - BUF); | ||
703 | while (i--) | ||
704 | { | ||
705 | b = src[i]; | ||
706 | if (b && (!pri[i] || !(bg[i]&3))) | ||
707 | dest[i] = pal|b; | ||
708 | } | ||
709 | } | ||
710 | else while (i--) if (src[i]) dest[i] = pal|src[i]; | ||
711 | /* else while (i--) if (src[i]) dest[i] = 31 + ns; */ | ||
712 | } | ||
713 | // if (sprdebug) for (i = 0; i < NS; i++) BUF[i<<1] = 36; | ||
714 | } | ||
715 | |||
716 | |||
717 | |||
718 | |||
719 | |||
720 | |||
721 | void lcd_begin(void) | ||
722 | { | ||
723 | /* if (fb.indexed) | ||
724 | { | ||
725 | if (rgb332) pal_set332(); | ||
726 | else pal_expire(); | ||
727 | } | ||
728 | while (scale * 160 > fb.w || scale * 144 > fb.h) scale--; */ | ||
729 | vdest = fb.ptr + ((fb.w*fb.pelsize)>>1) | ||
730 | - (80*fb.pelsize) | ||
731 | + ((fb.h>>1) - 72) * fb.pitch; | ||
732 | WY = R_WY; | ||
733 | } | ||
734 | |||
735 | void lcd_refreshline(void) | ||
736 | { | ||
737 | if (!fb.enabled) return; | ||
738 | |||
739 | if (!(R_LCDC & 0x80)) | ||
740 | return; /* should not happen... */ | ||
741 | |||
742 | #if LCD_HEIGHT == 64 | ||
743 | if (R_LY >= 128 || R_LY & 1) /* calculate only even lines */ | ||
744 | #else | ||
745 | if (R_LY >= 128) | ||
746 | #endif | ||
747 | return; | ||
748 | |||
749 | updatepatpix(); | ||
750 | |||
751 | L = R_LY; | ||
752 | #if LCD_HEIGHT == 64 | ||
753 | scanline_ind = (L/2) % 8; | ||
754 | #else | ||
755 | scanline_ind = L % 8; | ||
756 | #endif | ||
757 | X = R_SCX; | ||
758 | Y = (R_SCY + L) & 0xff; | ||
759 | S = X >> 3; | ||
760 | T = Y >> 3; | ||
761 | U = X & 7; | ||
762 | V = Y & 7; | ||
763 | |||
764 | WX = R_WX - 7; | ||
765 | if (WY>L || WY<0 || WY>143 || WX<-7 || WX>159 || !(R_LCDC&0x20)) | ||
766 | WX = 160; | ||
767 | WT = (L - WY) >> 3; | ||
768 | WV = (L - WY) & 7; | ||
769 | |||
770 | spr_enum(); | ||
771 | |||
772 | tilebuf(); | ||
773 | if (hw.cgb) | ||
774 | { | ||
775 | bg_scan_color(); | ||
776 | wnd_scan_color(); | ||
777 | if (NS) | ||
778 | { | ||
779 | bg_scan_pri(); | ||
780 | wnd_scan_pri(); | ||
781 | } | ||
782 | } | ||
783 | else | ||
784 | { | ||
785 | |||
786 | bg_scan(); | ||
787 | wnd_scan(); | ||
788 | recolor(BUF+WX, 0x04, 160-WX); | ||
789 | } | ||
790 | spr_scan(); | ||
791 | /* | ||
792 | if (fb.dirty) memset(fb.ptr, 0, fb.pitch * fb.h); | ||
793 | fb.dirty = 0; | ||
794 | if (density > scale) density = scale; | ||
795 | if (scale == 1) density = 1; | ||
796 | dest = vdest; | ||
797 | */ | ||
798 | if (scanline_ind == 7) | ||
799 | vid_update(L); | ||
800 | // vdest += fb.pitch * scale; | ||
801 | } | ||
802 | |||
803 | |||
804 | |||
805 | |||
806 | |||
807 | |||
808 | /* | ||
809 | static void updatepalette(int i) | ||
810 | { | ||
811 | int c, r, g, b, y, u, v, rr, gg; | ||
812 | |||
813 | c = (lcd.pal[i<<1] | ((int)lcd.pal[(i<<1)|1] << 8)) & 0x7FFF; | ||
814 | r = (c & 0x001F) << 3; | ||
815 | g = (c & 0x03E0) >> 2; | ||
816 | b = (c & 0x7C00) >> 7; | ||
817 | r |= (r >> 5); | ||
818 | g |= (g >> 5); | ||
819 | b |= (b >> 5); | ||
820 | |||
821 | if (usefilter && (filterdmg||hw.cgb)) | ||
822 | { | ||
823 | rr = ((r * filter[0][0] + g * filter[0][1] + b * filter[0][2]) >> 8) + filter[0][3]; | ||
824 | gg = ((r * filter[1][0] + g * filter[1][1] + b * filter[1][2]) >> 8) + filter[1][3]; | ||
825 | b = ((r * filter[2][0] + g * filter[2][1] + b * filter[2][2]) >> 8) + filter[2][3]; | ||
826 | r = rr; | ||
827 | g = gg; | ||
828 | } | ||
829 | |||
830 | if (fb.yuv) | ||
831 | { | ||
832 | y = (((r * 263) + (g * 516) + (b * 100)) >> 10) + 16; | ||
833 | u = (((r * 450) - (g * 377) - (b * 73)) >> 10) + 128; | ||
834 | v = (((r * -152) - (g * 298) + (b * 450)) >> 10) + 128; | ||
835 | if (y < 0) y = 0; if (y > 255) y = 255; | ||
836 | if (u < 0) u = 0; if (u > 255) u = 255; | ||
837 | if (v < 0) v = 0; if (v > 255) v = 255; | ||
838 | PAL4[i] = (y<<fb.cc[0].l) | (y<<fb.cc[3].l) | ||
839 | | (u<<fb.cc[1].l) | (v<<fb.cc[2].l); | ||
840 | return; | ||
841 | } | ||
842 | |||
843 | if (fb.indexed) | ||
844 | { | ||
845 | pal_release(PAL1[i]); | ||
846 | c = pal_getcolor(c, r, g, b); | ||
847 | PAL1[i] = c; | ||
848 | PAL2[i] = (c<<8) | c; | ||
849 | PAL4[i] = (c<<24) | (c<<16) | (c<<8) | c; | ||
850 | return; | ||
851 | } | ||
852 | |||
853 | r = (r >> fb.cc[0].r) << fb.cc[0].l; | ||
854 | g = (g >> fb.cc[1].r) << fb.cc[1].l; | ||
855 | b = (b >> fb.cc[2].r) << fb.cc[2].l; | ||
856 | c = r|g|b; | ||
857 | |||
858 | switch (fb.pelsize) | ||
859 | { | ||
860 | case 1: | ||
861 | PAL1[i] = c; | ||
862 | PAL2[i] = (c<<8) | c; | ||
863 | PAL4[i] = (c<<24) | (c<<16) | (c<<8) | c; | ||
864 | break; | ||
865 | case 2: | ||
866 | PAL2[i] = c; | ||
867 | PAL4[i] = (c<<16) | c; | ||
868 | break; | ||
869 | case 3: | ||
870 | case 4: | ||
871 | PAL4[i] = c; | ||
872 | break; | ||
873 | } | ||
874 | }*/ | ||
875 | |||
876 | void pal_write(int i, byte b) | ||
877 | { | ||
878 | if (lcd.pal[i] == b) return; | ||
879 | lcd.pal[i] = b; | ||
880 | // updatepalette(i>>1); | ||
881 | } | ||
882 | |||
883 | void pal_write_dmg(int i, int mapnum, byte d) | ||
884 | { | ||
885 | int j; | ||
886 | int *cmap = dmg_pal[mapnum]; | ||
887 | int c, r, g, b; | ||
888 | |||
889 | if (hw.cgb) return; | ||
890 | |||
891 | /* if (mapnum >= 2) d = 0xe4; */ | ||
892 | for (j = 0; j < 8; j += 2) | ||
893 | { | ||
894 | c = cmap[(d >> j) & 3]; | ||
895 | r = (c & 0xf8) >> 3; | ||
896 | g = (c & 0xf800) >> 6; | ||
897 | b = (c & 0xf80000) >> 9; | ||
898 | c = r|g|b; | ||
899 | /* FIXME - handle directly without faking cgb */ | ||
900 | pal_write(i+j, c & 0xff); | ||
901 | pal_write(i+j+1, c >> 8); | ||
902 | } | ||
903 | } | ||
904 | |||
905 | void vram_write(int a, byte b) | ||
906 | { | ||
907 | lcd.vbank[R_VBK&1][a] = b; | ||
908 | if (a >= 0x1800) return; | ||
909 | patdirty[((R_VBK&1)<<9)+(a>>4)] = 1; | ||
910 | anydirty = 1; | ||
911 | } | ||
912 | |||
913 | void vram_dirty(void) | ||
914 | { | ||
915 | anydirty = 1; | ||
916 | memset(patdirty, 1, sizeof patdirty); | ||
917 | } | ||
918 | |||
919 | void pal_dirty(void) | ||
920 | { | ||
921 | // int i; | ||
922 | if (!hw.cgb) | ||
923 | { | ||
924 | |||
925 | pal_write_dmg(0, 0, R_BGP); | ||
926 | pal_write_dmg(8, 1, R_BGP); | ||
927 | pal_write_dmg(64, 2, R_OBP0); | ||
928 | pal_write_dmg(72, 3, R_OBP1); | ||
929 | } | ||
930 | // for (i = 0; i < 64; i++) | ||
931 | // updatepalette(i); | ||
932 | } | ||
933 | |||
934 | void lcd_reset(void) | ||
935 | { | ||
936 | memset(&lcd, 0, sizeof lcd); | ||
937 | lcd_begin(); | ||
938 | vram_dirty(); | ||
939 | pal_dirty(); | ||
940 | } | ||
941 | |||
942 | |||
943 | |||
944 | |||
945 | |||
946 | |||
947 | |||
948 | |||
949 | |||
950 | |||
951 | |||
952 | |||
953 | |||
954 | |||
955 | |||
956 | |||
diff --git a/apps/plugins/rockboy/lcd.h b/apps/plugins/rockboy/lcd.h new file mode 100644 index 0000000000..9442b56cf0 --- /dev/null +++ b/apps/plugins/rockboy/lcd.h | |||
@@ -0,0 +1,74 @@ | |||
1 | |||
2 | |||
3 | #ifndef __LCD_H__ | ||
4 | #define __LCD_H__ | ||
5 | |||
6 | #include "defs.h" | ||
7 | |||
8 | struct vissprite | ||
9 | { | ||
10 | byte *buf; | ||
11 | int x; | ||
12 | byte pal, pri, pad[6]; | ||
13 | }; | ||
14 | |||
15 | struct scan | ||
16 | { | ||
17 | int bg[64]; | ||
18 | int wnd[64]; | ||
19 | byte buf[8][256]; | ||
20 | byte pal1[128]; | ||
21 | un16 pal2[64]; | ||
22 | un32 pal4[64]; | ||
23 | byte pri[256]; | ||
24 | struct vissprite vs[16]; | ||
25 | int ns, l, x, y, s, t, u, v, wx, wy, wt, wv; | ||
26 | }; | ||
27 | |||
28 | struct obj | ||
29 | { | ||
30 | byte y; | ||
31 | byte x; | ||
32 | byte pat; | ||
33 | byte flags; | ||
34 | }; | ||
35 | |||
36 | struct lcd | ||
37 | { | ||
38 | byte vbank[2][8192]; | ||
39 | union | ||
40 | { | ||
41 | byte mem[256]; | ||
42 | struct obj obj[40]; | ||
43 | } oam; | ||
44 | byte pal[128]; | ||
45 | }; | ||
46 | |||
47 | extern struct lcd lcd; | ||
48 | extern struct scan scan; | ||
49 | |||
50 | |||
51 | |||
52 | |||
53 | |||
54 | #endif | ||
55 | |||
56 | |||
57 | |||
58 | void updatepatpix(void); | ||
59 | void tilebuf(void); | ||
60 | void bg_scan(void); | ||
61 | void wnd_scan(void); | ||
62 | void bg_scan_pri(void); | ||
63 | void wnd_scan_pri(void); | ||
64 | void spr_count(void); | ||
65 | void spr_enum(void); | ||
66 | void spr_scan(void); | ||
67 | void lcd_begin(void); | ||
68 | void lcd_refreshline(void); | ||
69 | void pal_write(int i, byte b); | ||
70 | void pal_write_dmg(int i, int mapnum, byte d); | ||
71 | void vram_write(int a, byte b); | ||
72 | void vram_dirty(void); | ||
73 | void pal_dirty(void); | ||
74 | void lcd_reset(void); | ||
diff --git a/apps/plugins/rockboy/lcdc.c b/apps/plugins/rockboy/lcdc.c new file mode 100644 index 0000000000..c82b828354 --- /dev/null +++ b/apps/plugins/rockboy/lcdc.c | |||
@@ -0,0 +1,180 @@ | |||
1 | |||
2 | |||
3 | #include "rockmacros.h" | ||
4 | |||
5 | #include "defs.h" | ||
6 | #include "hw.h" | ||
7 | #include "cpu.h" | ||
8 | #include "regs.h" | ||
9 | #include "lcd.h" | ||
10 | |||
11 | |||
12 | #define C (cpu.lcdc) | ||
13 | |||
14 | |||
15 | /* | ||
16 | * stat_trigger updates the STAT interrupt line to reflect whether any | ||
17 | * of the conditions set to be tested (by bits 3-6 of R_STAT) are met. | ||
18 | * This function should be called whenever any of the following occur: | ||
19 | * 1) LY or LYC changes. | ||
20 | * 2) A state transition affects the low 2 bits of R_STAT (see below). | ||
21 | * 3) The program writes to the upper bits of R_STAT. | ||
22 | * stat_trigger also updates bit 2 of R_STAT to reflect whether LY=LYC. | ||
23 | */ | ||
24 | |||
25 | void stat_trigger(void) | ||
26 | { | ||
27 | static const int condbits[4] = { 0x08, 0x30, 0x20, 0x00 }; | ||
28 | int flag = 0; | ||
29 | |||
30 | if ((R_LY < 0x91) && (R_LY == R_LYC)) | ||
31 | { | ||
32 | R_STAT |= 0x04; | ||
33 | if (R_STAT & 0x40) flag = IF_STAT; | ||
34 | } | ||
35 | else R_STAT &= ~0x04; | ||
36 | |||
37 | if (R_STAT & condbits[R_STAT&3]) flag = IF_STAT; | ||
38 | |||
39 | if (!(R_LCDC & 0x80)) flag = 0; | ||
40 | |||
41 | hw_interrupt(flag, IF_STAT); | ||
42 | } | ||
43 | |||
44 | void stat_write(byte b) | ||
45 | { | ||
46 | R_STAT = (R_STAT & 0x07) | (b & 0x78); | ||
47 | if (!hw.cgb &&!(R_STAT & 2)) /* DMG STAT write bug => interrupt */ | ||
48 | hw_interrupt(IF_STAT, IF_STAT); | ||
49 | stat_trigger(); | ||
50 | } | ||
51 | |||
52 | |||
53 | /* | ||
54 | * stat_change is called when a transition results in a change to the | ||
55 | * LCD STAT condition (the low 2 bits of R_STAT). It raises or lowers | ||
56 | * the VBLANK interrupt line appropriately and calls stat_trigger to | ||
57 | * update the STAT interrupt line. | ||
58 | */ | ||
59 | |||
60 | static void stat_change(int stat) | ||
61 | { | ||
62 | stat &= 3; | ||
63 | R_STAT = (R_STAT & 0x7C) | stat; | ||
64 | |||
65 | if (stat != 1) hw_interrupt(0, IF_VBLANK); | ||
66 | /* hw_interrupt((stat == 1) ? IF_VBLANK : 0, IF_VBLANK); */ | ||
67 | stat_trigger(); | ||
68 | } | ||
69 | |||
70 | |||
71 | void lcdc_change(byte b) | ||
72 | { | ||
73 | byte old = R_LCDC; | ||
74 | R_LCDC = b; | ||
75 | if ((R_LCDC ^ old) & 0x80) /* lcd on/off change */ | ||
76 | { | ||
77 | R_LY = 0; | ||
78 | stat_change(2); | ||
79 | C = 40; | ||
80 | lcd_begin(); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | |||
85 | void lcdc_trans(void) | ||
86 | { | ||
87 | if (!(R_LCDC & 0x80)) | ||
88 | { | ||
89 | while (C <= 0) | ||
90 | { | ||
91 | switch ((byte)(R_STAT & 3)) | ||
92 | { | ||
93 | case 0: | ||
94 | case 1: | ||
95 | stat_change(2); | ||
96 | C += 40; | ||
97 | break; | ||
98 | case 2: | ||
99 | stat_change(3); | ||
100 | C += 86; | ||
101 | break; | ||
102 | case 3: | ||
103 | stat_change(0); | ||
104 | if (hw.hdma & 0x80) | ||
105 | hw_hdma(); | ||
106 | else | ||
107 | C += 102; | ||
108 | break; | ||
109 | } | ||
110 | return; | ||
111 | } | ||
112 | } | ||
113 | while (C <= 0) | ||
114 | { | ||
115 | switch ((byte)(R_STAT & 3)) | ||
116 | { | ||
117 | case 1: | ||
118 | if (!(hw.ilines & IF_VBLANK)) | ||
119 | { | ||
120 | C += 218; | ||
121 | hw_interrupt(IF_VBLANK, IF_VBLANK); | ||
122 | break; | ||
123 | } | ||
124 | if (R_LY == 0) | ||
125 | { | ||
126 | lcd_begin(); | ||
127 | stat_change(2); | ||
128 | C += 40; | ||
129 | break; | ||
130 | } | ||
131 | else if (R_LY < 152) | ||
132 | C += 228; | ||
133 | else if (R_LY == 152) | ||
134 | C += 28; | ||
135 | else | ||
136 | { | ||
137 | R_LY = -1; | ||
138 | C += 200; | ||
139 | } | ||
140 | R_LY++; | ||
141 | stat_trigger(); | ||
142 | break; | ||
143 | case 2: | ||
144 | lcd_refreshline(); | ||
145 | stat_change(3); | ||
146 | C += 86; | ||
147 | break; | ||
148 | case 3: | ||
149 | stat_change(0); | ||
150 | if (hw.hdma & 0x80) | ||
151 | hw_hdma(); | ||
152 | /* FIXME -- how much of the hblank does hdma use?? */ | ||
153 | /* else */ | ||
154 | C += 102; | ||
155 | break; | ||
156 | case 0: | ||
157 | if (++R_LY >= 144) | ||
158 | { | ||
159 | if (cpu.halt) | ||
160 | { | ||
161 | hw_interrupt(IF_VBLANK, IF_VBLANK); | ||
162 | C += 228; | ||
163 | } | ||
164 | else C += 10; | ||
165 | stat_change(1); | ||
166 | break; | ||
167 | } | ||
168 | stat_change(2); | ||
169 | C += 40; | ||
170 | break; | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | |||
175 | |||
176 | |||
177 | |||
178 | |||
179 | |||
180 | |||
diff --git a/apps/plugins/rockboy/lcdc.h b/apps/plugins/rockboy/lcdc.h new file mode 100644 index 0000000000..c5edc6c065 --- /dev/null +++ b/apps/plugins/rockboy/lcdc.h | |||
@@ -0,0 +1,4 @@ | |||
1 | void stat_trigger(void); | ||
2 | void stat_write(byte b); | ||
3 | void lcdc_change(byte b); | ||
4 | void lcdc_trans(void); | ||
diff --git a/apps/plugins/rockboy/loader.c b/apps/plugins/rockboy/loader.c new file mode 100644 index 0000000000..ad7c309bd8 --- /dev/null +++ b/apps/plugins/rockboy/loader.c | |||
@@ -0,0 +1,383 @@ | |||
1 | |||
2 | #include <stdio.h> | ||
3 | #include <string.h> | ||
4 | |||
5 | |||
6 | #include "rockmacros.h" | ||
7 | #include "defs.h" | ||
8 | #include "regs.h" | ||
9 | #include "mem.h" | ||
10 | #include "hw.h" | ||
11 | #include "rtc.h" | ||
12 | #include "rc.h" | ||
13 | #include "save.h" | ||
14 | #include "sound.h" | ||
15 | |||
16 | |||
17 | static int mbc_table[256] = | ||
18 | { | ||
19 | 0, 1, 1, 1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, | ||
20 | 3, 3, 3, 3, 0, 0, 0, 0, 0, 5, 5, 5, MBC_RUMBLE, MBC_RUMBLE, MBC_RUMBLE, 0, | ||
21 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
22 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
23 | |||
24 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
25 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
26 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
27 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
28 | |||
29 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
30 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
31 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
32 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
33 | |||
34 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
35 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
36 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
37 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MBC_HUC3, MBC_HUC1 | ||
38 | }; | ||
39 | |||
40 | static int rtc_table[256] = | ||
41 | { | ||
42 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, | ||
43 | 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
44 | 0 | ||
45 | }; | ||
46 | |||
47 | static int batt_table[256] = | ||
48 | { | ||
49 | 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, | ||
50 | 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, | ||
51 | 0 | ||
52 | }; | ||
53 | |||
54 | static int romsize_table[256] = | ||
55 | { | ||
56 | 2, 4, 8, 16, 32, 64, 128, 256, 512, | ||
57 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
58 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
59 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
60 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
61 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
62 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
63 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
64 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
65 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
66 | 0, 0, 128, 128, 128 | ||
67 | /* 0, 0, 72, 80, 96 -- actual values but bad to use these! */ | ||
68 | }; | ||
69 | |||
70 | static int ramsize_table[256] = | ||
71 | { | ||
72 | 1, 1, 1, 4, 16, | ||
73 | 4 /* FIXME - what value should this be?! */ | ||
74 | }; | ||
75 | |||
76 | |||
77 | static char *romfile; | ||
78 | static char sramfile[500]; | ||
79 | static char rtcfile[500]; | ||
80 | static char saveprefix[500]; | ||
81 | |||
82 | static char *savename; | ||
83 | static char *savedir = "/.rockbox/rockboy"; | ||
84 | |||
85 | static int saveslot; | ||
86 | |||
87 | static int forcebatt, nobatt; | ||
88 | static int forcedmg; | ||
89 | |||
90 | static int memfill = -1, memrand = -1; | ||
91 | |||
92 | //static byte romMemory[4*1025*1024]; | ||
93 | int mp3_buffer_size; | ||
94 | void *bufferpos; | ||
95 | |||
96 | static void initmem(void *mem, int size) | ||
97 | { | ||
98 | char *p = mem; | ||
99 | if (memrand >= 0) | ||
100 | { | ||
101 | srand(memrand ? memrand : -6 ); //time(0)); | ||
102 | while(size--) *(p++) = rand(); | ||
103 | } | ||
104 | else if (memfill >= 0) | ||
105 | memset(p, memfill, size); | ||
106 | } | ||
107 | |||
108 | static byte *loadfile(int fd, int *len) | ||
109 | { | ||
110 | int c, l = 0, p = 0; | ||
111 | |||
112 | byte *d, buf[512]; | ||
113 | d=malloc(32768); | ||
114 | for(;;) | ||
115 | { | ||
116 | c = read(fd, buf, sizeof buf); | ||
117 | if (c <= 0) break; | ||
118 | l += c; | ||
119 | memcpy(d+p, buf, c); | ||
120 | p += c; | ||
121 | } | ||
122 | setmallocpos(d+p+64); | ||
123 | *len = l; | ||
124 | return d; | ||
125 | } | ||
126 | |||
127 | //static byte sram[65536]; | ||
128 | |||
129 | int rom_load(void) | ||
130 | { | ||
131 | int fd; | ||
132 | byte c, *data, *header; | ||
133 | int len = 0, rlen; | ||
134 | |||
135 | fd = open(romfile, O_RDONLY); | ||
136 | |||
137 | if (fd<0) { | ||
138 | die("cannot open rom file"); | ||
139 | die(romfile); | ||
140 | return 1; | ||
141 | } | ||
142 | |||
143 | data = loadfile(fd, &len); | ||
144 | header = data; // no zip. = decompress(data, &len); | ||
145 | |||
146 | memcpy(rom.name, header+0x0134, 16); | ||
147 | if (rom.name[14] & 0x80) rom.name[14] = 0; | ||
148 | if (rom.name[15] & 0x80) rom.name[15] = 0; | ||
149 | rom.name[16] = 0; | ||
150 | |||
151 | c = header[0x0147]; | ||
152 | mbc.type = mbc_table[c]; | ||
153 | mbc.batt = (batt_table[c] && !nobatt) || forcebatt; | ||
154 | // mbc.batt = 1; // always store savegame mem. | ||
155 | rtc.batt = rtc_table[c]; | ||
156 | mbc.romsize = romsize_table[header[0x0148]]; | ||
157 | mbc.ramsize = ramsize_table[header[0x0149]]; | ||
158 | |||
159 | if (!mbc.romsize) { | ||
160 | die("unknown ROM size %02X\n", header[0x0148]); | ||
161 | return 1; | ||
162 | } | ||
163 | if (!mbc.ramsize) { | ||
164 | die("unknown SRAM size %02X\n", header[0x0149]); | ||
165 | return 1; | ||
166 | } | ||
167 | |||
168 | rlen = 16384 * mbc.romsize; | ||
169 | rom.bank = (void *) data; //realloc(data, rlen); | ||
170 | if (rlen > len) memset(rom.bank[0]+len, 0xff, rlen - len); | ||
171 | |||
172 | ram.sbank = malloc(8192 * mbc.ramsize); | ||
173 | //ram.ibank = malloc(4096*8); | ||
174 | |||
175 | initmem(ram.sbank, 8192 * mbc.ramsize); | ||
176 | initmem(ram.ibank, 4096 * 8); | ||
177 | |||
178 | mbc.rombank = 1; | ||
179 | mbc.rambank = 0; | ||
180 | |||
181 | c = header[0x0143]; | ||
182 | hw.cgb = ((c == 0x80) || (c == 0xc0)) && !forcedmg; | ||
183 | hw.gba = 0; //(hw.cgb && gbamode); | ||
184 | |||
185 | close(fd); | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | int sram_load(void) | ||
191 | { | ||
192 | int fd; | ||
193 | char meow[500]; | ||
194 | |||
195 | if (!mbc.batt || !sramfile || !*sramfile) return -1; | ||
196 | |||
197 | /* Consider sram loaded at this point, even if file doesn't exist */ | ||
198 | ram.loaded = 1; | ||
199 | |||
200 | fd = open(sramfile, O_RDONLY); | ||
201 | snprintf(meow,499,"Opening %s %d",sramfile,fd); | ||
202 | rb->splash(HZ*2, true, meow); | ||
203 | if (fd<0) return -1; | ||
204 | snprintf(meow,499,"Loading savedata from %s",sramfile); | ||
205 | rb->splash(HZ*2, true, meow); | ||
206 | read(fd,ram.sbank, 8192*mbc.ramsize); | ||
207 | close(fd); | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | |||
213 | int sram_save(void) | ||
214 | { | ||
215 | int fd; | ||
216 | char meow[500]; | ||
217 | |||
218 | /* If we crash before we ever loaded sram, DO NOT SAVE! */ | ||
219 | if (!mbc.batt || !sramfile || !ram.loaded || !mbc.ramsize) | ||
220 | return -1; | ||
221 | fd = open(sramfile, O_WRONLY|O_CREAT); | ||
222 | // snprintf(meow,499,"Opening %s %d",sramfile,fd); | ||
223 | // rb->splash(HZ*2, true, meow); | ||
224 | if (fd<0) return -1; | ||
225 | snprintf(meow,499,"Saving savedata to %s",sramfile); | ||
226 | rb->splash(HZ*2, true, meow); | ||
227 | write(fd,ram.sbank, 8192*mbc.ramsize); | ||
228 | close(fd); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | |||
234 | void state_save(int n) | ||
235 | { | ||
236 | int fd; | ||
237 | char name[500]; | ||
238 | |||
239 | if (n < 0) n = saveslot; | ||
240 | if (n < 0) n = 0; | ||
241 | snprintf(name, 499,"%s.%03d", saveprefix, n); | ||
242 | |||
243 | if ((fd = open(name, O_WRONLY|O_CREAT)>=0)) | ||
244 | { | ||
245 | savestate(fd); | ||
246 | close(fd); | ||
247 | } | ||
248 | } | ||
249 | |||
250 | |||
251 | void state_load(int n) | ||
252 | { | ||
253 | int fd; | ||
254 | char name[500]; | ||
255 | |||
256 | if (n < 0) n = saveslot; | ||
257 | if (n < 0) n = 0; | ||
258 | snprintf(name, 499, "%s.%03d", saveprefix, n); | ||
259 | |||
260 | if ((fd = open(name, O_RDONLY)>=0)) | ||
261 | { | ||
262 | loadstate(fd); | ||
263 | close(fd); | ||
264 | vram_dirty(); | ||
265 | pal_dirty(); | ||
266 | sound_dirty(); | ||
267 | mem_updatemap(); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | void rtc_save(void) | ||
272 | { | ||
273 | int fd; | ||
274 | if (!rtc.batt) return; | ||
275 | if ((fd = open(rtcfile, O_WRONLY|O_CREAT))<0) return; | ||
276 | rtc_save_internal(fd); | ||
277 | close(fd); | ||
278 | } | ||
279 | |||
280 | void rtc_load(void) | ||
281 | { | ||
282 | int fd; | ||
283 | if (!rtc.batt) return; | ||
284 | if ((fd = open(rtcfile, O_RDONLY))<0) return; | ||
285 | rtc_load_internal(fd); | ||
286 | close(fd); | ||
287 | } | ||
288 | |||
289 | |||
290 | void loader_unload(void) | ||
291 | { | ||
292 | sram_save(); | ||
293 | // if (romfile) free(romfile); | ||
294 | // if (sramfile) free(sramfile); | ||
295 | // if (saveprefix) free(saveprefix); | ||
296 | // if (rom.bank) free(rom.bank); | ||
297 | // if (ram.sbank) free(ram.sbank); | ||
298 | romfile = 0; | ||
299 | rom.bank = 0; | ||
300 | ram.sbank = 0; | ||
301 | mbc.type = mbc.romsize = mbc.ramsize = mbc.batt = 0; | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | static char *base(char *s) | ||
306 | { | ||
307 | char *p; | ||
308 | p = strrchr(s, '/'); | ||
309 | if (p) return p+1; | ||
310 | return s; | ||
311 | } | ||
312 | |||
313 | |||
314 | static char *ldup(char *s) | ||
315 | { | ||
316 | int i; | ||
317 | char *n, *p; | ||
318 | p = n = malloc(strlen(s)); | ||
319 | for (i = 0; s[i]; i++) if (isalnum(s[i])) *(p++) = tolower(s[i]); | ||
320 | *p = 0; | ||
321 | return n; | ||
322 | }*/ | ||
323 | |||
324 | void cleanup(void) | ||
325 | { | ||
326 | sram_save(); | ||
327 | rtc_save(); | ||
328 | // IDEA - if error, write emergency savestate..? | ||
329 | } | ||
330 | |||
331 | void loader_init(char *s) | ||
332 | { | ||
333 | char *name; | ||
334 | DIR* dir; | ||
335 | |||
336 | // sys_checkdir(savedir, 1); /* needs to be writable */ | ||
337 | dir=opendir(savedir); | ||
338 | if(!dir) | ||
339 | mkdir(savedir,0); | ||
340 | else | ||
341 | closedir(dir); | ||
342 | |||
343 | romfile = s; | ||
344 | if(rom_load()) | ||
345 | return; | ||
346 | vid_settitle(rom.name); | ||
347 | name = rom.name; | ||
348 | |||
349 | snprintf(saveprefix, 499, "%s/%s", savedir, name); | ||
350 | |||
351 | strcpy(sramfile, saveprefix); | ||
352 | strcat(sramfile, ".sav"); | ||
353 | |||
354 | strcpy(rtcfile, saveprefix); | ||
355 | strcat(rtcfile, ".rtc"); | ||
356 | |||
357 | sram_load(); | ||
358 | rtc_load(); | ||
359 | |||
360 | //atexit(cleanup); | ||
361 | } | ||
362 | |||
363 | rcvar_t loader_exports[] = | ||
364 | { | ||
365 | RCV_STRING("savedir", &savedir), | ||
366 | RCV_STRING("savename", &savename), | ||
367 | RCV_INT("saveslot", &saveslot), | ||
368 | RCV_BOOL("forcebatt", &forcebatt), | ||
369 | RCV_BOOL("nobatt", &nobatt), | ||
370 | RCV_BOOL("forcedmg", &forcedmg), | ||
371 | RCV_INT("memfill", &memfill), | ||
372 | RCV_INT("memrand", &memrand), | ||
373 | RCV_END | ||
374 | }; | ||
375 | |||
376 | |||
377 | |||
378 | |||
379 | |||
380 | |||
381 | |||
382 | |||
383 | |||
diff --git a/apps/plugins/rockboy/loader.h b/apps/plugins/rockboy/loader.h new file mode 100644 index 0000000000..45ee5e705d --- /dev/null +++ b/apps/plugins/rockboy/loader.h | |||
@@ -0,0 +1,28 @@ | |||
1 | |||
2 | |||
3 | #ifndef __LOADER_H__ | ||
4 | #define __LOADER_H__ | ||
5 | |||
6 | |||
7 | typedef struct loader_s | ||
8 | { | ||
9 | char *rom; | ||
10 | char *base; | ||
11 | char *sram; | ||
12 | char *state; | ||
13 | int ramloaded; | ||
14 | } loader_t; | ||
15 | |||
16 | |||
17 | extern loader_t loader; | ||
18 | |||
19 | |||
20 | int rom_load(void); | ||
21 | int sram_load(void); | ||
22 | int sram_save(void); | ||
23 | void loader_init(char *s); | ||
24 | void cleanup(void); | ||
25 | |||
26 | #endif | ||
27 | |||
28 | |||
diff --git a/apps/plugins/rockboy/main.c b/apps/plugins/rockboy/main.c new file mode 100644 index 0000000000..ea5d628f04 --- /dev/null +++ b/apps/plugins/rockboy/main.c | |||
@@ -0,0 +1,83 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <string.h> | ||
3 | |||
4 | #include "rockmacros.h" | ||
5 | #include "input.h" | ||
6 | #include "rc.h" | ||
7 | #include "exports.h" | ||
8 | #include "emu.h" | ||
9 | #include "loader.h" | ||
10 | #include "hw.h" | ||
11 | |||
12 | //#include "Version" | ||
13 | |||
14 | |||
15 | static char *defaultconfig[] = | ||
16 | { | ||
17 | "bind up +up", | ||
18 | "bind down +down", | ||
19 | "bind left +left", | ||
20 | "bind right +right", | ||
21 | "bind joy0 +b", | ||
22 | "bind joy1 +a", | ||
23 | "bind joy2 +select", | ||
24 | "bind joy3 +start", | ||
25 | "bind ins savestate", | ||
26 | "bind del loadstate", | ||
27 | NULL | ||
28 | }; | ||
29 | |||
30 | |||
31 | void doevents() | ||
32 | { | ||
33 | event_t ev; | ||
34 | int st; | ||
35 | |||
36 | ev_poll(); | ||
37 | while (ev_getevent(&ev)) | ||
38 | { | ||
39 | if (ev.type != EV_PRESS && ev.type != EV_RELEASE) | ||
40 | continue; | ||
41 | st = (ev.type != EV_RELEASE); | ||
42 | pad_set(ev.code, st); | ||
43 | } | ||
44 | } | ||
45 | |||
46 | |||
47 | |||
48 | int gnuboy_main(char *rom) | ||
49 | { | ||
50 | int i; | ||
51 | |||
52 | // Avoid initializing video if we don't have to | ||
53 | // If we have special perms, drop them ASAP! | ||
54 | rb->splash(HZ*1, true, "Init exports"); | ||
55 | init_exports(); | ||
56 | |||
57 | rb->splash(HZ*1, true, "Loading default config"); | ||
58 | for (i = 0; defaultconfig[i]; i++) | ||
59 | rc_command(defaultconfig[i]); | ||
60 | |||
61 | // sprintf(cmd, "source %s", rom); | ||
62 | // s = strchr(cmd, '.'); | ||
63 | // if (s) *s = 0; | ||
64 | // strcat(cmd, ".rc"); | ||
65 | // rc_command(cmd); | ||
66 | |||
67 | // FIXME - make interface modules responsible for atexit() | ||
68 | rb->splash(HZ*1, true, "Init video"); | ||
69 | vid_init(); | ||
70 | rb->splash(HZ*1, true, "Init sound (nosound)"); | ||
71 | pcm_init(); | ||
72 | rb->splash(HZ*1, true, "Loading rom"); | ||
73 | loader_init(rom); | ||
74 | if(shut) | ||
75 | return PLUGIN_ERROR; | ||
76 | rb->splash(HZ*1, true, "Emu reset"); | ||
77 | emu_reset(); | ||
78 | rb->splash(HZ*1, true, "Emu run"); | ||
79 | emu_run(); | ||
80 | |||
81 | // never reached | ||
82 | return PLUGIN_OK; | ||
83 | } | ||
diff --git a/apps/plugins/rockboy/mem.c b/apps/plugins/rockboy/mem.c new file mode 100644 index 0000000000..2e1e0e7154 --- /dev/null +++ b/apps/plugins/rockboy/mem.c | |||
@@ -0,0 +1,578 @@ | |||
1 | |||
2 | |||
3 | #include "rockmacros.h" | ||
4 | |||
5 | #include "defs.h" | ||
6 | #include "hw.h" | ||
7 | #include "regs.h" | ||
8 | #include "mem.h" | ||
9 | #include "rtc.h" | ||
10 | #include "lcd.h" | ||
11 | #include "lcdc.h" | ||
12 | #include "sound.h" | ||
13 | |||
14 | struct mbc mbc; | ||
15 | struct rom rom; | ||
16 | struct ram ram; | ||
17 | |||
18 | |||
19 | /* | ||
20 | * In order to make reads and writes efficient, we keep tables | ||
21 | * (indexed by the high nibble of the address) specifying which | ||
22 | * regions can be read/written without a function call. For such | ||
23 | * ranges, the pointer in the map table points to the base of the | ||
24 | * region in host system memory. For ranges that require special | ||
25 | * processing, the pointer is NULL. | ||
26 | * | ||
27 | * mem_updatemap is called whenever bank changes or other operations | ||
28 | * make the old maps potentially invalid. | ||
29 | */ | ||
30 | |||
31 | void mem_updatemap() | ||
32 | { | ||
33 | int n; | ||
34 | byte **map; | ||
35 | |||
36 | map = mbc.rmap; | ||
37 | map[0x0] = rom.bank[0]; | ||
38 | map[0x1] = rom.bank[0]; | ||
39 | map[0x2] = rom.bank[0]; | ||
40 | map[0x3] = rom.bank[0]; | ||
41 | if (mbc.rombank < mbc.romsize) | ||
42 | { | ||
43 | map[0x4] = rom.bank[mbc.rombank] - 0x4000; | ||
44 | map[0x5] = rom.bank[mbc.rombank] - 0x4000; | ||
45 | map[0x6] = rom.bank[mbc.rombank] - 0x4000; | ||
46 | map[0x7] = rom.bank[mbc.rombank] - 0x4000; | ||
47 | } | ||
48 | else map[0x4] = map[0x5] = map[0x6] = map[0x7] = NULL; | ||
49 | if (0 && (R_STAT & 0x03) == 0x03) | ||
50 | { | ||
51 | map[0x8] = NULL; | ||
52 | map[0x9] = NULL; | ||
53 | } | ||
54 | else | ||
55 | { | ||
56 | map[0x8] = lcd.vbank[R_VBK & 1] - 0x8000; | ||
57 | map[0x9] = lcd.vbank[R_VBK & 1] - 0x8000; | ||
58 | } | ||
59 | if (mbc.enableram && !(rtc.sel&8)) | ||
60 | { | ||
61 | map[0xA] = ram.sbank[mbc.rambank] - 0xA000; | ||
62 | map[0xB] = ram.sbank[mbc.rambank] - 0xA000; | ||
63 | } | ||
64 | else map[0xA] = map[0xB] = NULL; | ||
65 | map[0xC] = ram.ibank[0] - 0xC000; | ||
66 | n = R_SVBK & 0x07; | ||
67 | map[0xD] = ram.ibank[n?n:1] - 0xD000; | ||
68 | map[0xE] = ram.ibank[0] - 0xE000; | ||
69 | map[0xF] = NULL; | ||
70 | |||
71 | map = mbc.wmap; | ||
72 | map[0x0] = map[0x1] = map[0x2] = map[0x3] = NULL; | ||
73 | map[0x4] = map[0x5] = map[0x6] = map[0x7] = NULL; | ||
74 | map[0x8] = map[0x9] = NULL; | ||
75 | if (mbc.enableram && !(rtc.sel&8)) | ||
76 | { | ||
77 | map[0xA] = ram.sbank[mbc.rambank] - 0xA000; | ||
78 | map[0xB] = ram.sbank[mbc.rambank] - 0xA000; | ||
79 | } | ||
80 | else map[0xA] = map[0xB] = NULL; | ||
81 | map[0xC] = ram.ibank[0] - 0xC000; | ||
82 | n = R_SVBK & 0x07; | ||
83 | map[0xD] = ram.ibank[n?n:1] - 0xD000; | ||
84 | map[0xE] = ram.ibank[0] - 0xE000; | ||
85 | map[0xF] = NULL; | ||
86 | } | ||
87 | |||
88 | |||
89 | /* | ||
90 | * ioreg_write handles output to io registers in the FF00-FF7F,FFFF | ||
91 | * range. It takes the register number (low byte of the address) and a | ||
92 | * byte value to be written. | ||
93 | */ | ||
94 | |||
95 | void ioreg_write(byte r, byte b) | ||
96 | { | ||
97 | if (!hw.cgb) | ||
98 | { | ||
99 | |||
100 | switch (r) | ||
101 | { | ||
102 | case RI_VBK: | ||
103 | case RI_BCPS: | ||
104 | case RI_OCPS: | ||
105 | case RI_BCPD: | ||
106 | case RI_OCPD: | ||
107 | case RI_SVBK: | ||
108 | case RI_KEY1: | ||
109 | case RI_HDMA1: | ||
110 | case RI_HDMA2: | ||
111 | case RI_HDMA3: | ||
112 | case RI_HDMA4: | ||
113 | case RI_HDMA5: | ||
114 | return; | ||
115 | } | ||
116 | } | ||
117 | switch(r) | ||
118 | { | ||
119 | case RI_TIMA: | ||
120 | case RI_TMA: | ||
121 | case RI_TAC: | ||
122 | case RI_SCY: | ||
123 | case RI_SCX: | ||
124 | case RI_WY: | ||
125 | case RI_WX: | ||
126 | REG(r) = b; | ||
127 | break; | ||
128 | case RI_BGP: | ||
129 | if (R_BGP == b) break; | ||
130 | pal_write_dmg(0, 0, b); | ||
131 | pal_write_dmg(8, 1, b); | ||
132 | R_BGP = b; | ||
133 | break; | ||
134 | case RI_OBP0: | ||
135 | if (R_OBP0 == b) break; | ||
136 | pal_write_dmg(64, 2, b); | ||
137 | R_OBP0 = b; | ||
138 | break; | ||
139 | case RI_OBP1: | ||
140 | if (R_OBP1 == b) break; | ||
141 | pal_write_dmg(72, 3, b); | ||
142 | R_OBP1 = b; | ||
143 | break; | ||
144 | case RI_IF: | ||
145 | case RI_IE: | ||
146 | REG(r) = b & 0x1F; | ||
147 | break; | ||
148 | case RI_P1: | ||
149 | REG(r) = b; | ||
150 | pad_refresh(); | ||
151 | break; | ||
152 | case RI_SC: | ||
153 | /* FIXME - this is a hack for stupid roms that probe serial */ | ||
154 | if ((b & 0x81) == 0x81) | ||
155 | { | ||
156 | R_SB = 0xff; | ||
157 | hw_interrupt(IF_SERIAL, IF_SERIAL); | ||
158 | hw_interrupt(0, IF_SERIAL); | ||
159 | } | ||
160 | R_SC = b; /* & 0x7f; */ | ||
161 | break; | ||
162 | case RI_DIV: | ||
163 | REG(r) = 0; | ||
164 | break; | ||
165 | case RI_LCDC: | ||
166 | lcdc_change(b); | ||
167 | break; | ||
168 | case RI_STAT: | ||
169 | stat_write(b); | ||
170 | break; | ||
171 | case RI_LYC: | ||
172 | REG(r) = b; | ||
173 | stat_trigger(); | ||
174 | break; | ||
175 | case RI_VBK: | ||
176 | REG(r) = b | 0xFE; | ||
177 | mem_updatemap(); | ||
178 | break; | ||
179 | case RI_BCPS: | ||
180 | R_BCPS = b & 0xBF; | ||
181 | R_BCPD = lcd.pal[b & 0x3F]; | ||
182 | break; | ||
183 | case RI_OCPS: | ||
184 | R_OCPS = b & 0xBF; | ||
185 | R_OCPD = lcd.pal[64 + (b & 0x3F)]; | ||
186 | break; | ||
187 | case RI_BCPD: | ||
188 | R_BCPD = b; | ||
189 | pal_write(R_BCPS & 0x3F, b); | ||
190 | if (R_BCPS & 0x80) R_BCPS = (R_BCPS+1) & 0xBF; | ||
191 | break; | ||
192 | case RI_OCPD: | ||
193 | R_OCPD = b; | ||
194 | pal_write(64 + (R_OCPS & 0x3F), b); | ||
195 | if (R_OCPS & 0x80) R_OCPS = (R_OCPS+1) & 0xBF; | ||
196 | break; | ||
197 | case RI_SVBK: | ||
198 | REG(r) = b & 0x07; | ||
199 | mem_updatemap(); | ||
200 | break; | ||
201 | case RI_DMA: | ||
202 | hw_dma(b); | ||
203 | break; | ||
204 | case RI_KEY1: | ||
205 | REG(r) = (REG(r) & 0x80) | (b & 0x01); | ||
206 | break; | ||
207 | case RI_HDMA1: | ||
208 | REG(r) = b; | ||
209 | break; | ||
210 | case RI_HDMA2: | ||
211 | REG(r) = b & 0xF0; | ||
212 | break; | ||
213 | case RI_HDMA3: | ||
214 | REG(r) = b & 0x1F; | ||
215 | break; | ||
216 | case RI_HDMA4: | ||
217 | REG(r) = b & 0xF0; | ||
218 | break; | ||
219 | case RI_HDMA5: | ||
220 | hw_hdma_cmd(b); | ||
221 | break; | ||
222 | } | ||
223 | switch (r) | ||
224 | { | ||
225 | case RI_BGP: | ||
226 | case RI_OBP0: | ||
227 | case RI_OBP1: | ||
228 | /* printf("palette reg %02X write %02X at LY=%02X\n", r, b, R_LY); */ | ||
229 | case RI_HDMA1: | ||
230 | case RI_HDMA2: | ||
231 | case RI_HDMA3: | ||
232 | case RI_HDMA4: | ||
233 | case RI_HDMA5: | ||
234 | /* printf("HDMA %d: %02X\n", r - RI_HDMA1 + 1, b); */ | ||
235 | break; | ||
236 | } | ||
237 | /* printf("reg %02X => %02X (%02X)\n", r, REG(r), b); */ | ||
238 | } | ||
239 | |||
240 | |||
241 | byte ioreg_read(byte r) | ||
242 | { | ||
243 | switch(r) | ||
244 | { | ||
245 | case RI_SC: | ||
246 | r = R_SC; | ||
247 | R_SC &= 0x7f; | ||
248 | return r; | ||
249 | case RI_P1: | ||
250 | case RI_SB: | ||
251 | case RI_DIV: | ||
252 | case RI_TIMA: | ||
253 | case RI_TMA: | ||
254 | case RI_TAC: | ||
255 | case RI_LCDC: | ||
256 | case RI_STAT: | ||
257 | case RI_SCY: | ||
258 | case RI_SCX: | ||
259 | case RI_LY: | ||
260 | case RI_LYC: | ||
261 | case RI_BGP: | ||
262 | case RI_OBP0: | ||
263 | case RI_OBP1: | ||
264 | case RI_WY: | ||
265 | case RI_WX: | ||
266 | case RI_IE: | ||
267 | case RI_IF: | ||
268 | return REG(r); | ||
269 | case RI_VBK: | ||
270 | case RI_BCPS: | ||
271 | case RI_OCPS: | ||
272 | case RI_BCPD: | ||
273 | case RI_OCPD: | ||
274 | case RI_SVBK: | ||
275 | case RI_KEY1: | ||
276 | case RI_HDMA1: | ||
277 | case RI_HDMA2: | ||
278 | case RI_HDMA3: | ||
279 | case RI_HDMA4: | ||
280 | case RI_HDMA5: | ||
281 | if (hw.cgb) return REG(r); | ||
282 | default: | ||
283 | return 0xff; | ||
284 | } | ||
285 | } | ||
286 | |||
287 | |||
288 | |||
289 | /* | ||
290 | * Memory bank controllers typically intercept write attempts to | ||
291 | * 0000-7FFF, using the address and byte written as instructions to | ||
292 | * change rom or sram banks, control special hardware, etc. | ||
293 | * | ||
294 | * mbc_write takes an address (which should be in the proper range) | ||
295 | * and a byte value written to the address. | ||
296 | */ | ||
297 | |||
298 | void mbc_write(int a, byte b) | ||
299 | { | ||
300 | byte ha = (a>>12); | ||
301 | |||
302 | /* printf("mbc %d: rom bank %02X -[%04X:%02X]-> ", mbc.type, mbc.rombank, a, b); */ | ||
303 | switch (mbc.type) | ||
304 | { | ||
305 | case MBC_MBC1: | ||
306 | switch (ha & 0xE) | ||
307 | { | ||
308 | case 0x0: | ||
309 | mbc.enableram = ((b & 0x0F) == 0x0A); | ||
310 | break; | ||
311 | case 0x2: | ||
312 | if ((b & 0x1F) == 0) b = 0x01; | ||
313 | mbc.rombank = (mbc.rombank & 0x60) | (b & 0x1F); | ||
314 | break; | ||
315 | case 0x4: | ||
316 | if (mbc.model) | ||
317 | { | ||
318 | mbc.rambank = b & 0x03; | ||
319 | break; | ||
320 | } | ||
321 | mbc.rombank = (mbc.rombank & 0x1F) | ((int)(b&3)<<5); | ||
322 | break; | ||
323 | case 0x6: | ||
324 | mbc.model = b & 0x1; | ||
325 | break; | ||
326 | } | ||
327 | break; | ||
328 | case MBC_MBC2: /* is this at all right? */ | ||
329 | if ((a & 0x0100) == 0x0000) | ||
330 | { | ||
331 | mbc.enableram = ((b & 0x0F) == 0x0A); | ||
332 | break; | ||
333 | } | ||
334 | if ((a & 0xE100) == 0x2100) | ||
335 | { | ||
336 | mbc.rombank = b & 0x0F; | ||
337 | break; | ||
338 | } | ||
339 | break; | ||
340 | case MBC_MBC3: | ||
341 | switch (ha & 0xE) | ||
342 | { | ||
343 | case 0x0: | ||
344 | mbc.enableram = ((b & 0x0F) == 0x0A); | ||
345 | break; | ||
346 | case 0x2: | ||
347 | if ((b & 0x7F) == 0) b = 0x01; | ||
348 | mbc.rombank = b & 0x7F; | ||
349 | break; | ||
350 | case 0x4: | ||
351 | rtc.sel = b & 0x0f; | ||
352 | mbc.rambank = b & 0x03; | ||
353 | break; | ||
354 | case 0x6: | ||
355 | rtc_latch(b); | ||
356 | break; | ||
357 | } | ||
358 | break; | ||
359 | case MBC_RUMBLE: | ||
360 | switch (ha & 0xF) | ||
361 | { | ||
362 | case 0x4: | ||
363 | case 0x5: | ||
364 | /* FIXME - save high bit as rumble state */ | ||
365 | /* mask off high bit */ | ||
366 | b &= 0x7; | ||
367 | break; | ||
368 | } | ||
369 | /* fall thru */ | ||
370 | case MBC_MBC5: | ||
371 | switch (ha & 0xF) | ||
372 | { | ||
373 | case 0x0: | ||
374 | case 0x1: | ||
375 | mbc.enableram = ((b & 0x0F) == 0x0A); | ||
376 | break; | ||
377 | case 0x2: | ||
378 | if ((b & 0xFF) == 0) b = 0x01; | ||
379 | mbc.rombank = (mbc.rombank & 0x100) | (b & 0xFF); | ||
380 | break; | ||
381 | case 0x3: | ||
382 | mbc.rombank = (mbc.rombank & 0xFF) | ((int)(b&1)<<8); | ||
383 | break; | ||
384 | case 0x4: | ||
385 | case 0x5: | ||
386 | mbc.rambank = b & 0x0f; | ||
387 | break; | ||
388 | } | ||
389 | break; | ||
390 | case MBC_HUC1: /* FIXME - this is all guesswork -- is it right??? */ | ||
391 | switch (ha & 0xE) | ||
392 | { | ||
393 | case 0x0: | ||
394 | mbc.enableram = ((b & 0x0F) == 0x0A); | ||
395 | break; | ||
396 | case 0x2: | ||
397 | if ((b & 0x1F) == 0) b = 0x01; | ||
398 | mbc.rombank = (mbc.rombank & 0x60) | (b & 0x1F); | ||
399 | break; | ||
400 | case 0x4: | ||
401 | if (mbc.model) | ||
402 | { | ||
403 | mbc.rambank = b & 0x03; | ||
404 | break; | ||
405 | } | ||
406 | mbc.rombank = (mbc.rombank & 0x1F) | ((int)(b&3)<<5); | ||
407 | break; | ||
408 | case 0x6: | ||
409 | mbc.model = b & 0x1; | ||
410 | break; | ||
411 | } | ||
412 | break; | ||
413 | case MBC_HUC3: | ||
414 | switch (ha & 0xE) | ||
415 | { | ||
416 | case 0x0: | ||
417 | mbc.enableram = ((b & 0x0F) == 0x0A); | ||
418 | break; | ||
419 | case 0x2: | ||
420 | b &= 0x7F; | ||
421 | mbc.rombank = b ? b : 1; | ||
422 | break; | ||
423 | case 0x4: | ||
424 | rtc.sel = b & 0x0f; | ||
425 | mbc.rambank = b & 0x03; | ||
426 | break; | ||
427 | case 0x6: | ||
428 | rtc_latch(b); | ||
429 | break; | ||
430 | } | ||
431 | break; | ||
432 | } | ||
433 | mbc.rombank &= (mbc.romsize - 1); | ||
434 | mbc.rambank &= (mbc.ramsize - 1); | ||
435 | /* printf("%02X\n", mbc.rombank); */ | ||
436 | mem_updatemap(); | ||
437 | } | ||
438 | |||
439 | |||
440 | /* | ||
441 | * mem_write is the basic write function. Although it should only be | ||
442 | * called when the write map contains a NULL for the requested address | ||
443 | * region, it accepts writes to any address. | ||
444 | */ | ||
445 | |||
446 | void mem_write(int a, byte b) | ||
447 | { | ||
448 | int n; | ||
449 | byte ha = (a>>12) & 0xE; | ||
450 | |||
451 | /* printf("write to 0x%04X: 0x%02X\n", a, b); */ | ||
452 | switch (ha) | ||
453 | { | ||
454 | case 0x0: | ||
455 | case 0x2: | ||
456 | case 0x4: | ||
457 | case 0x6: | ||
458 | mbc_write(a, b); | ||
459 | break; | ||
460 | case 0x8: | ||
461 | /* if ((R_STAT & 0x03) == 0x03) break; */ | ||
462 | vram_write(a & 0x1FFF, b); | ||
463 | break; | ||
464 | case 0xA: | ||
465 | if (!mbc.enableram) break; | ||
466 | if (rtc.sel&8) | ||
467 | { | ||
468 | rtc_write(b); | ||
469 | break; | ||
470 | } | ||
471 | ram.sbank[mbc.rambank][a & 0x1FFF] = b; | ||
472 | break; | ||
473 | case 0xC: | ||
474 | if ((a & 0xF000) == 0xC000) | ||
475 | { | ||
476 | ram.ibank[0][a & 0x0FFF] = b; | ||
477 | break; | ||
478 | } | ||
479 | n = R_SVBK & 0x07; | ||
480 | ram.ibank[n?n:1][a & 0x0FFF] = b; | ||
481 | break; | ||
482 | case 0xE: | ||
483 | if (a < 0xFE00) | ||
484 | { | ||
485 | mem_write(a & 0xDFFF, b); | ||
486 | break; | ||
487 | } | ||
488 | if ((a & 0xFF00) == 0xFE00) | ||
489 | { | ||
490 | /* if (R_STAT & 0x02) break; */ | ||
491 | if (a < 0xFEA0) lcd.oam.mem[a & 0xFF] = b; | ||
492 | break; | ||
493 | } | ||
494 | /* return writehi(a & 0xFF, b); */ | ||
495 | if (a >= 0xFF10 && a <= 0xFF3F) | ||
496 | { | ||
497 | sound_write(a & 0xFF, b); | ||
498 | break; | ||
499 | } | ||
500 | if ((a & 0xFF80) == 0xFF80 && a != 0xFFFF) | ||
501 | { | ||
502 | ram.hi[a & 0xFF] = b; | ||
503 | break; | ||
504 | } | ||
505 | ioreg_write(a & 0xFF, b); | ||
506 | } | ||
507 | } | ||
508 | |||
509 | |||
510 | /* | ||
511 | * mem_read is the basic read function...not useful for much anymore | ||
512 | * with the read map, but it's still necessary for the final messy | ||
513 | * region. | ||
514 | */ | ||
515 | |||
516 | byte mem_read(int a) | ||
517 | { | ||
518 | int n; | ||
519 | byte ha = (a>>12) & 0xE; | ||
520 | |||
521 | /* printf("read %04x\n", a); */ | ||
522 | switch (ha) | ||
523 | { | ||
524 | case 0x0: | ||
525 | case 0x2: | ||
526 | return rom.bank[0][a]; | ||
527 | case 0x4: | ||
528 | case 0x6: | ||
529 | return rom.bank[mbc.rombank][a & 0x3FFF]; | ||
530 | case 0x8: | ||
531 | /* if ((R_STAT & 0x03) == 0x03) return 0xFF; */ | ||
532 | return lcd.vbank[R_VBK&1][a & 0x1FFF]; | ||
533 | case 0xA: | ||
534 | if (!mbc.enableram && mbc.type == MBC_HUC3) | ||
535 | return 0x01; | ||
536 | if (!mbc.enableram) | ||
537 | return 0xFF; | ||
538 | if (rtc.sel&8) | ||
539 | return rtc.regs[rtc.sel&7]; | ||
540 | return ram.sbank[mbc.rambank][a & 0x1FFF]; | ||
541 | case 0xC: | ||
542 | if ((a & 0xF000) == 0xC000) | ||
543 | return ram.ibank[0][a & 0x0FFF]; | ||
544 | n = R_SVBK & 0x07; | ||
545 | return ram.ibank[n?n:1][a & 0x0FFF]; | ||
546 | case 0xE: | ||
547 | if (a < 0xFE00) return mem_read(a & 0xDFFF); | ||
548 | if ((a & 0xFF00) == 0xFE00) | ||
549 | { | ||
550 | /* if (R_STAT & 0x02) return 0xFF; */ | ||
551 | if (a < 0xFEA0) return lcd.oam.mem[a & 0xFF]; | ||
552 | return 0xFF; | ||
553 | } | ||
554 | /* return readhi(a & 0xFF); */ | ||
555 | if (a == 0xFFFF) return REG(0xFF); | ||
556 | if (a >= 0xFF10 && a <= 0xFF3F) | ||
557 | return sound_read(a & 0xFF); | ||
558 | if ((a & 0xFF80) == 0xFF80) | ||
559 | return ram.hi[a & 0xFF]; | ||
560 | return ioreg_read(a & 0xFF); | ||
561 | } | ||
562 | return 0xff; /* not reached */ | ||
563 | } | ||
564 | |||
565 | void mbc_reset(void) | ||
566 | { | ||
567 | mbc.rombank = 1; | ||
568 | mbc.rambank = 0; | ||
569 | mbc.enableram = 0; | ||
570 | mem_updatemap(); | ||
571 | } | ||
572 | |||
573 | |||
574 | |||
575 | |||
576 | |||
577 | |||
578 | |||
diff --git a/apps/plugins/rockboy/mem.h b/apps/plugins/rockboy/mem.h new file mode 100644 index 0000000000..7926e2eda9 --- /dev/null +++ b/apps/plugins/rockboy/mem.h | |||
@@ -0,0 +1,80 @@ | |||
1 | |||
2 | #ifndef __MEM_H__ | ||
3 | #define __MEM_H__ | ||
4 | |||
5 | |||
6 | #include "defs.h" | ||
7 | |||
8 | |||
9 | |||
10 | #define MBC_NONE 0 | ||
11 | #define MBC_MBC1 1 | ||
12 | #define MBC_MBC2 2 | ||
13 | #define MBC_MBC3 3 | ||
14 | #define MBC_MBC5 5 | ||
15 | #define MBC_RUMBLE 15 | ||
16 | #define MBC_HUC1 0xC1 | ||
17 | #define MBC_HUC3 0xC3 | ||
18 | |||
19 | struct mbc | ||
20 | { | ||
21 | int type; | ||
22 | int model; | ||
23 | int rombank; | ||
24 | int rambank; | ||
25 | int romsize; | ||
26 | int ramsize; | ||
27 | int enableram; | ||
28 | int batt; | ||
29 | byte *rmap[0x10], *wmap[0x10]; | ||
30 | }; | ||
31 | |||
32 | struct rom | ||
33 | { | ||
34 | byte (*bank)[16384]; | ||
35 | char name[20]; | ||
36 | }; | ||
37 | |||
38 | struct ram | ||
39 | { | ||
40 | byte hi[256]; | ||
41 | byte ibank[8][4096]; | ||
42 | byte (*sbank)[8192]; | ||
43 | int loaded; | ||
44 | }; | ||
45 | |||
46 | |||
47 | extern struct mbc mbc; | ||
48 | extern struct rom rom; | ||
49 | extern struct ram ram; | ||
50 | |||
51 | |||
52 | |||
53 | |||
54 | |||
55 | void mem_updatemap(void); | ||
56 | void ioreg_write(byte r, byte b); | ||
57 | void mbc_write(int a, byte b); | ||
58 | void mem_write(int a, byte b); | ||
59 | byte mem_read(int a); | ||
60 | void mbc_reset(void); | ||
61 | |||
62 | |||
63 | |||
64 | #define READB(a) ( mbc.rmap[(a)>>12] \ | ||
65 | ? mbc.rmap[(a)>>12][(a)] \ | ||
66 | : mem_read((a)) ) | ||
67 | #define READW(a) ( READB((a)) | ((word)READB((a)+1)<<8) ) | ||
68 | |||
69 | #define WRITEB(a, b) ( mbc.wmap[(a)>>12] \ | ||
70 | ? ( mbc.wmap[(a)>>12][(a)] = (b) ) \ | ||
71 | : ( mem_write((a), (b)), (b) ) ) | ||
72 | #define WRITEW(a, w) ( WRITEB((a), (w)&0xFF), WRITEB((a)+1, (w)>>8) ) | ||
73 | |||
74 | |||
75 | |||
76 | |||
77 | #endif | ||
78 | |||
79 | |||
80 | |||
diff --git a/apps/plugins/rockboy/noise.h b/apps/plugins/rockboy/noise.h new file mode 100644 index 0000000000..037499eef3 --- /dev/null +++ b/apps/plugins/rockboy/noise.h | |||
@@ -0,0 +1,532 @@ | |||
1 | |||
2 | #ifndef __NOISE_H__ | ||
3 | #define __NOISE_H__ | ||
4 | |||
5 | |||
6 | #include "defs.h" | ||
7 | |||
8 | static byte noise7[] = | ||
9 | { | ||
10 | 0xfd,0xf3,0xd7,0x0d,0xd3,0x15,0x82,0xf1, | ||
11 | 0xdb,0x25,0x21,0x39,0x68,0x8c,0xd5,0x00, | ||
12 | }; | ||
13 | |||
14 | static byte noise15[] = | ||
15 | { | ||
16 | 0xff,0xfd,0xff,0xf3,0xff,0xd7,0xff,0x0f, | ||
17 | 0xfd,0xdf,0xf3,0x3f,0xd5,0x7f,0x00,0xfd, | ||
18 | 0xfd,0xf3,0xf3,0xd7,0xd7,0x0f,0x0d,0xdd, | ||
19 | 0xd3,0x33,0x15,0x55,0x80,0x02,0xff,0xf1, | ||
20 | 0xff,0xdb,0xff,0x27,0xfd,0x2f,0xf1,0x1f, | ||
21 | 0xd9,0xbf,0x2a,0x7d,0x02,0xf1,0xf1,0xdb, | ||
22 | 0xdb,0x27,0x25,0x2d,0x21,0x11,0x39,0x99, | ||
23 | 0x6a,0xa8,0x80,0x0c,0xff,0xd5,0xff,0x03, | ||
24 | 0xfd,0xf7,0xf3,0xcf,0xd7,0x5f,0x0c,0x3d, | ||
25 | 0xd7,0x73,0x0c,0xd5,0xd5,0x03,0x01,0xf5, | ||
26 | 0xfb,0xc3,0xe7,0x77,0xac,0xce,0x15,0x5b, | ||
27 | 0x80,0x26,0xff,0x29,0xfd,0x0b,0xf1,0xc7, | ||
28 | 0xdb,0x6f,0x24,0x9d,0x24,0xb1,0x24,0x59, | ||
29 | 0x26,0x29,0x2b,0x09,0x05,0xc9,0xe3,0x4b, | ||
30 | 0xb4,0x46,0x46,0x6a,0x6a,0x82,0x80,0xf0, | ||
31 | 0xfd,0xdd,0xf3,0x33,0xd5,0x57,0x00,0x0d, | ||
32 | 0xff,0xd3,0xff,0x17,0xfd,0x8f,0xf2,0xdf, | ||
33 | 0xd1,0x3f,0x19,0x7d,0xa8,0xf2,0x0d,0xd3, | ||
34 | 0xd3,0x17,0x15,0x8d,0x82,0xd2,0xf1,0x11, | ||
35 | 0xd9,0x9b,0x2a,0xa5,0x00,0x21,0xff,0x3b, | ||
36 | 0xfd,0x67,0xf0,0xaf,0xdc,0x1f,0x37,0xbd, | ||
37 | 0x4e,0x70,0x5a,0xde,0x21,0x3b,0x39,0x65, | ||
38 | 0x68,0xa0,0x8c,0x3c,0xd7,0x75,0x0c,0xc1, | ||
39 | 0xd5,0x7b,0x00,0xe5,0xfd,0xa3,0xf2,0x37, | ||
40 | 0xd3,0x4f,0x14,0x5d,0x86,0x32,0xeb,0x51, | ||
41 | 0x84,0x1a,0xe7,0xa1,0xae,0x3a,0x1b,0x63, | ||
42 | 0xa4,0xb6,0x24,0x4b,0x26,0x45,0x2a,0x61, | ||
43 | 0x02,0xb9,0xf0,0x6b,0xde,0x87,0x38,0xed, | ||
44 | 0x6d,0x90,0x92,0x9c,0x90,0xb4,0x9c,0x44, | ||
45 | 0xb6,0x64,0x4a,0xa6,0x40,0x2a,0x7f,0x02, | ||
46 | 0xfd,0xf1,0xf3,0xdb,0xd7,0x27,0x0d,0x2d, | ||
47 | 0xd1,0x13,0x19,0x95,0xaa,0x82,0x00,0xf3, | ||
48 | 0xfd,0xd7,0xf3,0x0f,0xd5,0xdf,0x03,0x3d, | ||
49 | 0xf5,0x73,0xc0,0xd7,0x7d,0x0c,0xf1,0xd5, | ||
50 | 0xdb,0x03,0x25,0xf5,0x23,0xc1,0x37,0x79, | ||
51 | 0x4c,0xe8,0x55,0x8e,0x02,0xdb,0xf1,0x27, | ||
52 | 0xd9,0x2f,0x29,0x1d,0x09,0xb1,0xca,0x5b, | ||
53 | 0x42,0x24,0x73,0x26,0xd5,0x29,0x01,0x09, | ||
54 | 0xf9,0xcb,0xeb,0x47,0x84,0x6e,0xe6,0x99, | ||
55 | 0xa8,0xaa,0x0c,0x03,0xd7,0xf7,0x0f,0xcd, | ||
56 | 0xdf,0x53,0x3c,0x15,0x77,0x80,0xce,0xfd, | ||
57 | 0x59,0xf0,0x2b,0xdf,0x07,0x3d,0xed,0x73, | ||
58 | 0x90,0xd6,0x9d,0x08,0xb1,0xcc,0x5b,0x56, | ||
59 | 0x24,0x0b,0x27,0xc5,0x2f,0x61,0x1c,0xb9, | ||
60 | 0xb4,0x6a,0x46,0x82,0x68,0xf2,0x8d,0xd0, | ||
61 | 0xd3,0x1d,0x15,0xb1,0x82,0x5a,0xf2,0x21, | ||
62 | 0xd3,0x3b,0x15,0x65,0x80,0xa2,0xfc,0x31, | ||
63 | 0xf7,0x5b,0xcc,0x27,0x57,0x2c,0x0d,0x17, | ||
64 | 0xd1,0x8f,0x1a,0xdd,0xa1,0x32,0x39,0x53, | ||
65 | 0x68,0x14,0x8f,0x84,0xde,0xe5,0x39,0xa1, | ||
66 | 0x6a,0x38,0x83,0x6c,0xf4,0x95,0xc4,0x83, | ||
67 | 0x64,0xf4,0xa5,0xc4,0x23,0x67,0x34,0xad, | ||
68 | 0x44,0x10,0x67,0x9e,0xae,0xb8,0x18,0x6f, | ||
69 | 0xae,0x9e,0x18,0xbb,0xac,0x66,0x16,0xab, | ||
70 | 0x88,0x06,0xcf,0xe9,0x5f,0x88,0x3e,0xcf, | ||
71 | 0x79,0x5c,0xe8,0x35,0x8f,0x42,0xdc,0x71, | ||
72 | 0x36,0xd9,0x49,0x28,0x49,0x0e,0x49,0xda, | ||
73 | 0x4b,0x22,0x45,0x32,0x61,0x52,0xb8,0x10, | ||
74 | 0x6f,0x9e,0x9e,0xb8,0xb8,0x6c,0x6e,0x96, | ||
75 | 0x98,0x88,0xac,0xcc,0x15,0x57,0x80,0x0e, | ||
76 | 0xff,0xd9,0xff,0x2b,0xfd,0x07,0xf1,0xef, | ||
77 | 0xdb,0x9f,0x26,0xbd,0x28,0x71,0x0e,0xd9, | ||
78 | 0xd9,0x2b,0x29,0x05,0x09,0xe1,0xcb,0xbb, | ||
79 | 0x46,0x64,0x6a,0xa6,0x80,0x28,0xff,0x0d, | ||
80 | 0xfd,0xd3,0xf3,0x17,0xd5,0x8f,0x02,0xdd, | ||
81 | 0xf1,0x33,0xd9,0x57,0x28,0x0d,0x0f,0xd1, | ||
82 | 0xdf,0x1b,0x3d,0xa5,0x72,0x20,0xd3,0x3d, | ||
83 | 0x15,0x71,0x80,0xda,0xfd,0x21,0xf1,0x3b, | ||
84 | 0xd9,0x67,0x28,0xad,0x0c,0x11,0xd7,0x9b, | ||
85 | 0x0e,0xa5,0xd8,0x23,0x2f,0x35,0x1d,0x41, | ||
86 | 0xb0,0x7a,0x5e,0xe2,0x39,0xb3,0x6a,0x54, | ||
87 | 0x82,0x04,0xf3,0xe5,0xd7,0xa3,0x0e,0x35, | ||
88 | 0xdb,0x43,0x24,0x75,0x26,0xc1,0x29,0x79, | ||
89 | 0x08,0xe9,0xcd,0x8b,0x52,0xc4,0x11,0x67, | ||
90 | 0x98,0xae,0xac,0x18,0x17,0xaf,0x8e,0x1e, | ||
91 | 0xdb,0xb9,0x26,0x69,0x2a,0x89,0x00,0xc9, | ||
92 | 0xfd,0x4b,0xf0,0x47,0xde,0x6f,0x3a,0x9d, | ||
93 | 0x60,0xb0,0xbc,0x5c,0x76,0x36,0xcb,0x49, | ||
94 | 0x44,0x48,0x66,0x4e,0xaa,0x58,0x02,0x2f, | ||
95 | 0xf3,0x1f,0xd5,0xbf,0x02,0x7d,0xf2,0xf3, | ||
96 | 0xd1,0xd7,0x1b,0x0d,0xa5,0xd2,0x23,0x13, | ||
97 | 0x35,0x95,0x42,0x80,0x70,0xfe,0xdd,0xf9, | ||
98 | 0x33,0xe9,0x57,0x88,0x0e,0xcf,0xd9,0x5f, | ||
99 | 0x28,0x3d,0x0f,0x71,0xdc,0xdb,0x35,0x25, | ||
100 | 0x41,0x20,0x79,0x3e,0xe9,0x79,0x88,0xea, | ||
101 | 0xcd,0x81,0x52,0xf8,0x11,0xef,0x9b,0x9e, | ||
102 | 0xa6,0xb8,0x28,0x6f,0x0e,0x9d,0xd8,0xb3, | ||
103 | 0x2c,0x55,0x16,0x01,0x8b,0xfa,0xc7,0xe1, | ||
104 | 0x6f,0xb8,0x9e,0x6c,0xba,0x94,0x60,0x86, | ||
105 | 0xbc,0xe8,0x75,0x8e,0xc2,0xd9,0x71,0x28, | ||
106 | 0xd9,0x0d,0x29,0xd1,0x0b,0x19,0xc5,0xab, | ||
107 | 0x62,0x04,0xb3,0xe4,0x57,0xa6,0x0e,0x2b, | ||
108 | 0xdb,0x07,0x25,0xed,0x23,0x91,0x36,0x99, | ||
109 | 0x48,0xa8,0x4c,0x0e,0x57,0xda,0x0f,0x23, | ||
110 | 0xdd,0x37,0x31,0x4d,0x58,0x50,0x2e,0x1f, | ||
111 | 0x1b,0xbd,0xa6,0x72,0x2a,0xd3,0x01,0x15, | ||
112 | 0xf9,0x83,0xea,0xf7,0x81,0xce,0xfb,0x59, | ||
113 | 0xe4,0x2b,0xa7,0x06,0x2d,0xeb,0x13,0x85, | ||
114 | 0x96,0xe2,0x89,0xb0,0xca,0x5d,0x42,0x30, | ||
115 | 0x73,0x5e,0xd4,0x39,0x07,0x69,0xec,0x8b, | ||
116 | 0x94,0xc6,0x85,0x68,0xe0,0x8d,0xbc,0xd2, | ||
117 | 0x75,0x12,0xc1,0x91,0x7a,0x98,0xe0,0xad, | ||
118 | 0xbc,0x12,0x77,0x92,0xce,0x91,0x58,0x98, | ||
119 | 0x2c,0xaf,0x14,0x1d,0x87,0xb2,0xee,0x51, | ||
120 | 0x9a,0x1a,0xa3,0xa0,0x36,0x3f,0x4b,0x7c, | ||
121 | 0x44,0xf6,0x65,0xca,0xa3,0x40,0x34,0x7f, | ||
122 | 0x46,0xfc,0x69,0xf6,0x8b,0xc8,0xc7,0x4d, | ||
123 | 0x6c,0x50,0x96,0x1c,0x8b,0xb4,0xc6,0x45, | ||
124 | 0x6a,0x60,0x82,0xbc,0xf0,0x75,0xde,0xc3, | ||
125 | 0x39,0x75,0x68,0xc0,0x8d,0x7c,0xd0,0xf5, | ||
126 | 0x1d,0xc1,0xb3,0x7a,0x54,0xe2,0x05,0xb3, | ||
127 | 0xe2,0x57,0xb2,0x0e,0x53,0xda,0x17,0x23, | ||
128 | 0x8d,0x36,0xd1,0x49,0x18,0x49,0xae,0x4a, | ||
129 | 0x1a,0x43,0xa2,0x76,0x32,0xcb,0x51,0x44, | ||
130 | 0x18,0x67,0xae,0xae,0x18,0x1b,0xaf,0xa6, | ||
131 | 0x1e,0x2b,0xbb,0x06,0x65,0xea,0xa3,0x80, | ||
132 | 0x36,0xff,0x49,0xfc,0x4b,0xf6,0x47,0xca, | ||
133 | 0x6f,0x42,0x9c,0x70,0xb6,0xdc,0x49,0x36, | ||
134 | 0x49,0x4a,0x48,0x42,0x4e,0x72,0x5a,0xd2, | ||
135 | 0x21,0x13,0x39,0x95,0x6a,0x80,0x80,0xfc, | ||
136 | 0xfd,0xf5,0xf3,0xc3,0xd7,0x77,0x0c,0xcd, | ||
137 | 0xd5,0x53,0x00,0x15,0xff,0x83,0xfe,0xf7, | ||
138 | 0xf9,0xcf,0xeb,0x5f,0x84,0x3e,0xe7,0x79, | ||
139 | 0xac,0xea,0x15,0x83,0x82,0xf6,0xf1,0xc9, | ||
140 | 0xdb,0x4b,0x24,0x45,0x26,0x61,0x2a,0xb9, | ||
141 | 0x00,0x69,0xfe,0x8b,0xf8,0xc7,0xed,0x6f, | ||
142 | 0x90,0x9e,0x9c,0xb8,0xb4,0x6c,0x46,0x96, | ||
143 | 0x68,0x8a,0x8c,0xc0,0xd5,0x7d,0x00,0xf1, | ||
144 | 0xfd,0xdb,0xf3,0x27,0xd5,0x2f,0x01,0x1d, | ||
145 | 0xf9,0xb3,0xea,0x57,0x82,0x0e,0xf3,0xd9, | ||
146 | 0xd7,0x2b,0x0d,0x05,0xd1,0xe3,0x1b,0xb5, | ||
147 | 0xa6,0x42,0x2a,0x73,0x02,0xd5,0xf1,0x03, | ||
148 | 0xd9,0xf7,0x2b,0xcd,0x07,0x51,0xec,0x1b, | ||
149 | 0x97,0xa6,0x8e,0x28,0xdb,0x0d,0x25,0xd1, | ||
150 | 0x23,0x19,0x35,0xa9,0x42,0x08,0x73,0xce, | ||
151 | 0xd7,0x59,0x0c,0x29,0xd7,0x0b,0x0d,0xc5, | ||
152 | 0xd3,0x63,0x14,0xb5,0x84,0x42,0xe6,0x71, | ||
153 | 0xaa,0xda,0x01,0x23,0xf9,0x37,0xe9,0x4f, | ||
154 | 0x88,0x5e,0xce,0x39,0x5b,0x68,0x24,0x8f, | ||
155 | 0x24,0xdd,0x25,0x31,0x21,0x59,0x38,0x29, | ||
156 | 0x6f,0x08,0x9d,0xcc,0xb3,0x54,0x54,0x06, | ||
157 | 0x07,0xeb,0xef,0x87,0x9e,0xee,0xb9,0x98, | ||
158 | 0x6a,0xae,0x80,0x18,0xff,0xad,0xfe,0x13, | ||
159 | 0xfb,0x97,0xe6,0x8f,0xa8,0xde,0x0d,0x3b, | ||
160 | 0xd1,0x67,0x18,0xad,0xac,0x12,0x17,0x93, | ||
161 | 0x8e,0x96,0xd8,0x89,0x2c,0xc9,0x15,0x49, | ||
162 | 0x80,0x4a,0xfe,0x41,0xfa,0x7b,0xe2,0xe7, | ||
163 | 0xb1,0xae,0x5a,0x1a,0x23,0xa3,0x36,0x35, | ||
164 | 0x4b,0x40,0x44,0x7e,0x66,0xfa,0xa9,0xe0, | ||
165 | 0x0b,0xbf,0xc6,0x7f,0x6a,0xfc,0x81,0xf4, | ||
166 | 0xfb,0xc5,0xe7,0x63,0xac,0xb6,0x14,0x4b, | ||
167 | 0x86,0x46,0xea,0x69,0x82,0x8a,0xf0,0xc1, | ||
168 | 0xdd,0x7b,0x30,0xe5,0x5d,0xa0,0x32,0x3f, | ||
169 | 0x53,0x7c,0x14,0xf7,0x85,0xce,0xe3,0x59, | ||
170 | 0xb4,0x2a,0x47,0x02,0x6d,0xf2,0x93,0xd0, | ||
171 | 0x97,0x1c,0x8d,0xb4,0xd2,0x45,0x12,0x61, | ||
172 | 0x92,0xba,0x90,0x60,0x9e,0xbc,0xb8,0x74, | ||
173 | 0x6e,0xc6,0x99,0x68,0xa8,0x8c,0x0c,0xd7, | ||
174 | 0xd5,0x0f,0x01,0xdd,0xfb,0x33,0xe5,0x57, | ||
175 | 0xa0,0x0e,0x3f,0xdb,0x7f,0x24,0xfd,0x25, | ||
176 | 0xf1,0x23,0xd9,0x37,0x29,0x4d,0x08,0x51, | ||
177 | 0xce,0x1b,0x5b,0xa4,0x26,0x27,0x2b,0x2d, | ||
178 | 0x05,0x11,0xe1,0x9b,0xba,0xa6,0x60,0x2a, | ||
179 | 0xbf,0x00,0x7d,0xfe,0xf3,0xf9,0xd7,0xeb, | ||
180 | 0x0f,0x85,0xde,0xe3,0x39,0xb5,0x6a,0x40, | ||
181 | 0x82,0x7c,0xf2,0xf5,0xd1,0xc3,0x1b,0x75, | ||
182 | 0xa4,0xc2,0x25,0x73,0x20,0xd5,0x3d,0x01, | ||
183 | 0x71,0xf8,0xdb,0xed,0x27,0x91,0x2e,0x99, | ||
184 | 0x18,0xa9,0xac,0x0a,0x17,0xc3,0x8f,0x76, | ||
185 | 0xdc,0xc9,0x35,0x49,0x40,0x48,0x7e,0x4e, | ||
186 | 0xfa,0x59,0xe2,0x2b,0xb3,0x06,0x55,0xe2, | ||
187 | 0x03,0x83,0xf6,0xf7,0xc9,0xcf,0x4b,0x5c, | ||
188 | 0x04,0x3e,0x67,0x4e,0xac,0x60,0x17,0x7f, | ||
189 | 0x80,0xfe,0xc1,0xf9,0x7b,0xe8,0xe7,0x87, | ||
190 | 0xae,0xc2,0x19,0x93,0xfc,0x96,0x08,0x8f, | ||
191 | 0xc0,0xe7,0xfc,0x2c,0xf0,0x1d,0xcc,0xc3, | ||
192 | 0x9e,0x70,0x00,0xc0,0x63,0x7f,0x54,0x78, | ||
193 | 0x40,0xfe,0x61,0x9b,0xf3,0x40,0x64,0x3f, | ||
194 | 0x0f,0xf8,0x2c,0xf3,0x3f,0x99,0x83,0x2a, | ||
195 | 0x79,0x07,0xcb,0xe1,0x9f,0xcc,0xce,0x60, | ||
196 | 0x6c,0x00,0x84,0x7c,0x0f,0xf5,0xe8,0xcf, | ||
197 | 0x15,0x66,0x80,0xb0,0xf8,0x5d,0xf4,0x33, | ||
198 | 0x8a,0x57,0x44,0x0c,0x67,0xd6,0xaf,0x08, | ||
199 | 0x1f,0xcf,0xb3,0x5e,0x54,0x3a,0x07,0x63, | ||
200 | 0xec,0xb7,0x94,0x4e,0x86,0x58,0xea,0x2d, | ||
201 | 0x83,0x12,0xf5,0x91,0xc2,0x9b,0x70,0xa4, | ||
202 | 0xdc,0x25,0x37,0x21,0x4d,0x38,0x51,0x6e, | ||
203 | 0x18,0x9b,0xac,0xa6,0x14,0x2b,0x87,0x06, | ||
204 | 0xed,0xe9,0x93,0x8a,0x96,0xc0,0x89,0x7c, | ||
205 | 0xc8,0xf5,0x4d,0xc0,0x53,0x7e,0x14,0xfb, | ||
206 | 0x85,0xe6,0xe3,0xa9,0xb6,0x0a,0x4b,0xc2, | ||
207 | 0x47,0x72,0x6c,0xd2,0x95,0x10,0x81,0x9c, | ||
208 | 0xfa,0xb5,0xe0,0x43,0xbe,0x76,0x7a,0xca, | ||
209 | 0xe1,0x41,0xb8,0x7a,0x6e,0xe2,0x99,0xb0, | ||
210 | 0xaa,0x5c,0x02,0x37,0xf3,0x4f,0xd4,0x5f, | ||
211 | 0x06,0x3d,0xeb,0x73,0x84,0xd6,0xe5,0x09, | ||
212 | 0xa1,0xca,0x3b,0x43,0x64,0x74,0xa6,0xc4, | ||
213 | 0x29,0x67,0x08,0xad,0xcc,0x13,0x57,0x94, | ||
214 | 0x0e,0x87,0xd8,0xef,0x2d,0x9d,0x12,0xb1, | ||
215 | 0x90,0x5a,0x9e,0x20,0xbb,0x3c,0x65,0x76, | ||
216 | 0xa0,0xc8,0x3d,0x4f,0x70,0x5c,0xde,0x35, | ||
217 | 0x3b,0x41,0x64,0x78,0xa6,0xec,0x29,0x97, | ||
218 | 0x0a,0x8d,0xc0,0xd3,0x7d,0x14,0xf1,0x85, | ||
219 | 0xda,0xe3,0x21,0xb5,0x3a,0x41,0x62,0x78, | ||
220 | 0xb2,0xec,0x51,0x96,0x1a,0x8b,0xa0,0xc6, | ||
221 | 0x3d,0x6b,0x70,0x84,0xdc,0xe5,0x35,0xa1, | ||
222 | 0x42,0x38,0x73,0x6e,0xd4,0x99,0x04,0xa9, | ||
223 | 0xe4,0x0b,0xa7,0xc6,0x2f,0x6b,0x1c,0x85, | ||
224 | 0xb4,0xe2,0x45,0xb2,0x62,0x52,0xb2,0x10, | ||
225 | 0x53,0x9e,0x16,0xbb,0x88,0x66,0xce,0xa9, | ||
226 | 0x58,0x08,0x2f,0xcf,0x1f,0x5d,0xbc,0x32, | ||
227 | 0x77,0x52,0xcc,0x11,0x57,0x98,0x0e,0xaf, | ||
228 | 0xd8,0x1f,0x2f,0xbd,0x1e,0x71,0xba,0xda, | ||
229 | 0x61,0x22,0xb9,0x30,0x69,0x5e,0x88,0x38, | ||
230 | 0xcf,0x6d,0x5c,0x90,0x34,0x9f,0x44,0xbc, | ||
231 | 0x64,0x76,0xa6,0xc8,0x29,0x4f,0x08,0x5d, | ||
232 | 0xce,0x33,0x5b,0x54,0x24,0x07,0x27,0xed, | ||
233 | 0x2f,0x91,0x1e,0x99,0xb8,0xaa,0x6c,0x02, | ||
234 | 0x97,0xf0,0x8f,0xdc,0xdf,0x35,0x3d,0x41, | ||
235 | 0x70,0x78,0xde,0xed,0x39,0x91,0x6a,0x98, | ||
236 | 0x80,0xac,0xfc,0x15,0xf7,0x83,0xce,0xf7, | ||
237 | 0x59,0xcc,0x2b,0x57,0x04,0x0d,0xe7,0xd3, | ||
238 | 0xaf,0x16,0x1d,0x8b,0xb2,0xc6,0x51,0x6a, | ||
239 | 0x18,0x83,0xac,0xf6,0x15,0xcb,0x83,0x46, | ||
240 | 0xf4,0x69,0xc6,0x8b,0x68,0xc4,0x8d,0x64, | ||
241 | 0xd0,0xa5,0x1c,0x21,0xb7,0x3a,0x4d,0x62, | ||
242 | 0x50,0xb2,0x1c,0x53,0xb6,0x16,0x4b,0x8a, | ||
243 | 0x46,0xc2,0x69,0x72,0x88,0xd0,0xcd,0x1d, | ||
244 | 0x51,0xb0,0x1a,0x5f,0xa2,0x3e,0x33,0x7b, | ||
245 | 0x54,0xe4,0x05,0xa7,0xe2,0x2f,0xb3,0x1e, | ||
246 | 0x55,0xba,0x02,0x63,0xf2,0xb7,0xd0,0x4f, | ||
247 | 0x1e,0x5d,0xba,0x32,0x63,0x52,0xb4,0x10, | ||
248 | 0x47,0x9e,0x6e,0xba,0x98,0x60,0xae,0xbc, | ||
249 | 0x18,0x77,0xae,0xce,0x19,0x5b,0xa8,0x26, | ||
250 | 0x0f,0x2b,0xdd,0x07,0x31,0xed,0x5b,0x90, | ||
251 | 0x26,0x9f,0x28,0xbd,0x0c,0x71,0xd6,0xdb, | ||
252 | 0x09,0x25,0xc9,0x23,0x49,0x34,0x49,0x46, | ||
253 | 0x48,0x6a,0x4e,0x82,0x58,0xf2,0x2d,0xd3, | ||
254 | 0x13,0x15,0x95,0x82,0x82,0xf0,0xf1,0xdd, | ||
255 | 0xdb,0x33,0x25,0x55,0x20,0x01,0x3f,0xf9, | ||
256 | 0x7f,0xe8,0xff,0x8d,0xfe,0xd3,0xf9,0x17, | ||
257 | 0xe9,0x8f,0x8a,0xde,0xc1,0x39,0x79,0x68, | ||
258 | 0xe8,0x8d,0x8c,0xd2,0xd5,0x11,0x01,0x99, | ||
259 | 0xfa,0xab,0xe0,0x07,0xbf,0xee,0x7f,0x9a, | ||
260 | 0xfe,0xa1,0xf8,0x3b,0xef,0x67,0x9c,0xae, | ||
261 | 0xb4,0x18,0x47,0xae,0x6e,0x1a,0x9b,0xa0, | ||
262 | 0xa6,0x3c,0x2b,0x77,0x04,0xcd,0xe5,0x53, | ||
263 | 0xa0,0x16,0x3f,0x8b,0x7e,0xc4,0xf9,0x65, | ||
264 | 0xe8,0xa3,0x8c,0x36,0xd7,0x49,0x0c,0x49, | ||
265 | 0xd6,0x4b,0x0a,0x45,0xc2,0x63,0x72,0xb4, | ||
266 | 0xd0,0x45,0x1e,0x61,0xba,0xba,0x60,0x62, | ||
267 | 0xbe,0xb0,0x78,0x5e,0xee,0x39,0x9b,0x6a, | ||
268 | 0xa4,0x80,0x24,0xff,0x25,0xfd,0x23,0xf1, | ||
269 | 0x37,0xd9,0x4f,0x28,0x5d,0x0e,0x31,0xdb, | ||
270 | 0x5b,0x24,0x25,0x27,0x21,0x2d,0x39,0x11, | ||
271 | 0x69,0x98,0x8a,0xac,0xc0,0x15,0x7f,0x80, | ||
272 | 0xfe,0xfd,0xf9,0xf3,0xeb,0xd7,0x87,0x0e, | ||
273 | 0xed,0xd9,0x93,0x2a,0x95,0x00,0x81,0xfc, | ||
274 | 0xfb,0xf5,0xe7,0xc3,0xaf,0x76,0x1c,0xcb, | ||
275 | 0xb5,0x46,0x40,0x6a,0x7e,0x82,0xf8,0xf1, | ||
276 | 0xed,0xdb,0x93,0x26,0x95,0x28,0x81,0x0c, | ||
277 | 0xf9,0xd5,0xeb,0x03,0x85,0xf6,0xe3,0xc9, | ||
278 | 0xb7,0x4a,0x4c,0x42,0x56,0x72,0x0a,0xd3, | ||
279 | 0xc1,0x17,0x79,0x8c,0xea,0xd5,0x81,0x02, | ||
280 | 0xf9,0xf1,0xeb,0xdb,0x87,0x26,0xed,0x29, | ||
281 | 0x91,0x0a,0x99,0xc0,0xab,0x7c,0x04,0xf7, | ||
282 | 0xe5,0xcf,0xa3,0x5e,0x34,0x3b,0x47,0x64, | ||
283 | 0x6c,0xa6,0x94,0x28,0x87,0x0c,0xed,0xd5, | ||
284 | 0x93,0x02,0x95,0xf0,0x83,0xdc,0xf7,0x35, | ||
285 | 0xcd,0x43,0x50,0x74,0x1e,0xc7,0xb9,0x6e, | ||
286 | 0x68,0x9a,0x8c,0xa0,0xd4,0x3d,0x07,0x71, | ||
287 | 0xec,0xdb,0x95,0x26,0x81,0x28,0xf9,0x0d, | ||
288 | 0xe9,0xd3,0x8b,0x16,0xc5,0x89,0x62,0xc8, | ||
289 | 0xb1,0x4c,0x58,0x56,0x2e,0x0b,0x1b,0xc5, | ||
290 | 0xa7,0x62,0x2c,0xb3,0x14,0x55,0x86,0x02, | ||
291 | 0xeb,0xf1,0x87,0xda,0xef,0x21,0x9d,0x3a, | ||
292 | 0xb1,0x60,0x58,0xbe,0x2c,0x7b,0x16,0xe5, | ||
293 | 0x89,0xa2,0xca,0x31,0x43,0x58,0x74,0x2e, | ||
294 | 0xc7,0x19,0x6d,0xa8,0x92,0x0c,0x93,0xd4, | ||
295 | 0x97,0x04,0x8d,0xe4,0xd3,0xa5,0x16,0x21, | ||
296 | 0x8b,0x3a,0xc5,0x61,0x60,0xb8,0xbc,0x6c, | ||
297 | 0x76,0x96,0xc8,0x89,0x4c,0xc8,0x55,0x4e, | ||
298 | 0x00,0x5b,0xfe,0x27,0xfb,0x2f,0xe5,0x1f, | ||
299 | 0xa1,0xbe,0x3a,0x7b,0x62,0xe4,0xb1,0xa4, | ||
300 | 0x5a,0x26,0x23,0x2b,0x35,0x05,0x41,0xe0, | ||
301 | 0x7b,0xbe,0xe6,0x79,0xaa,0xea,0x01,0x83, | ||
302 | 0xfa,0xf7,0xe1,0xcf,0xbb,0x5e,0x64,0x3a, | ||
303 | 0xa7,0x60,0x2c,0xbf,0x14,0x7d,0x86,0xf2, | ||
304 | 0xe9,0xd1,0x8b,0x1a,0xc5,0xa1,0x62,0x38, | ||
305 | 0xb3,0x6c,0x54,0x96,0x04,0x8b,0xe4,0xc7, | ||
306 | 0xa5,0x6e,0x20,0x9b,0x3c,0xa5,0x74,0x20, | ||
307 | 0xc7,0x3d,0x6d,0x70,0x90,0xdc,0x9d,0x34, | ||
308 | 0xb1,0x44,0x58,0x66,0x2e,0xab,0x18,0x05, | ||
309 | 0xaf,0xe2,0x1f,0xb3,0xbe,0x56,0x7a,0x0a, | ||
310 | 0xe3,0xc1,0xb7,0x7a,0x4c,0xe2,0x55,0xb2, | ||
311 | 0x02,0x53,0xf2,0x17,0xd3,0x8f,0x16,0xdd, | ||
312 | 0x89,0x32,0xc9,0x51,0x48,0x18,0x4f,0xae, | ||
313 | 0x5e,0x1a,0x3b,0xa3,0x66,0x34,0xab,0x44, | ||
314 | 0x04,0x67,0xe6,0xaf,0xa8,0x1e,0x0f,0xbb, | ||
315 | 0xde,0x67,0x3a,0xad,0x60,0x10,0xbf,0x9c, | ||
316 | 0x7e,0xb6,0xf8,0x49,0xee,0x4b,0x9a,0x46, | ||
317 | 0xa2,0x68,0x32,0x8f,0x50,0xdc,0x1d,0x37, | ||
318 | 0xb1,0x4e,0x58,0x5a,0x2e,0x23,0x1b,0x35, | ||
319 | 0xa5,0x42,0x20,0x73,0x3e,0xd5,0x79,0x00, | ||
320 | 0xe9,0xfd,0x8b,0xf2,0xc7,0xd1,0x6f,0x18, | ||
321 | 0x9d,0xac,0xb2,0x14,0x53,0x86,0x16,0xeb, | ||
322 | 0x89,0x86,0xca,0xe9,0x41,0x88,0x7a,0xce, | ||
323 | 0xe1,0x59,0xb8,0x2a,0x6f,0x02,0x9d,0xf0, | ||
324 | 0xb3,0xdc,0x57,0x36,0x0d,0x4b,0xd0,0x47, | ||
325 | 0x1e,0x6d,0xba,0x92,0x60,0x92,0xbc,0x90, | ||
326 | 0x74,0x9e,0xc4,0xb9,0x64,0x68,0xa6,0x8c, | ||
327 | 0x28,0xd7,0x0d,0x0d,0xd1,0xd3,0x1b,0x15, | ||
328 | 0xa5,0x82,0x22,0xf3,0x31,0xd5,0x5b,0x00, | ||
329 | 0x25,0xff,0x23,0xfd,0x37,0xf1,0x4f,0xd8, | ||
330 | 0x5f,0x2e,0x3d,0x1b,0x71,0xa4,0xda,0x25, | ||
331 | 0x23,0x21,0x35,0x39,0x41,0x68,0x78,0x8e, | ||
332 | 0xec,0xd9,0x95,0x2a,0x81,0x00,0xf9,0xfd, | ||
333 | 0xeb,0xf3,0x87,0xd6,0xef,0x09,0x9d,0xca, | ||
334 | 0xb3,0x40,0x54,0x7e,0x06,0xfb,0xe9,0xe7, | ||
335 | 0x8b,0xae,0xc6,0x19,0x6b,0xa8,0x86,0x0c, | ||
336 | 0xeb,0xd5,0x87,0x02,0xed,0xf1,0x93,0xda, | ||
337 | 0x97,0x20,0x8d,0x3c,0xd1,0x75,0x18,0xc1, | ||
338 | 0xad,0x7a,0x10,0xe3,0x9d,0xb6,0xb2,0x48, | ||
339 | 0x52,0x4e,0x12,0x5b,0x92,0x26,0x93,0x28, | ||
340 | 0x95,0x0c,0x81,0xd4,0xfb,0x05,0xe5,0xe3, | ||
341 | 0xa3,0xb6,0x36,0x4b,0x4a,0x44,0x42,0x66, | ||
342 | 0x72,0xaa,0xd0,0x01,0x1f,0xf9,0xbf,0xea, | ||
343 | 0x7f,0x82,0xfe,0xf1,0xf9,0xdb,0xeb,0x27, | ||
344 | 0x85,0x2e,0xe1,0x19,0xb9,0xaa,0x6a,0x02, | ||
345 | 0x83,0xf0,0xf7,0xdd,0xcf,0x33,0x5d,0x54, | ||
346 | 0x30,0x07,0x5f,0xec,0x3f,0x97,0x7e,0x8c, | ||
347 | 0xf8,0xd5,0xed,0x03,0x91,0xf6,0x9b,0xc8, | ||
348 | 0xa7,0x4c,0x2c,0x57,0x16,0x0d,0x8b,0xd2, | ||
349 | 0xc7,0x11,0x6d,0x98,0x92,0xac,0x90,0x14, | ||
350 | 0x9f,0x84,0xbe,0xe4,0x79,0xa6,0xea,0x29, | ||
351 | 0x83,0x0a,0xf5,0xc1,0xc3,0x7b,0x74,0xe4, | ||
352 | 0xc5,0xa5,0x62,0x20,0xb3,0x3c,0x55,0x76, | ||
353 | 0x00,0xcb,0xfd,0x47,0xf0,0x6f,0xde,0x9f, | ||
354 | 0x38,0xbd,0x6c,0x70,0x96,0xdc,0x89,0x34, | ||
355 | 0xc9,0x45,0x48,0x60,0x4e,0xbe,0x58,0x7a, | ||
356 | 0x2e,0xe3,0x19,0xb5,0xaa,0x42,0x02,0x73, | ||
357 | 0xf2,0xd7,0xd1,0x0f,0x19,0xdd,0xab,0x32, | ||
358 | 0x05,0x53,0xe0,0x17,0xbf,0x8e,0x7e,0xda, | ||
359 | 0xf9,0x21,0xe9,0x3b,0x89,0x66,0xc8,0xa9, | ||
360 | 0x4c,0x08,0x57,0xce,0x0f,0x5b,0xdc,0x27, | ||
361 | 0x37,0x2d,0x4d,0x10,0x51,0x9e,0x1a,0xbb, | ||
362 | 0xa0,0x66,0x3e,0xab,0x78,0x04,0xef,0xe5, | ||
363 | 0x9f,0xa2,0xbe,0x30,0x7b,0x5e,0xe4,0x39, | ||
364 | 0xa7,0x6a,0x2c,0x83,0x14,0xf5,0x85,0xc2, | ||
365 | 0xe3,0x71,0xb4,0xda,0x45,0x22,0x61,0x32, | ||
366 | 0xb9,0x50,0x68,0x1e,0x8f,0xb8,0xde,0x6d, | ||
367 | 0x3a,0x91,0x60,0x98,0xbc,0xac,0x74,0x16, | ||
368 | 0xc7,0x89,0x6e,0xc8,0x99,0x4c,0xa8,0x54, | ||
369 | 0x0e,0x07,0xdb,0xef,0x27,0x9d,0x2e,0xb1, | ||
370 | 0x18,0x59,0xae,0x2a,0x1b,0x03,0xa5,0xf6, | ||
371 | 0x23,0xcb,0x37,0x45,0x4c,0x60,0x56,0xbe, | ||
372 | 0x08,0x7b,0xce,0xe7,0x59,0xac,0x2a,0x17, | ||
373 | 0x03,0x8d,0xf6,0xd3,0xc9,0x17,0x49,0x8c, | ||
374 | 0x4a,0xd6,0x41,0x0a,0x79,0xc2,0xeb,0x71, | ||
375 | 0x84,0xda,0xe5,0x21,0xa1,0x3a,0x39,0x63, | ||
376 | 0x68,0xb4,0x8c,0x44,0xd6,0x65,0x0a,0xa1, | ||
377 | 0xc0,0x3b,0x7f,0x64,0xfc,0xa5,0xf4,0x23, | ||
378 | 0xc7,0x37,0x6d,0x4c,0x90,0x54,0x9e,0x04, | ||
379 | 0xbb,0xe4,0x67,0xa6,0xae,0x28,0x1b,0x0f, | ||
380 | 0xa5,0xde,0x23,0x3b,0x35,0x65,0x40,0xa0, | ||
381 | 0x7c,0x3e,0xf7,0x79,0xcc,0xeb,0x55,0x84, | ||
382 | 0x02,0xe7,0xf1,0xaf,0xda,0x1f,0x23,0xbd, | ||
383 | 0x36,0x71,0x4a,0xd8,0x41,0x2e,0x79,0x1a, | ||
384 | 0xe9,0xa1,0x8a,0x3a,0xc3,0x61,0x74,0xb8, | ||
385 | 0xc4,0x6d,0x66,0x90,0xa8,0x9c,0x0c,0xb7, | ||
386 | 0xd4,0x4f,0x06,0x5d,0xea,0x33,0x83,0x56, | ||
387 | 0xf4,0x09,0xc7,0xcb,0x6f,0x44,0x9c,0x64, | ||
388 | 0xb6,0xa4,0x48,0x26,0x4f,0x2a,0x5d,0x02, | ||
389 | 0x31,0xf3,0x5b,0xd4,0x27,0x07,0x2d,0xed, | ||
390 | 0x13,0x91,0x96,0x9a,0x88,0xa0,0xcc,0x3d, | ||
391 | 0x57,0x70,0x0c,0xdf,0xd5,0x3f,0x01,0x7d, | ||
392 | 0xf8,0xf3,0xed,0xd7,0x93,0x0e,0x95,0xd8, | ||
393 | 0x83,0x2c,0xf5,0x15,0xc1,0x83,0x7a,0xf4, | ||
394 | 0xe1,0xc5,0xbb,0x62,0x64,0xb2,0xa4,0x50, | ||
395 | 0x26,0x1f,0x2b,0xbd,0x06,0x71,0xea,0xdb, | ||
396 | 0x81,0x26,0xf9,0x29,0xe9,0x0b,0x89,0xc6, | ||
397 | 0xcb,0x69,0x44,0x88,0x64,0xce,0xa5,0x58, | ||
398 | 0x20,0x2f,0x3f,0x1d,0x7d,0xb0,0xf2,0x5d, | ||
399 | 0xd2,0x33,0x13,0x55,0x94,0x02,0x87,0xf0, | ||
400 | 0xef,0xdd,0x9f,0x32,0xbd,0x50,0x70,0x1e, | ||
401 | 0xdf,0xb9,0x3e,0x69,0x7a,0x88,0xe0,0xcd, | ||
402 | 0xbd,0x52,0x70,0x12,0xdf,0x91,0x3e,0x99, | ||
403 | 0x78,0xa8,0xec,0x0d,0x97,0xd2,0x8f,0x10, | ||
404 | 0xdd,0x9d,0x32,0xb1,0x50,0x58,0x1e,0x2f, | ||
405 | 0xbb,0x1e,0x65,0xba,0xa2,0x60,0x32,0xbf, | ||
406 | 0x50,0x7c,0x1e,0xf7,0xb9,0xce,0x6b,0x5a, | ||
407 | 0x84,0x20,0xe7,0x3d,0xad,0x72,0x10,0xd3, | ||
408 | 0x9d,0x16,0xb1,0x88,0x5a,0xce,0x21,0x5b, | ||
409 | 0x38,0x25,0x6f,0x20,0x9d,0x3c,0xb1,0x74, | ||
410 | 0x58,0xc6,0x2d,0x6b,0x10,0x85,0x9c,0xe2, | ||
411 | 0xb5,0xb0,0x42,0x5e,0x72,0x3a,0xd3,0x61, | ||
412 | 0x14,0xb9,0x84,0x6a,0xe6,0x81,0xa8,0xfa, | ||
413 | 0x0d,0xe3,0xd3,0xb7,0x16,0x4d,0x8a,0x52, | ||
414 | 0xc2,0x11,0x73,0x98,0xd6,0xad,0x08,0x11, | ||
415 | 0xcf,0x9b,0x5e,0xa4,0x38,0x27,0x6f,0x2c, | ||
416 | 0x9d,0x14,0xb1,0x84,0x5a,0xe6,0x21,0xab, | ||
417 | 0x3a,0x05,0x63,0xe0,0xb7,0xbc,0x4e,0x76, | ||
418 | 0x5a,0xca,0x21,0x43,0x38,0x75,0x6e,0xc0, | ||
419 | 0x99,0x7c,0xa8,0xf4,0x0d,0xc7,0xd3,0x6f, | ||
420 | 0x14,0x9d,0x84,0xb2,0xe4,0x51,0xa6,0x1a, | ||
421 | 0x2b,0xa3,0x06,0x35,0xeb,0x43,0x84,0x76, | ||
422 | 0xe6,0xc9,0xa9,0x4a,0x08,0x43,0xce,0x77, | ||
423 | 0x5a,0xcc,0x21,0x57,0x38,0x0d,0x6f,0xd0, | ||
424 | 0x9f,0x1c,0xbd,0xb4,0x72,0x46,0xd2,0x69, | ||
425 | 0x12,0x89,0x90,0xca,0x9d,0x40,0xb0,0x7c, | ||
426 | 0x5e,0xf6,0x39,0xcb,0x6b,0x44,0x84,0x64, | ||
427 | 0xe6,0xa5,0xa8,0x22,0x0f,0x33,0xdd,0x57, | ||
428 | 0x30,0x0d,0x5f,0xd0,0x3f,0x1f,0x7d,0xbc, | ||
429 | 0xf2,0x75,0xd2,0xc3,0x11,0x75,0x98,0xc2, | ||
430 | 0xad,0x70,0x10,0xdf,0x9d,0x3e,0xb1,0x78, | ||
431 | 0x58,0xee,0x2d,0x9b,0x12,0xa5,0x90,0x22, | ||
432 | 0x9f,0x30,0xbd,0x5c,0x70,0x36,0xdf,0x49, | ||
433 | 0x3c,0x49,0x76,0x48,0xca,0x4d,0x42,0x50, | ||
434 | 0x72,0x1e,0xd3,0xb9,0x16,0x69,0x8a,0x8a, | ||
435 | 0xc0,0xc1,0x7d,0x78,0xf0,0xed,0xdd,0x93, | ||
436 | 0x32,0x95,0x50,0x80,0x1c,0xff,0xb5,0xfe, | ||
437 | 0x43,0xfa,0x77,0xe2,0xcf,0xb1,0x5e,0x58, | ||
438 | 0x3a,0x2f,0x63,0x1c,0xb5,0xb4,0x42,0x46, | ||
439 | 0x72,0x6a,0xd2,0x81,0x10,0xf9,0x9d,0xea, | ||
440 | 0xb3,0x80,0x56,0xfe,0x09,0xfb,0xcb,0xe7, | ||
441 | 0x47,0xac,0x6e,0x16,0x9b,0x88,0xa6,0xcc, | ||
442 | 0x29,0x57,0x08,0x0d,0xcf,0xd3,0x5f,0x14, | ||
443 | 0x3d,0x87,0x72,0xec,0xd1,0x95,0x1a,0x81, | ||
444 | 0xa0,0xfa,0x3d,0xe3,0x73,0xb4,0xd6,0x45, | ||
445 | 0x0a,0x61,0xc2,0xbb,0x70,0x64,0xde,0xa5, | ||
446 | 0x38,0x21,0x6f,0x38,0x9d,0x6c,0xb0,0x94, | ||
447 | 0x5c,0x86,0x3e,0xeb,0x45,0x84,0x62,0xe6, | ||
448 | 0xb1,0xa8,0x5a,0x0e,0x23,0xfb,0x33,0x25, | ||
449 | 0x47,0x20,0x51,0x3e,0x19,0x7f,0xa8,0x66, | ||
450 | 0x0c,0xfb,0xd0,0x07,0x13,0xe5,0x9f,0x83, | ||
451 | 0xce,0x98,0x58,0xcd,0x2e,0x19,0x14,0x39, | ||
452 | 0x86,0x3f,0xff,0x01,0x85,0xff,0xe1,0xe1, | ||
453 | 0xb3,0xfc,0x46,0x63,0x0f,0xf8,0x00,0x53, | ||
454 | 0xbe,0x1f,0xfb,0xc0,0xe6,0x7e,0xbc,0xf0, | ||
455 | 0x01,0xe3,0xc3,0x9f,0xa6,0xcc,0x48,0x7e, | ||
456 | 0x40,0x82,0x9d,0xf2,0xff,0xd6,0x07,0x13, | ||
457 | 0xf5,0x87,0x80,0x0f,0x71,0x9c,0xfd,0x35, | ||
458 | 0x61,0x43,0xf8,0x78,0x7e,0xcf,0x19,0x99, | ||
459 | 0xa8,0x32,0x00,0x53,0xfc,0x17,0xfb,0x8f, | ||
460 | 0xc6,0xdf,0xa9,0x3e,0x09,0x7b,0xc8,0xe7, | ||
461 | 0x4d,0xac,0x52,0x16,0x13,0x8b,0x96,0xc6, | ||
462 | 0x89,0x68,0xc8,0x8d,0x4c,0xd0,0x55,0x1e, | ||
463 | 0x01,0xbb,0xfa,0x67,0xe2,0xaf,0xb0,0x1e, | ||
464 | 0x5f,0xba,0x3e,0x63,0x7a,0xb4,0xe0,0x45, | ||
465 | 0xbe,0x62,0x7a,0xb2,0xe0,0x51,0xbe,0x1a, | ||
466 | 0x7b,0xa2,0xe6,0x31,0xab,0x5a,0x04,0x23, | ||
467 | 0xe7,0x37,0xad,0x4e,0x10,0x5b,0x9e,0x26, | ||
468 | 0xbb,0x28,0x65,0x0e,0xa1,0xd8,0x3b,0x2f, | ||
469 | 0x65,0x1c,0xa1,0xb4,0x3a,0x47,0x62,0x6c, | ||
470 | 0xb2,0x94,0x50,0x86,0x1c,0xeb,0xb5,0x86, | ||
471 | 0x42,0xea,0x71,0x82,0xda,0xf1,0x21,0xd9, | ||
472 | 0x3b,0x29,0x65,0x08,0xa1,0xcc,0x3b,0x57, | ||
473 | 0x64,0x0c,0xa7,0xd4,0x2f,0x07,0x1d,0xed, | ||
474 | 0xb3,0x92,0x56,0x92,0x08,0x93,0xcc,0x97, | ||
475 | 0x54,0x8c,0x04,0xd7,0xe5,0x0f,0xa1,0xde, | ||
476 | 0x3b,0x3b,0x65,0x64,0xa0,0xa4,0x3c,0x27, | ||
477 | 0x77,0x2c,0xcd,0x15,0x51,0x80,0x1a,0xff, | ||
478 | 0xa1,0xfe,0x3b,0xfb,0x67,0xe4,0xaf,0xa4, | ||
479 | 0x1e,0x27,0xbb,0x2e,0x65,0x1a,0xa1,0xa0, | ||
480 | 0x3a,0x3f,0x63,0x7c,0xb4,0xf4,0x45,0xc6, | ||
481 | 0x63,0x6a,0xb4,0x80,0x44,0xfe,0x65,0xfa, | ||
482 | 0xa3,0xe0,0x37,0xbf,0x4e,0x7c,0x5a,0xf6, | ||
483 | 0x21,0xcb,0x3b,0x45,0x64,0x60,0xa6,0xbc, | ||
484 | 0x28,0x77,0x0e,0xcd,0xd9,0x53,0x28,0x15, | ||
485 | 0x0f,0x81,0xde,0xfb,0x39,0xe5,0x6b,0xa0, | ||
486 | 0x86,0x3c,0xeb,0x75,0x84,0xc2,0xe5,0x71, | ||
487 | 0xa0,0xda,0x3d,0x23,0x71,0x34,0xd9,0x45, | ||
488 | 0x28,0x61,0x0e,0xb9,0xd8,0x6b,0x2e,0x85, | ||
489 | 0x18,0xe1,0xad,0xba,0x12,0x63,0x92,0xb6, | ||
490 | 0x90,0x48,0x9e,0x4c,0xba,0x54,0x62,0x06, | ||
491 | 0xb3,0xe8,0x57,0x8e,0x0e,0xdb,0xd9,0x27, | ||
492 | 0x29,0x2d,0x09,0x11,0xc9,0x9b,0x4a,0xa4, | ||
493 | 0x40,0x26,0x7f,0x2a,0xfd,0x01,0xf1,0xfb, | ||
494 | 0xdb,0xe7,0x27,0xad,0x2e,0x11,0x1b,0x99, | ||
495 | 0xa6,0xaa,0x28,0x03,0x0f,0xf5,0xdf,0xc3, | ||
496 | 0x3f,0x75,0x7c,0xc0,0xf5,0x7d,0xc0,0xf3, | ||
497 | 0x7d,0xd4,0xf3,0x05,0xd5,0xe3,0x03,0xb5, | ||
498 | 0xf6,0x43,0xca,0x77,0x42,0xcc,0x71,0x56, | ||
499 | 0xd8,0x09,0x2f,0xc9,0x1f,0x49,0xbc,0x4a, | ||
500 | 0x76,0x42,0xca,0x71,0x42,0xd8,0x71,0x2e, | ||
501 | 0xd9,0x19,0x29,0xa9,0x0a,0x09,0xc3,0xcb, | ||
502 | 0x77,0x44,0xcc,0x65,0x56,0xa0,0x08,0x3f, | ||
503 | 0xcf,0x7f,0x5c,0xfc,0x35,0xf7,0x43,0xcc, | ||
504 | 0x77,0x56,0xcc,0x09,0x57,0xc8,0x0f,0x4f, | ||
505 | 0xdc,0x5f,0x36,0x3d,0x4b,0x70,0x44,0xde, | ||
506 | 0x65,0x3a,0xa1,0x60,0x38,0xbf,0x6c,0x7c, | ||
507 | 0x96,0xf4,0x89,0xc4,0xcb,0x65,0x44,0xa0, | ||
508 | 0x64,0x3e,0xa7,0x78,0x2c,0xef,0x15,0x9d, | ||
509 | 0x82,0xb2,0xf0,0x51,0xde,0x1b,0x3b,0xa5, | ||
510 | 0x66,0x20,0xab,0x3c,0x05,0x77,0xe0,0xcf, | ||
511 | 0xbd,0x5e,0x70,0x3a,0xdf,0x61,0x3c,0xb9, | ||
512 | 0x74,0x68,0xc6,0x8d,0x68,0xd0,0x8d,0x1c, | ||
513 | 0xd1,0xb5,0x1a,0x41,0xa2,0x7a,0x32,0xe3, | ||
514 | 0x51,0xb4,0x1a,0x47,0xa2,0x6e,0x32,0x9b, | ||
515 | 0x50,0xa4,0x1c,0x27,0xb7,0x2e,0x4d,0x1a, | ||
516 | 0x51,0xa2,0x1a,0x33,0xa3,0x56,0x34,0x0b, | ||
517 | 0x47,0xc4,0x6f,0x66,0x9c,0xa8,0xb4,0x0c, | ||
518 | 0x47,0xd6,0x6f,0x0a,0x9d,0xc0,0xb3,0x7c, | ||
519 | 0x54,0xf6,0x05,0xcb,0xe3,0x47,0xb4,0x6e, | ||
520 | 0x46,0x9a,0x68,0xa2,0x8c,0x30,0xd7,0x5d, | ||
521 | 0x0c,0x31,0xd7,0x5b,0x0c,0x25,0xd7,0x23, | ||
522 | 0x0d,0x35,0xd1,0x43,0x18,0x75,0xae,0xc2, | ||
523 | 0x19,0x73,0xa8,0xd6,0x0d,0x0b,0xd1,0xc7, | ||
524 | 0x1b,0x6d,0xa4,0x92,0x24,0x93,0x24,0x95, | ||
525 | 0x24,0x81,0x24,0xf9,0x25,0xe9,0x23,0x89, | ||
526 | 0x36,0xc9,0x49,0x48,0x48,0x4e,0x4e,0x5a, | ||
527 | 0x5a,0x22,0x23,0x33,0x35,0x55,0x40,0x00, | ||
528 | }; | ||
529 | |||
530 | |||
531 | #endif | ||
532 | |||
diff --git a/apps/plugins/rockboy/nosound.c b/apps/plugins/rockboy/nosound.c new file mode 100644 index 0000000000..a0c9b17f15 --- /dev/null +++ b/apps/plugins/rockboy/nosound.c | |||
@@ -0,0 +1,43 @@ | |||
1 | |||
2 | |||
3 | |||
4 | #include "rockmacros.h" | ||
5 | #include "defs.h" | ||
6 | #include "pcm.h" | ||
7 | #include "rc.h" | ||
8 | |||
9 | |||
10 | struct pcm pcm; | ||
11 | |||
12 | static byte buf[4096]; | ||
13 | |||
14 | |||
15 | rcvar_t pcm_exports[] = | ||
16 | { | ||
17 | RCV_END | ||
18 | }; | ||
19 | |||
20 | |||
21 | void pcm_init(void) | ||
22 | { | ||
23 | pcm.hz = 11025; | ||
24 | pcm.buf = buf; | ||
25 | pcm.len = sizeof buf; | ||
26 | pcm.pos = 0; | ||
27 | } | ||
28 | |||
29 | void pcm_close(void) | ||
30 | { | ||
31 | memset(&pcm, 0, sizeof pcm); | ||
32 | } | ||
33 | |||
34 | int pcm_submit(void) | ||
35 | { | ||
36 | pcm.pos = 0; | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | |||
41 | |||
42 | |||
43 | |||
diff --git a/apps/plugins/rockboy/palette.c b/apps/plugins/rockboy/palette.c new file mode 100644 index 0000000000..5c5083d247 --- /dev/null +++ b/apps/plugins/rockboy/palette.c | |||
@@ -0,0 +1,153 @@ | |||
1 | |||
2 | |||
3 | #include "rockmacros.h" | ||
4 | #include "defs.h" | ||
5 | #include "fb.h" | ||
6 | #include "palette.h" | ||
7 | |||
8 | |||
9 | static byte palmap[32768]; | ||
10 | static byte pallock[256]; | ||
11 | static int palrev[256]; | ||
12 | |||
13 | /* Course color mapping, for when palette is exhausted. */ | ||
14 | static byte crsmap[4][32768]; | ||
15 | static int crsrev[4][256]; | ||
16 | static const int crsmask[4] = { 0x7BDE, 0x739C, 0x6318, 0x4210 }; | ||
17 | |||
18 | enum plstatus | ||
19 | { | ||
20 | pl_unused = 0, | ||
21 | pl_linger, | ||
22 | pl_active, | ||
23 | pl_locked | ||
24 | }; | ||
25 | |||
26 | /* | ||
27 | static byte bestmatch(int c) | ||
28 | { | ||
29 | byte n, best; | ||
30 | int r, g, b; | ||
31 | int r2, g2, b2, c2; | ||
32 | int err, besterr; | ||
33 | |||
34 | r = (c & 0x001F) << 3; | ||
35 | g = (c & 0x03E0) >> 2; | ||
36 | b = (c & 0x7C00) >> 7; | ||
37 | |||
38 | best = 0; | ||
39 | besterr = 1024; | ||
40 | for (n = 1; n; n++) | ||
41 | { | ||
42 | c2 = palrev[n]; | ||
43 | r2 = (c2 & 0x001F) << 3; | ||
44 | g2 = (c2 & 0x03E0) >> 2; | ||
45 | b2 = (c2 & 0x7C00) >> 7; | ||
46 | err = abs(r-r2) + abs(b-b2) + abs(g-g2); | ||
47 | if (err < besterr) | ||
48 | { | ||
49 | besterr = err; | ||
50 | best = n; | ||
51 | } | ||
52 | } | ||
53 | return best; | ||
54 | } | ||
55 | */ | ||
56 | |||
57 | static void makecourse(int c, byte n) | ||
58 | { | ||
59 | int i; | ||
60 | for (i = 0; i < 4; i++) | ||
61 | { | ||
62 | c &= crsmask[i]; | ||
63 | crsmap[i][c] = n; | ||
64 | crsrev[i][n] = c; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | static byte findcourse(int c) | ||
69 | { | ||
70 | int i; | ||
71 | byte n; | ||
72 | for (i = 0; i < 4; i++) | ||
73 | { | ||
74 | c &= crsmask[i]; | ||
75 | n = crsmap[i][c]; | ||
76 | if (crsrev[i][n] == c) | ||
77 | return n; | ||
78 | } | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | |||
83 | void pal_lock(byte n) | ||
84 | { | ||
85 | if (!n) return; | ||
86 | if (pallock[n] >= pl_locked) | ||
87 | pallock[n]++; | ||
88 | else pallock[n] = pl_locked; | ||
89 | } | ||
90 | |||
91 | byte pal_getcolor(int c, int r, int g, int b) | ||
92 | { | ||
93 | byte n; | ||
94 | static byte l; | ||
95 | n = palmap[c]; | ||
96 | if (n && pallock[n] && palrev[n] == c) | ||
97 | { | ||
98 | pal_lock(n); | ||
99 | return n; | ||
100 | } | ||
101 | for (n = l+1; n != l; n++) | ||
102 | { | ||
103 | if (!n || pallock[n] /* || n < 16 */) continue; | ||
104 | pal_lock(n); | ||
105 | palmap[c] = n; | ||
106 | palrev[n] = c; | ||
107 | makecourse(c, n); | ||
108 | vid_setpal(n, r, g, b); | ||
109 | return (l = n); | ||
110 | } | ||
111 | n = findcourse(c); | ||
112 | pal_lock(n); | ||
113 | return n; | ||
114 | } | ||
115 | |||
116 | void pal_release(byte n) | ||
117 | { | ||
118 | if (pallock[n] >= pl_locked) | ||
119 | pallock[n]--; | ||
120 | } | ||
121 | |||
122 | |||
123 | void pal_expire(void) | ||
124 | { | ||
125 | int i; | ||
126 | for (i = 0; i < 256; i++) | ||
127 | if (pallock[i] && pallock[i] < pl_locked) | ||
128 | pallock[i]--; | ||
129 | } | ||
130 | |||
131 | |||
132 | void pal_set332(void) | ||
133 | { | ||
134 | int i, r, g, b; | ||
135 | |||
136 | fb.indexed = 0; | ||
137 | fb.cc[0].r = 5; | ||
138 | fb.cc[1].r = 5; | ||
139 | fb.cc[2].r = 6; | ||
140 | fb.cc[0].l = 0; | ||
141 | fb.cc[1].l = 3; | ||
142 | fb.cc[2].l = 6; | ||
143 | |||
144 | i = 0; | ||
145 | for (b = 0; b < 4; b++) for (g = 0; g < 8; g++) for (r = 0; r < 8; r++) | ||
146 | vid_setpal(i++, (r<<5)|(r<<2)|(r>>1), | ||
147 | (g<<5)|(g<<2)|(g>>1), (b<<6)|(b<<4)|(b<<2)|b); | ||
148 | } | ||
149 | |||
150 | |||
151 | |||
152 | |||
153 | |||
diff --git a/apps/plugins/rockboy/palette.h b/apps/plugins/rockboy/palette.h new file mode 100644 index 0000000000..05b093be77 --- /dev/null +++ b/apps/plugins/rockboy/palette.h | |||
@@ -0,0 +1,6 @@ | |||
1 | void pal_lock(byte n); | ||
2 | byte pal_getcolor(int c, int r, int g, int b); | ||
3 | void pal_release(byte n); | ||
4 | void pal_expire(void); | ||
5 | void pal_set332(void); | ||
6 | void vid_setpal(int i, int r, int g, int b); | ||
diff --git a/apps/plugins/rockboy/pcm.h b/apps/plugins/rockboy/pcm.h new file mode 100644 index 0000000000..3719933520 --- /dev/null +++ b/apps/plugins/rockboy/pcm.h | |||
@@ -0,0 +1,21 @@ | |||
1 | |||
2 | #ifndef __PCM_H__ | ||
3 | #define __PCM_H__ | ||
4 | |||
5 | |||
6 | #include "defs.h" | ||
7 | |||
8 | struct pcm | ||
9 | { | ||
10 | int hz, len; | ||
11 | int stereo; | ||
12 | byte *buf; | ||
13 | int pos; | ||
14 | }; | ||
15 | |||
16 | extern struct pcm pcm; | ||
17 | |||
18 | |||
19 | #endif | ||
20 | |||
21 | |||
diff --git a/apps/plugins/rockboy/rc.h b/apps/plugins/rockboy/rc.h new file mode 100644 index 0000000000..217b05f5c6 --- /dev/null +++ b/apps/plugins/rockboy/rc.h | |||
@@ -0,0 +1,71 @@ | |||
1 | |||
2 | |||
3 | |||
4 | #ifndef __RC_H__ | ||
5 | #define __RC_H__ | ||
6 | |||
7 | |||
8 | |||
9 | typedef enum rctype | ||
10 | { | ||
11 | rcv_end, | ||
12 | rcv_int, | ||
13 | rcv_string, | ||
14 | rcv_vector, | ||
15 | rcv_bool | ||
16 | } rcvtype_t; | ||
17 | |||
18 | |||
19 | typedef struct rcvar_s | ||
20 | { | ||
21 | char *name; | ||
22 | int type; | ||
23 | int len; | ||
24 | void *mem; | ||
25 | } rcvar_t; | ||
26 | |||
27 | #define RCV_END { 0, rcv_end, 0, 0 } | ||
28 | #define RCV_INT(n,v) { (n), rcv_int, 1, (v) } | ||
29 | #define RCV_STRING(n,v) { (n), rcv_string, 0, (v) } | ||
30 | #define RCV_VECTOR(n,v,l) { (n), rcv_vector, (l), (v) } | ||
31 | #define RCV_BOOL(n,v) { (n), rcv_bool, 1, (v) } | ||
32 | |||
33 | typedef struct rccmd_s | ||
34 | { | ||
35 | char *name; | ||
36 | int (*func)(int, char **); | ||
37 | } rccmd_t; | ||
38 | |||
39 | #define RCC(n,f) { (n), (f) } | ||
40 | #define RCC_END { 0, 0 } | ||
41 | |||
42 | void rc_export(rcvar_t *v); | ||
43 | void rc_exportvars(rcvar_t *vars); | ||
44 | |||
45 | int rc_findvar(char *name); | ||
46 | |||
47 | int rc_setvar_n(int i, int c, char **v); | ||
48 | int rc_setvar(char *name, int c, char **v); | ||
49 | |||
50 | int rc_getint_n(int i); | ||
51 | int *rc_getvec_n(int i); | ||
52 | char *rc_getstr_n(int i); | ||
53 | |||
54 | int rc_getint(char *name); | ||
55 | int *rc_getvec(char *name); | ||
56 | char *rc_getstr(char *name); | ||
57 | |||
58 | int rc_bindkey(char *keyname, char *cmd); | ||
59 | int rc_unbindkey(char *keyname); | ||
60 | void rc_unbindall(void); | ||
61 | |||
62 | int rc_sourcefile(char *filename); | ||
63 | void rc_dokey(int key, int st); | ||
64 | |||
65 | int rc_command(char *line); | ||
66 | |||
67 | #endif | ||
68 | |||
69 | |||
70 | |||
71 | |||
diff --git a/apps/plugins/rockboy/rccmds.c b/apps/plugins/rockboy/rccmds.c new file mode 100644 index 0000000000..c9375b69b5 --- /dev/null +++ b/apps/plugins/rockboy/rccmds.c | |||
@@ -0,0 +1,122 @@ | |||
1 | |||
2 | |||
3 | |||
4 | |||
5 | #include "rockmacros.h" | ||
6 | |||
7 | #include "defs.h" | ||
8 | #include "rc.h" | ||
9 | #include "hw.h" | ||
10 | #include "emu.h" | ||
11 | #include "save.h" | ||
12 | #include "split.h" | ||
13 | |||
14 | /* | ||
15 | * the set command is used to set rc-exported variables. | ||
16 | */ | ||
17 | |||
18 | static int cmd_set(int argc, char **argv) | ||
19 | { | ||
20 | if (argc < 3) | ||
21 | return -1; | ||
22 | return rc_setvar(argv[1], argc-2, argv+2); | ||
23 | } | ||
24 | |||
25 | |||
26 | |||
27 | /* | ||
28 | * the following commands allow keys to be bound to perform rc commands. | ||
29 | */ | ||
30 | |||
31 | static int cmd_reset(int argc, char **argv) | ||
32 | { | ||
33 | (void)argc; | ||
34 | (void)argv; | ||
35 | emu_reset(); | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static int cmd_savestate(int argc, char **argv) | ||
40 | { | ||
41 | state_save(argc > 1 ? atoi(argv[1]) : -1); | ||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | static int cmd_loadstate(int argc, char **argv) | ||
46 | { | ||
47 | state_load(argc > 1 ? atoi(argv[1]) : -1); | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | |||
52 | |||
53 | /* | ||
54 | * table of command names and the corresponding functions to be called | ||
55 | */ | ||
56 | |||
57 | rccmd_t rccmds[] = | ||
58 | { | ||
59 | RCC("set", cmd_set), | ||
60 | RCC("reset", cmd_reset), | ||
61 | RCC("savestate", cmd_savestate), | ||
62 | RCC("loadstate", cmd_loadstate), | ||
63 | RCC_END | ||
64 | }; | ||
65 | |||
66 | |||
67 | |||
68 | |||
69 | |||
70 | int rc_command(char *line) | ||
71 | { | ||
72 | int i, argc, ret; | ||
73 | char *argv[128], linecopy[500]; | ||
74 | |||
75 | // linecopy = malloc(strlen(line)+1); | ||
76 | strcpy(linecopy, line); | ||
77 | |||
78 | argc = splitline(argv, (sizeof argv)/(sizeof argv[0]), linecopy); | ||
79 | if (!argc) | ||
80 | { | ||
81 | // free(linecopy); | ||
82 | return -1; | ||
83 | } | ||
84 | |||
85 | for (i = 0; rccmds[i].name; i++) | ||
86 | { | ||
87 | if (!strcmp(argv[0], rccmds[i].name)) | ||
88 | { | ||
89 | ret = rccmds[i].func(argc, argv); | ||
90 | // free(linecopy); | ||
91 | return ret; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | /* printf("unknown command: %s\n", argv[0]); */ | ||
96 | // free(linecopy); | ||
97 | |||
98 | return -1; | ||
99 | } | ||
100 | |||
101 | |||
102 | |||
103 | |||
104 | |||
105 | |||
106 | |||
107 | |||
108 | |||
109 | |||
110 | |||
111 | |||
112 | |||
113 | |||
114 | |||
115 | |||
116 | |||
117 | |||
118 | |||
119 | |||
120 | |||
121 | |||
122 | |||
diff --git a/apps/plugins/rockboy/rcvars.c b/apps/plugins/rockboy/rcvars.c new file mode 100644 index 0000000000..e37657dbad --- /dev/null +++ b/apps/plugins/rockboy/rcvars.c | |||
@@ -0,0 +1,233 @@ | |||
1 | |||
2 | |||
3 | |||
4 | |||
5 | #include <string.h> | ||
6 | #include "rockmacros.h" | ||
7 | |||
8 | #include "defs.h" | ||
9 | #include "rc.h" | ||
10 | |||
11 | |||
12 | |||
13 | |||
14 | |||
15 | |||
16 | static rcvar_t rcvars[150]; | ||
17 | |||
18 | static int nvars; | ||
19 | |||
20 | |||
21 | |||
22 | |||
23 | |||
24 | void rc_export(rcvar_t *v) | ||
25 | { | ||
26 | const rcvar_t end = RCV_END; | ||
27 | |||
28 | if (!v) return; | ||
29 | nvars++; | ||
30 | // rcvars = realloc(rcvars, sizeof (rcvar_t) * (nvars+1)); | ||
31 | // if (!rcvars) | ||
32 | // die("out of memory adding rcvar %s\n", v->name); | ||
33 | rcvars[nvars-1] = *v; | ||
34 | rcvars[nvars] = end; | ||
35 | } | ||
36 | |||
37 | void rc_exportvars(rcvar_t *vars) | ||
38 | { | ||
39 | while(vars->type) | ||
40 | rc_export(vars++); | ||
41 | } | ||
42 | |||
43 | |||
44 | |||
45 | int rc_findvar(char *name) | ||
46 | { | ||
47 | int i; | ||
48 | if (!rcvars) return -1; | ||
49 | for (i = 0; rcvars[i].name; i++) | ||
50 | if (!strcmp(rcvars[i].name, name)) | ||
51 | break; | ||
52 | if (!rcvars[i].name) | ||
53 | return -1; | ||
54 | return i; | ||
55 | } | ||
56 | |||
57 | |||
58 | int my_atoi(const char *s) | ||
59 | { | ||
60 | int a = 0; | ||
61 | if (*s == '0') | ||
62 | { | ||
63 | s++; | ||
64 | if (*s == 'x' || *s == 'X') | ||
65 | { | ||
66 | s++; | ||
67 | while (*s) | ||
68 | { | ||
69 | if (isdigit(*s)) | ||
70 | a = (a<<4) + *s - '0'; | ||
71 | else if (strchr("ABCDEF", *s)) | ||
72 | a = (a<<4) + *s - 'A' + 10; | ||
73 | else if (strchr("abcdef", *s)) | ||
74 | a = (a<<4) + *s - 'a' + 10; | ||
75 | else return a; | ||
76 | s++; | ||
77 | } | ||
78 | return a; | ||
79 | } | ||
80 | while (*s) | ||
81 | { | ||
82 | if (strchr("01234567", *s)) | ||
83 | a = (a<<3) + *s - '0'; | ||
84 | else return a; | ||
85 | s++; | ||
86 | } | ||
87 | return a; | ||
88 | } | ||
89 | if (*s == '-') | ||
90 | { | ||
91 | s++; | ||
92 | for (;;) | ||
93 | { | ||
94 | if (isdigit(*s)) | ||
95 | a = (a*10) + *s - '0'; | ||
96 | else return -a; | ||
97 | s++; | ||
98 | } | ||
99 | } | ||
100 | while (*s) | ||
101 | { | ||
102 | if (isdigit(*s)) | ||
103 | a = (a*10) + *s - '0'; | ||
104 | else return a; | ||
105 | s++; | ||
106 | } | ||
107 | return a; | ||
108 | } | ||
109 | |||
110 | |||
111 | int rc_setvar_n(int i, int c, char **v) | ||
112 | { | ||
113 | int j; | ||
114 | int *n; | ||
115 | char **s; | ||
116 | |||
117 | switch (rcvars[i].type) | ||
118 | { | ||
119 | case rcv_int: | ||
120 | if (c < 1) return -1; | ||
121 | n = (int *)rcvars[i].mem; | ||
122 | *n = my_atoi(v[0]); | ||
123 | return 0; | ||
124 | case rcv_string: | ||
125 | if (c < 1) return -1; | ||
126 | s = (char **)rcvars[i].mem; | ||
127 | // if (*s) free(*s); | ||
128 | strcpy(*s,v[0]); | ||
129 | if (!*s) | ||
130 | die("out of memory setting rcvar %s\n", rcvars[i].name); | ||
131 | return 0; | ||
132 | case rcv_vector: | ||
133 | if (c > rcvars[i].len) | ||
134 | c = rcvars[i].len; | ||
135 | for (j = 0; j < c ; j++) | ||
136 | ((int *)rcvars[i].mem)[j] = my_atoi(v[j]); | ||
137 | return 0; | ||
138 | case rcv_bool: | ||
139 | if (c < 1 || atoi(v[0]) || strchr("yYtT", v[0][0])) | ||
140 | *(int *)rcvars[i].mem = 1; | ||
141 | else if (strchr("0nNfF", v[0][0])) | ||
142 | *(int *)rcvars[i].mem = 0; | ||
143 | else | ||
144 | return -1; | ||
145 | return 0; | ||
146 | } | ||
147 | return -1; | ||
148 | } | ||
149 | |||
150 | |||
151 | int rc_setvar(char *name, int c, char **v) | ||
152 | { | ||
153 | int i; | ||
154 | |||
155 | i = rc_findvar(name); | ||
156 | if (i < 0) return i; | ||
157 | |||
158 | return rc_setvar_n(i, c, v); | ||
159 | } | ||
160 | |||
161 | |||
162 | void *rc_getmem_n(int i) | ||
163 | { | ||
164 | return rcvars[i].mem; | ||
165 | } | ||
166 | |||
167 | |||
168 | void *rc_getmem(char *name) | ||
169 | { | ||
170 | int i; | ||
171 | i = rc_findvar(name); | ||
172 | if (i < 0) return NULL; | ||
173 | return rcvars[i].mem; | ||
174 | } | ||
175 | |||
176 | int rc_getint_n(int i) | ||
177 | { | ||
178 | if (i < 0) return 0; | ||
179 | switch (rcvars[i].type) | ||
180 | { | ||
181 | case rcv_int: | ||
182 | case rcv_bool: | ||
183 | return *(int *)rcvars[i].mem; | ||
184 | } | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | int *rc_getvec_n(int i) | ||
189 | { | ||
190 | if (i < 0) return NULL; | ||
191 | switch (rcvars[i].type) | ||
192 | { | ||
193 | case rcv_int: | ||
194 | case rcv_bool: | ||
195 | case rcv_vector: | ||
196 | return (int *)rcvars[i].mem; | ||
197 | } | ||
198 | return NULL; | ||
199 | } | ||
200 | |||
201 | char *rc_getstr_n(int i) | ||
202 | { | ||
203 | if (i < 0) return 0; | ||
204 | switch (rcvars[i].type) | ||
205 | { | ||
206 | case rcv_string: | ||
207 | return *(char **)rcvars[i].mem; | ||
208 | } | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | int rc_getint(char *name) | ||
213 | { | ||
214 | return rc_getint_n(rc_findvar(name)); | ||
215 | } | ||
216 | |||
217 | int *rc_getvec(char *name) | ||
218 | { | ||
219 | return rc_getvec_n(rc_findvar(name)); | ||
220 | } | ||
221 | |||
222 | char *rc_getstr(char *name) | ||
223 | { | ||
224 | return rc_getstr_n(rc_findvar(name)); | ||
225 | } | ||
226 | |||
227 | |||
228 | |||
229 | |||
230 | |||
231 | |||
232 | |||
233 | |||
diff --git a/apps/plugins/rockboy/regs.h b/apps/plugins/rockboy/regs.h new file mode 100644 index 0000000000..4457fd90ed --- /dev/null +++ b/apps/plugins/rockboy/regs.h | |||
@@ -0,0 +1,181 @@ | |||
1 | |||
2 | #ifndef __REGS_H__ | ||
3 | #define __REGS_H__ | ||
4 | |||
5 | |||
6 | #include "mem.h" | ||
7 | |||
8 | /* General internal/io stuff */ | ||
9 | |||
10 | #define RI_P1 0x00 | ||
11 | #define RI_SB 0x01 | ||
12 | #define RI_SC 0x02 | ||
13 | #define RI_DIV 0x04 | ||
14 | #define RI_TIMA 0x05 | ||
15 | #define RI_TMA 0x06 | ||
16 | #define RI_TAC 0x07 | ||
17 | |||
18 | #define RI_KEY1 0x4D | ||
19 | |||
20 | #define RI_RP 0x56 | ||
21 | |||
22 | #define RI_SVBK 0x70 | ||
23 | |||
24 | |||
25 | |||
26 | /* Interrupts flags */ | ||
27 | |||
28 | #define RI_IF 0x0F | ||
29 | #define RI_IE 0xFF | ||
30 | |||
31 | |||
32 | |||
33 | |||
34 | /* LCDC */ | ||
35 | |||
36 | #define RI_LCDC 0x40 | ||
37 | #define RI_STAT 0x41 | ||
38 | #define RI_SCY 0x42 | ||
39 | #define RI_SCX 0x43 | ||
40 | #define RI_LY 0x44 | ||
41 | #define RI_LYC 0x45 | ||
42 | #define RI_DMA 0x46 | ||
43 | #define RI_BGP 0x47 | ||
44 | #define RI_OBP0 0x48 | ||
45 | #define RI_OBP1 0x49 | ||
46 | #define RI_WY 0x4A | ||
47 | #define RI_WX 0x4B | ||
48 | |||
49 | #define RI_VBK 0x4F | ||
50 | |||
51 | #define RI_HDMA1 0x51 | ||
52 | #define RI_HDMA2 0x52 | ||
53 | #define RI_HDMA3 0x53 | ||
54 | #define RI_HDMA4 0x54 | ||
55 | #define RI_HDMA5 0x55 | ||
56 | |||
57 | #define RI_BCPS 0x68 | ||
58 | #define RI_BCPD 0x69 | ||
59 | #define RI_OCPS 0x6A | ||
60 | #define RI_OCPD 0x6B | ||
61 | |||
62 | |||
63 | |||
64 | /* Sound */ | ||
65 | |||
66 | #define RI_NR10 0x10 | ||
67 | #define RI_NR11 0x11 | ||
68 | #define RI_NR12 0x12 | ||
69 | #define RI_NR13 0x13 | ||
70 | #define RI_NR14 0x14 | ||
71 | #define RI_NR21 0x16 | ||
72 | #define RI_NR22 0x17 | ||
73 | #define RI_NR23 0x18 | ||
74 | #define RI_NR24 0x19 | ||
75 | #define RI_NR30 0x1A | ||
76 | #define RI_NR31 0x1B | ||
77 | #define RI_NR32 0x1C | ||
78 | #define RI_NR33 0x1D | ||
79 | #define RI_NR34 0x1E | ||
80 | #define RI_NR41 0x20 | ||
81 | #define RI_NR42 0x21 | ||
82 | #define RI_NR43 0x22 | ||
83 | #define RI_NR44 0x23 | ||
84 | #define RI_NR50 0x24 | ||
85 | #define RI_NR51 0x25 | ||
86 | #define RI_NR52 0x26 | ||
87 | |||
88 | |||
89 | |||
90 | #define REG(n) ram.hi[(n)] | ||
91 | |||
92 | |||
93 | |||
94 | /* General internal/io stuff */ | ||
95 | |||
96 | #define R_P1 REG(RI_P1) | ||
97 | #define R_SB REG(RI_SB) | ||
98 | #define R_SC REG(RI_SC) | ||
99 | #define R_DIV REG(RI_DIV) | ||
100 | #define R_TIMA REG(RI_TIMA) | ||
101 | #define R_TMA REG(RI_TMA) | ||
102 | #define R_TAC REG(RI_TAC) | ||
103 | |||
104 | #define R_KEY1 REG(RI_KEY1) | ||
105 | |||
106 | #define R_RP REG(RI_RP) | ||
107 | |||
108 | #define R_SVBK REG(RI_SVBK) | ||
109 | |||
110 | |||
111 | |||
112 | /* Interrupts flags */ | ||
113 | |||
114 | #define R_IF REG(RI_IF) | ||
115 | #define R_IE REG(RI_IE) | ||
116 | |||
117 | |||
118 | |||
119 | |||
120 | /* LCDC */ | ||
121 | |||
122 | #define R_LCDC REG(RI_LCDC) | ||
123 | #define R_STAT REG(RI_STAT) | ||
124 | #define R_SCY REG(RI_SCY) | ||
125 | #define R_SCX REG(RI_SCX) | ||
126 | #define R_LY REG(RI_LY) | ||
127 | #define R_LYC REG(RI_LYC) | ||
128 | #define R_DMA REG(RI_DMA) | ||
129 | #define R_BGP REG(RI_BGP) | ||
130 | #define R_OBP0 REG(RI_OBP0) | ||
131 | #define R_OBP1 REG(RI_OBP1) | ||
132 | #define R_WY REG(RI_WY) | ||
133 | #define R_WX REG(RI_WX) | ||
134 | |||
135 | #define R_VBK REG(RI_VBK) | ||
136 | |||
137 | #define R_HDMA1 REG(RI_HDMA1) | ||
138 | #define R_HDMA2 REG(RI_HDMA2) | ||
139 | #define R_HDMA3 REG(RI_HDMA3) | ||
140 | #define R_HDMA4 REG(RI_HDMA4) | ||
141 | #define R_HDMA5 REG(RI_HDMA5) | ||
142 | |||
143 | #define R_BCPS REG(RI_BCPS) | ||
144 | #define R_BCPD REG(RI_BCPD) | ||
145 | #define R_OCPS REG(RI_OCPS) | ||
146 | #define R_OCPD REG(RI_OCPD) | ||
147 | |||
148 | |||
149 | |||
150 | /* Sound */ | ||
151 | |||
152 | #define R_NR10 REG(RI_NR10) | ||
153 | #define R_NR11 REG(RI_NR11) | ||
154 | #define R_NR12 REG(RI_NR12) | ||
155 | #define R_NR13 REG(RI_NR13) | ||
156 | #define R_NR14 REG(RI_NR14) | ||
157 | #define R_NR21 REG(RI_NR21) | ||
158 | #define R_NR22 REG(RI_NR22) | ||
159 | #define R_NR23 REG(RI_NR23) | ||
160 | #define R_NR24 REG(RI_NR24) | ||
161 | #define R_NR30 REG(RI_NR30) | ||
162 | #define R_NR31 REG(RI_NR31) | ||
163 | #define R_NR32 REG(RI_NR32) | ||
164 | #define R_NR33 REG(RI_NR33) | ||
165 | #define R_NR34 REG(RI_NR34) | ||
166 | #define R_NR41 REG(RI_NR41) | ||
167 | #define R_NR42 REG(RI_NR42) | ||
168 | #define R_NR43 REG(RI_NR43) | ||
169 | #define R_NR44 REG(RI_NR44) | ||
170 | #define R_NR50 REG(RI_NR50) | ||
171 | #define R_NR51 REG(RI_NR51) | ||
172 | #define R_NR52 REG(RI_NR52) | ||
173 | |||
174 | |||
175 | |||
176 | #endif | ||
177 | |||
178 | |||
179 | |||
180 | |||
181 | |||
diff --git a/apps/plugins/rockboy/rockboy.c b/apps/plugins/rockboy/rockboy.c new file mode 100644 index 0000000000..c9788e2438 --- /dev/null +++ b/apps/plugins/rockboy/rockboy.c | |||
@@ -0,0 +1,137 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Gameboy emulator based on gnuboy | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "plugin.h" | ||
20 | #include "loader.h" | ||
21 | #include "rockmacros.h" | ||
22 | |||
23 | #if MEM <= 8 && !defined(SIMULATOR) | ||
24 | /* On archos this is loaded as an overlay */ | ||
25 | |||
26 | /* These are defined in the linker script */ | ||
27 | extern unsigned char ovl_start_addr[]; | ||
28 | extern unsigned char ovl_end_addr[]; | ||
29 | |||
30 | const struct { | ||
31 | unsigned long magic; | ||
32 | unsigned char *start_addr; | ||
33 | unsigned char *end_addr; | ||
34 | enum plugin_status (*entry_point)(struct plugin_api*, void*); | ||
35 | } header __attribute__ ((section (".header"))) = { | ||
36 | 0x524f564c, /* ROVL */ | ||
37 | ovl_start_addr, ovl_end_addr, plugin_start | ||
38 | }; | ||
39 | #endif | ||
40 | |||
41 | /* here is a global api struct pointer. while not strictly necessary, | ||
42 | it's nice not to have to pass the api pointer in all function calls | ||
43 | in the plugin */ | ||
44 | struct plugin_api* rb; | ||
45 | int shut,cleanshut; | ||
46 | char *errormsg; | ||
47 | int gnuboy_main(char *rom); | ||
48 | |||
49 | /* libc functions */ | ||
50 | |||
51 | int isdigit(int c) { | ||
52 | return c>='0' && c<= '9'; | ||
53 | } | ||
54 | |||
55 | int isalpha(int c) { | ||
56 | return (c>='a' && c<='z')||(c>='A' && c<='Z'); | ||
57 | } | ||
58 | |||
59 | int isupper(int c) { | ||
60 | return c>='A'&&c<='Z'; | ||
61 | } | ||
62 | |||
63 | int isalnum(int c) { | ||
64 | return isdigit(c)||isalpha(c); | ||
65 | } | ||
66 | |||
67 | void die(char *message, ...) | ||
68 | { | ||
69 | shut=1; | ||
70 | errormsg=message; | ||
71 | } | ||
72 | |||
73 | void *mp3_bufferbase; | ||
74 | void *mp3_bufferpointer; | ||
75 | unsigned int mp3_buffer_free; | ||
76 | |||
77 | void *my_malloc(size_t size) | ||
78 | { | ||
79 | void *alloc; | ||
80 | |||
81 | if (!mp3_bufferbase) | ||
82 | { | ||
83 | mp3_bufferbase = mp3_bufferpointer | ||
84 | = rb->plugin_get_mp3_buffer(&mp3_buffer_free); | ||
85 | #if MEM <= 8 && !defined(SIMULATOR) | ||
86 | /* loaded as an overlay, protect from overwriting ourselves */ | ||
87 | if ((unsigned)(ovl_start_addr - (unsigned char *)mp3_bufferbase) | ||
88 | < mp3_buffer_free) | ||
89 | mp3_buffer_free = ovl_start_addr - (unsigned char *)mp3_bufferbase; | ||
90 | #endif | ||
91 | } | ||
92 | if (size + 4 > mp3_buffer_free) | ||
93 | return 0; | ||
94 | alloc = mp3_bufferpointer; | ||
95 | mp3_bufferpointer += size + 4; | ||
96 | mp3_buffer_free -= size + 4; | ||
97 | return alloc; | ||
98 | } | ||
99 | |||
100 | void setmallocpos(void *pointer) | ||
101 | { | ||
102 | mp3_bufferpointer = pointer; | ||
103 | mp3_buffer_free = mp3_bufferpointer - mp3_bufferbase; | ||
104 | } | ||
105 | |||
106 | /* this is the plugin entry point */ | ||
107 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
108 | { | ||
109 | /* this macro should be called as the first thing you do in the plugin. | ||
110 | it test that the api version and model the plugin was compiled for | ||
111 | matches the machine it is running on */ | ||
112 | TEST_PLUGIN_API(api); | ||
113 | |||
114 | /* if you are using a global api pointer, don't forget to copy it! | ||
115 | otherwise you will get lovely "I04: IllInstr" errors... :-) */ | ||
116 | rb = api; | ||
117 | shut=0; | ||
118 | cleanshut=0; | ||
119 | mp3_bufferbase=mp3_bufferpointer=0; | ||
120 | mp3_buffer_free=0; | ||
121 | |||
122 | /* now go ahead and have fun! */ | ||
123 | rb->splash(HZ*2, true, "Rockboy v0.3"); | ||
124 | rb->lcd_clear_display(); | ||
125 | gnuboy_main(parameter); | ||
126 | |||
127 | if(shut&&!cleanshut) { | ||
128 | rb->splash(HZ*2, true, errormsg); | ||
129 | return PLUGIN_ERROR; | ||
130 | } | ||
131 | |||
132 | rb->splash(HZ*2, true, "Shutting down.. byebye ^^"); | ||
133 | |||
134 | cleanup(); | ||
135 | |||
136 | return PLUGIN_OK; | ||
137 | } | ||
diff --git a/apps/plugins/rockboy/rockmacros.h b/apps/plugins/rockboy/rockmacros.h new file mode 100644 index 0000000000..63f9b106e9 --- /dev/null +++ b/apps/plugins/rockboy/rockmacros.h | |||
@@ -0,0 +1,88 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 Michiel van der Kolk, Jens Arnold | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include <plugin.h> | ||
21 | |||
22 | /* workaround for cygwin not defining endian macros */ | ||
23 | #if !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN) && defined(_X86_) | ||
24 | #define LITTLE_ENDIAN | ||
25 | #endif | ||
26 | |||
27 | #define malloc(a) my_malloc(a) | ||
28 | void *my_malloc(size_t size); | ||
29 | |||
30 | extern struct plugin_api* rb; | ||
31 | extern int shut,cleanshut; | ||
32 | void vid_update(int scanline); | ||
33 | void vid_init(void); | ||
34 | void vid_begin(void); | ||
35 | void vid_end(void); | ||
36 | void die(char *message, ...); | ||
37 | void setmallocpos(void *pointer); | ||
38 | void vid_settitle(char *title); | ||
39 | void *sys_timer(void); | ||
40 | int sys_elapsed(long *oldtick); | ||
41 | void sys_sleep(int us); | ||
42 | int pcm_submit(void); | ||
43 | void pcm_init(void); | ||
44 | void doevents(void); | ||
45 | int isupper(int c); | ||
46 | int isdigit(int c); | ||
47 | void ev_poll(void); | ||
48 | |||
49 | #ifdef SIMULATOR | ||
50 | #undef opendir | ||
51 | #define opendir(a) rb->sim_opendir((a)) | ||
52 | #undef closedir | ||
53 | #define closedir(a) rb->sim_closedir((a)) | ||
54 | #undef mkdir | ||
55 | #define mkdir(a,b) rb->sim_mkdir((a),(b)) | ||
56 | #undef open | ||
57 | #define open(a,b) rb->sim_open((a),(b)) | ||
58 | #undef lseek | ||
59 | #define lseek(a,b,c) rb->sim_lseek((a),(b),(c)) | ||
60 | #else /* !SIMULATOR */ | ||
61 | #define opendir(a) rb->opendir((a)) | ||
62 | #define closedir(a) rb->closedir((a)) | ||
63 | #define mkdir(a,b) rb->mkdir((a),(b)) | ||
64 | #define open(a,b) rb->open((a),(b)) | ||
65 | #define lseek(a,b,c) rb->lseek((a),(b),(c)) | ||
66 | #endif /* !SIMULATOR */ | ||
67 | |||
68 | #define strcat(a,b) rb->strcat((a),(b)) | ||
69 | #define close(a) rb->close((a)) | ||
70 | #define read(a,b,c) rb->read((a),(b),(c)) | ||
71 | #define write(a,b,c) rb->write((a),(b),(c)) | ||
72 | #define memset(a,b,c) rb->memset((a),(b),(c)) | ||
73 | #define memcpy(a,b,c) rb->memcpy((a),(b),(c)) | ||
74 | #define strcpy(a,b) rb->strcpy((a),(b)) | ||
75 | #define strncpy(a,b,c) rb->strncpy((a),(b),(c)) | ||
76 | #define strlen(a) rb->strlen((a)) | ||
77 | #define strcmp(a,b) rb->strcmp((a),(b)) | ||
78 | #define strchr(a,b) rb->strchr((a),(b)) | ||
79 | #define strrchr(a,b) rb->strrchr((a),(b)) | ||
80 | #define strcasecmp(a,b) rb->strcasecmp((a),(b)) | ||
81 | #define srand(a) rb->srand((a)) | ||
82 | #define rand() rb->rand() | ||
83 | #define atoi(a) rb->atoi((a)) | ||
84 | #define strcat(a,b) rb->strcat((a),(b)) | ||
85 | #define snprintf(...) rb->snprintf(__VA_ARGS__) | ||
86 | #define fprintf(...) rb->fdprintf(__VA_ARGS__) | ||
87 | #define tolower(_A_) (isupper(_A_) ? (_A_ - 'A' + 'a') : _A_) | ||
88 | |||
diff --git a/apps/plugins/rockboy/rtc.c b/apps/plugins/rockboy/rtc.c new file mode 100644 index 0000000000..99e71dcfae --- /dev/null +++ b/apps/plugins/rockboy/rtc.c | |||
@@ -0,0 +1,135 @@ | |||
1 | |||
2 | |||
3 | |||
4 | #include "rockmacros.h" | ||
5 | #include <stdio.h> | ||
6 | |||
7 | #include "defs.h" | ||
8 | #include "mem.h" | ||
9 | #include "rtc.h" | ||
10 | #include "rc.h" | ||
11 | |||
12 | struct rtc rtc; | ||
13 | |||
14 | static int syncrtc = 1; | ||
15 | |||
16 | rcvar_t rtc_exports[] = | ||
17 | { | ||
18 | RCV_BOOL("syncrtc", &syncrtc), | ||
19 | RCV_END | ||
20 | }; | ||
21 | |||
22 | |||
23 | void rtc_latch(byte b) | ||
24 | { | ||
25 | if ((rtc.latch ^ b) & b & 1) | ||
26 | { | ||
27 | rtc.regs[0] = rtc.s; | ||
28 | rtc.regs[1] = rtc.m; | ||
29 | rtc.regs[2] = rtc.h; | ||
30 | rtc.regs[3] = rtc.d; | ||
31 | rtc.regs[4] = (rtc.d>>9) | (rtc.stop<<6) | (rtc.carry<<7); | ||
32 | rtc.regs[5] = 0xff; | ||
33 | rtc.regs[6] = 0xff; | ||
34 | rtc.regs[7] = 0xff; | ||
35 | } | ||
36 | rtc.latch = b; | ||
37 | } | ||
38 | |||
39 | void rtc_write(byte b) | ||
40 | { | ||
41 | /* printf("write %02X: %02X (%d)\n", rtc.sel, b, b); */ | ||
42 | if (!(rtc.sel & 8)) return; | ||
43 | switch (rtc.sel & 7) | ||
44 | { | ||
45 | case 0: | ||
46 | rtc.s = rtc.regs[0] = b; | ||
47 | while (rtc.s >= 60) rtc.s -= 60; | ||
48 | break; | ||
49 | case 1: | ||
50 | rtc.m = rtc.regs[1] = b; | ||
51 | while (rtc.m >= 60) rtc.m -= 60; | ||
52 | break; | ||
53 | case 2: | ||
54 | rtc.h = rtc.regs[2] = b; | ||
55 | while (rtc.h >= 24) rtc.h -= 24; | ||
56 | break; | ||
57 | case 3: | ||
58 | rtc.regs[3] = b; | ||
59 | rtc.d = (rtc.d & 0x100) | b; | ||
60 | break; | ||
61 | case 4: | ||
62 | rtc.regs[4] = b; | ||
63 | rtc.d = (rtc.d & 0xff) | ((b&1)<<9); | ||
64 | rtc.stop = (b>>6)&1; | ||
65 | rtc.carry = (b>>7)&1; | ||
66 | break; | ||
67 | } | ||
68 | } | ||
69 | |||
70 | void rtc_tick() | ||
71 | { | ||
72 | if (rtc.stop) return; | ||
73 | if (++rtc.t == 60) | ||
74 | { | ||
75 | if (++rtc.s == 60) | ||
76 | { | ||
77 | if (++rtc.m == 60) | ||
78 | { | ||
79 | if (++rtc.h == 24) | ||
80 | { | ||
81 | if (++rtc.d == 365) | ||
82 | { | ||
83 | rtc.d = 0; | ||
84 | rtc.carry = 1; | ||
85 | } | ||
86 | rtc.h = 0; | ||
87 | } | ||
88 | rtc.m = 0; | ||
89 | } | ||
90 | rtc.s = 0; | ||
91 | } | ||
92 | rtc.t = 0; | ||
93 | } | ||
94 | } | ||
95 | |||
96 | void rtc_save_internal(int fd) | ||
97 | { | ||
98 | (void)fd; // stop compiler complaining | ||
99 | // TODO | ||
100 | // fprintf(f, "%d %d %d %02d %02d %02d %02d\n%d\n", | ||
101 | // rtc.carry, rtc.stop, rtc.d, rtc.h, rtc.m, rtc.s, rtc.t, | ||
102 | // time(0)); | ||
103 | } | ||
104 | |||
105 | void rtc_load_internal(int fd) | ||
106 | { | ||
107 | //int rt = 0; | ||
108 | (void)fd; // stop compiler complaining | ||
109 | // TODO | ||
110 | /* fscanf( | ||
111 | f, "%d %d %d %02d %02d %02d %02d\n%d\n", | ||
112 | &rtc.carry, &rtc.stop, &rtc.d, | ||
113 | &rtc.h, &rtc.m, &rtc.s, &rtc.t, &rt); | ||
114 | while (rtc.t >= 60) rtc.t -= 60; | ||
115 | while (rtc.s >= 60) rtc.s -= 60; | ||
116 | while (rtc.m >= 60) rtc.m -= 60; | ||
117 | while (rtc.h >= 24) rtc.h -= 24; | ||
118 | while (rtc.d >= 365) rtc.d -= 365; | ||
119 | rtc.stop &= 1; | ||
120 | rtc.carry &= 1; | ||
121 | if (rt) rt = (time(0) - rt) * 60; | ||
122 | if (syncrtc) while (rt-- > 0) rtc_tick(); */ | ||
123 | } | ||
124 | |||
125 | |||
126 | |||
127 | |||
128 | |||
129 | |||
130 | |||
131 | |||
132 | |||
133 | |||
134 | |||
135 | |||
diff --git a/apps/plugins/rockboy/rtc.h b/apps/plugins/rockboy/rtc.h new file mode 100644 index 0000000000..2665cd81c3 --- /dev/null +++ b/apps/plugins/rockboy/rtc.h | |||
@@ -0,0 +1,25 @@ | |||
1 | |||
2 | |||
3 | #ifndef __RTC_H__ | ||
4 | #define __RTC_H__ | ||
5 | |||
6 | |||
7 | struct rtc | ||
8 | { | ||
9 | int batt; | ||
10 | int sel; | ||
11 | int latch; | ||
12 | int d, h, m, s, t; | ||
13 | int stop, carry; | ||
14 | byte regs[8]; | ||
15 | }; | ||
16 | |||
17 | extern struct rtc rtc; | ||
18 | |||
19 | void rtc_latch(byte b); | ||
20 | void rtc_write(byte b); | ||
21 | void rtc_tick(void); | ||
22 | void rtc_save_internal(int fd); | ||
23 | void rtc_load_internal(int fd); | ||
24 | |||
25 | #endif | ||
diff --git a/apps/plugins/rockboy/save.c b/apps/plugins/rockboy/save.c new file mode 100644 index 0000000000..bb9f905b8f --- /dev/null +++ b/apps/plugins/rockboy/save.c | |||
@@ -0,0 +1,286 @@ | |||
1 | |||
2 | |||
3 | #include "rockmacros.h" | ||
4 | #include <stdio.h> | ||
5 | |||
6 | #include "defs.h" | ||
7 | #include "cpu.h" | ||
8 | #include "cpuregs.h" | ||
9 | #include "hw.h" | ||
10 | #include "regs.h" | ||
11 | #include "lcd.h" | ||
12 | #include "rtc.h" | ||
13 | #include "mem.h" | ||
14 | #include "sound.h" | ||
15 | |||
16 | |||
17 | |||
18 | #ifdef LITTLE_ENDIAN | ||
19 | #define LIL(x) (x) | ||
20 | #else | ||
21 | #define LIL(x) ((x<<24)|((x&0xff00)<<8)|((x>>8)&0xff00)|(x>>24)) | ||
22 | #endif | ||
23 | |||
24 | #define I1(s, p) { 1, s, p } | ||
25 | #define I2(s, p) { 2, s, p } | ||
26 | #define I4(s, p) { 4, s, p } | ||
27 | #define R(r) I1(#r, &R_##r) | ||
28 | #define NOSAVE { -1, "\0\0\0\0", 0 } | ||
29 | #define END { 0, "\0\0\0\0", 0 } | ||
30 | |||
31 | struct svar | ||
32 | { | ||
33 | int len; | ||
34 | char key[4]; | ||
35 | void *ptr; | ||
36 | }; | ||
37 | |||
38 | static int ver; | ||
39 | static int sramblock, iramblock, vramblock; | ||
40 | static int hramofs, hiofs, palofs, oamofs, wavofs; | ||
41 | |||
42 | struct svar svars[] = | ||
43 | { | ||
44 | I4("GbSs", &ver), | ||
45 | |||
46 | I2("PC ", &PC), | ||
47 | I2("SP ", &SP), | ||
48 | I2("BC ", &BC), | ||
49 | I2("DE ", &DE), | ||
50 | I2("HL ", &HL), | ||
51 | I2("AF ", &AF), | ||
52 | |||
53 | I4("IME ", &cpu.ime), | ||
54 | I4("ima ", &cpu.ima), | ||
55 | I4("spd ", &cpu.speed), | ||
56 | I4("halt", &cpu.halt), | ||
57 | I4("div ", &cpu.div), | ||
58 | I4("tim ", &cpu.tim), | ||
59 | I4("lcdc", &cpu.lcdc), | ||
60 | I4("snd ", &cpu.snd), | ||
61 | |||
62 | I1("ints", &hw.ilines), | ||
63 | I1("pad ", &hw.pad), | ||
64 | I4("cgb ", &hw.cgb), | ||
65 | I4("gba ", &hw.gba), | ||
66 | |||
67 | I4("mbcm", &mbc.model), | ||
68 | I4("romb", &mbc.rombank), | ||
69 | I4("ramb", &mbc.rambank), | ||
70 | I4("enab", &mbc.enableram), | ||
71 | I4("batt", &mbc.batt), | ||
72 | |||
73 | I4("rtcR", &rtc.sel), | ||
74 | I4("rtcL", &rtc.latch), | ||
75 | I4("rtcC", &rtc.carry), | ||
76 | I4("rtcS", &rtc.stop), | ||
77 | I4("rtcd", &rtc.d), | ||
78 | I4("rtch", &rtc.h), | ||
79 | I4("rtcm", &rtc.m), | ||
80 | I4("rtcs", &rtc.s), | ||
81 | I4("rtct", &rtc.t), | ||
82 | I1("rtR8", &rtc.regs[0]), | ||
83 | I1("rtR9", &rtc.regs[1]), | ||
84 | I1("rtRA", &rtc.regs[2]), | ||
85 | I1("rtRB", &rtc.regs[3]), | ||
86 | I1("rtRC", &rtc.regs[4]), | ||
87 | |||
88 | I4("S1on", &snd.ch[0].on), | ||
89 | I4("S1p ", &snd.ch[0].pos), | ||
90 | I4("S1c ", &snd.ch[0].cnt), | ||
91 | I4("S1ec", &snd.ch[0].encnt), | ||
92 | I4("S1sc", &snd.ch[0].swcnt), | ||
93 | I4("S1sf", &snd.ch[0].swfreq), | ||
94 | |||
95 | I4("S2on", &snd.ch[1].on), | ||
96 | I4("S2p ", &snd.ch[1].pos), | ||
97 | I4("S2c ", &snd.ch[1].cnt), | ||
98 | I4("S2ec", &snd.ch[1].encnt), | ||
99 | |||
100 | I4("S3on", &snd.ch[2].on), | ||
101 | I4("S3p ", &snd.ch[2].pos), | ||
102 | I4("S3c ", &snd.ch[2].cnt), | ||
103 | |||
104 | I4("S4on", &snd.ch[3].on), | ||
105 | I4("S4p ", &snd.ch[3].pos), | ||
106 | I4("S4c ", &snd.ch[3].cnt), | ||
107 | I4("S4ec", &snd.ch[3].encnt), | ||
108 | |||
109 | I4("hdma", &hw.hdma), | ||
110 | |||
111 | I4("sram", &sramblock), | ||
112 | I4("iram", &iramblock), | ||
113 | I4("vram", &vramblock), | ||
114 | I4("hi ", &hiofs), | ||
115 | I4("pal ", &palofs), | ||
116 | I4("oam ", &oamofs), | ||
117 | I4("wav ", &wavofs), | ||
118 | |||
119 | /* NOSAVE is a special code to prevent the rest of the table | ||
120 | * from being saved, used to support old stuff for backwards | ||
121 | * compatibility... */ | ||
122 | NOSAVE, | ||
123 | |||
124 | /* the following are obsolete as of 0x104 */ | ||
125 | |||
126 | I4("hram", &hramofs), | ||
127 | |||
128 | R(P1), R(SB), R(SC), | ||
129 | R(DIV), R(TIMA), R(TMA), R(TAC), | ||
130 | R(IE), R(IF), | ||
131 | R(LCDC), R(STAT), R(LY), R(LYC), | ||
132 | R(SCX), R(SCY), R(WX), R(WY), | ||
133 | R(BGP), R(OBP0), R(OBP1), | ||
134 | R(DMA), | ||
135 | |||
136 | R(VBK), R(SVBK), R(KEY1), | ||
137 | R(BCPS), R(BCPD), R(OCPS), R(OCPD), | ||
138 | |||
139 | R(NR10), R(NR11), R(NR12), R(NR13), R(NR14), | ||
140 | R(NR21), R(NR22), R(NR23), R(NR24), | ||
141 | R(NR30), R(NR31), R(NR32), R(NR33), R(NR34), | ||
142 | R(NR41), R(NR42), R(NR43), R(NR44), | ||
143 | R(NR50), R(NR51), R(NR52), | ||
144 | |||
145 | I1("DMA1", &R_HDMA1), | ||
146 | I1("DMA2", &R_HDMA2), | ||
147 | I1("DMA3", &R_HDMA3), | ||
148 | I1("DMA4", &R_HDMA4), | ||
149 | I1("DMA5", &R_HDMA5), | ||
150 | |||
151 | END | ||
152 | }; | ||
153 | |||
154 | |||
155 | void loadstate(int fd) | ||
156 | { | ||
157 | int i, j; | ||
158 | byte buf[4096]; | ||
159 | un32 (*header)[2] = (un32 (*)[2])buf; | ||
160 | un32 d; | ||
161 | int irl = hw.cgb ? 8 : 2; | ||
162 | int vrl = hw.cgb ? 4 : 2; | ||
163 | int srl = mbc.ramsize << 1; | ||
164 | |||
165 | ver = hramofs = hiofs = palofs = oamofs = wavofs = 0; | ||
166 | |||
167 | read(fd,buf, 4096); | ||
168 | |||
169 | for (j = 0; header[j][0]; j++) | ||
170 | { | ||
171 | for (i = 0; svars[i].ptr; i++) | ||
172 | { | ||
173 | if (header[j][0] != *(un32 *)svars[i].key) | ||
174 | continue; | ||
175 | d = LIL(header[j][1]); | ||
176 | switch (svars[i].len) | ||
177 | { | ||
178 | case 1: | ||
179 | *(byte *)svars[i].ptr = d; | ||
180 | break; | ||
181 | case 2: | ||
182 | *(un16 *)svars[i].ptr = d; | ||
183 | break; | ||
184 | case 4: | ||
185 | *(un32 *)svars[i].ptr = d; | ||
186 | break; | ||
187 | } | ||
188 | break; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | /* obsolete as of version 0x104 */ | ||
193 | if (hramofs) memcpy(ram.hi+128, buf+hramofs, 127); | ||
194 | |||
195 | if (hiofs) memcpy(ram.hi, buf+hiofs, sizeof ram.hi); | ||
196 | if (palofs) memcpy(lcd.pal, buf+palofs, sizeof lcd.pal); | ||
197 | if (oamofs) memcpy(lcd.oam.mem, buf+oamofs, sizeof lcd.oam); | ||
198 | |||
199 | if (wavofs) memcpy(snd.wave, buf+wavofs, sizeof snd.wave); | ||
200 | else memcpy(snd.wave, ram.hi+0x30, 16); /* patch data from older files */ | ||
201 | |||
202 | lseek(fd, iramblock<<12, SEEK_SET); | ||
203 | read(fd,ram.ibank, 4096*irl); | ||
204 | |||
205 | lseek(fd, vramblock<<12, SEEK_SET); | ||
206 | read(fd,lcd.vbank, 4096*vrl); | ||
207 | |||
208 | lseek(fd, sramblock<<12, SEEK_SET); | ||
209 | read(fd,ram.sbank, 4096*srl); | ||
210 | } | ||
211 | |||
212 | void savestate(int fd) | ||
213 | { | ||
214 | int i; | ||
215 | byte buf[4096]; | ||
216 | un32 (*header)[2] = (un32 (*)[2])buf; | ||
217 | un32 d = 0; | ||
218 | int irl = hw.cgb ? 8 : 2; | ||
219 | int vrl = hw.cgb ? 4 : 2; | ||
220 | int srl = mbc.ramsize << 1; | ||
221 | |||
222 | ver = 0x105; | ||
223 | iramblock = 1; | ||
224 | vramblock = 1+irl; | ||
225 | sramblock = 1+irl+vrl; | ||
226 | wavofs = 4096 - 784; | ||
227 | hiofs = 4096 - 768; | ||
228 | palofs = 4096 - 512; | ||
229 | oamofs = 4096 - 256; | ||
230 | memset(buf, 0, sizeof buf); | ||
231 | |||
232 | for (i = 0; svars[i].len > 0; i++) | ||
233 | { | ||
234 | header[i][0] = *(un32 *)svars[i].key; | ||
235 | switch (svars[i].len) | ||
236 | { | ||
237 | case 1: | ||
238 | d = *(byte *)svars[i].ptr; | ||
239 | break; | ||
240 | case 2: | ||
241 | d = *(un16 *)svars[i].ptr; | ||
242 | break; | ||
243 | case 4: | ||
244 | d = *(un32 *)svars[i].ptr; | ||
245 | break; | ||
246 | } | ||
247 | header[i][1] = LIL(d); | ||
248 | } | ||
249 | header[i][0] = header[i][1] = 0; | ||
250 | |||
251 | memcpy(buf+hiofs, ram.hi, sizeof ram.hi); | ||
252 | memcpy(buf+palofs, lcd.pal, sizeof lcd.pal); | ||
253 | memcpy(buf+oamofs, lcd.oam.mem, sizeof lcd.oam); | ||
254 | memcpy(buf+wavofs, snd.wave, sizeof snd.wave); | ||
255 | |||
256 | lseek(fd, 0, SEEK_SET); | ||
257 | write(fd,buf, 4096); | ||
258 | |||
259 | lseek(fd, iramblock<<12, SEEK_SET); | ||
260 | write(fd,ram.ibank, 4096*irl); | ||
261 | |||
262 | lseek(fd, vramblock<<12, SEEK_SET); | ||
263 | write(fd,lcd.vbank, 4096*vrl); | ||
264 | |||
265 | lseek(fd, sramblock<<12, SEEK_SET); | ||
266 | write(fd,ram.sbank, 4096*srl); | ||
267 | } | ||
268 | |||
269 | |||
270 | |||
271 | |||
272 | |||
273 | |||
274 | |||
275 | |||
276 | |||
277 | |||
278 | |||
279 | |||
280 | |||
281 | |||
282 | |||
283 | |||
284 | |||
285 | |||
286 | |||
diff --git a/apps/plugins/rockboy/save.h b/apps/plugins/rockboy/save.h new file mode 100644 index 0000000000..01b3b14f05 --- /dev/null +++ b/apps/plugins/rockboy/save.h | |||
@@ -0,0 +1,4 @@ | |||
1 | void loadstate(int fd); | ||
2 | void savestate(int fd); | ||
3 | void state_save(int n); | ||
4 | void state_load(int n); | ||
diff --git a/apps/plugins/rockboy/sound.c b/apps/plugins/rockboy/sound.c new file mode 100644 index 0000000000..edf31d81b7 --- /dev/null +++ b/apps/plugins/rockboy/sound.c | |||
@@ -0,0 +1,466 @@ | |||
1 | |||
2 | |||
3 | |||
4 | #include "rockmacros.h" | ||
5 | #include "defs.h" | ||
6 | #include "pcm.h" | ||
7 | #include "sound.h" | ||
8 | #include "cpu.h" | ||
9 | #include "hw.h" | ||
10 | #include "regs.h" | ||
11 | #include "rc.h" | ||
12 | #include "noise.h" | ||
13 | |||
14 | |||
15 | static const byte dmgwave[16] = | ||
16 | { | ||
17 | 0xac, 0xdd, 0xda, 0x48, | ||
18 | 0x36, 0x02, 0xcf, 0x16, | ||
19 | 0x2c, 0x04, 0xe5, 0x2c, | ||
20 | 0xac, 0xdd, 0xda, 0x48 | ||
21 | }; | ||
22 | |||
23 | static const byte cgbwave[16] = | ||
24 | { | ||
25 | 0x00, 0xff, 0x00, 0xff, | ||
26 | 0x00, 0xff, 0x00, 0xff, | ||
27 | 0x00, 0xff, 0x00, 0xff, | ||
28 | 0x00, 0xff, 0x00, 0xff, | ||
29 | }; | ||
30 | |||
31 | |||
32 | static const byte sqwave[4][8] = | ||
33 | { | ||
34 | { 0, 0,-1, 0, 0, 0, 0, 0 }, | ||
35 | { 0,-1,-1, 0, 0, 0, 0, 0 }, | ||
36 | { -1,-1,-1,-1, 0, 0, 0, 0 }, | ||
37 | { -1, 0, 0,-1,-1,-1,-1,-1 } | ||
38 | }; | ||
39 | |||
40 | static const int freqtab[8] = | ||
41 | { | ||
42 | (1<<14)*2, | ||
43 | (1<<14), | ||
44 | (1<<14)/2, | ||
45 | (1<<14)/3, | ||
46 | (1<<14)/4, | ||
47 | (1<<14)/5, | ||
48 | (1<<14)/6, | ||
49 | (1<<14)/7 | ||
50 | }; | ||
51 | |||
52 | struct snd snd; | ||
53 | int pcm_submit(void); | ||
54 | |||
55 | #define RATE (snd.rate) | ||
56 | #define WAVE (snd.wave) /* ram.hi+0x30 */ | ||
57 | #define S1 (snd.ch[0]) | ||
58 | #define S2 (snd.ch[1]) | ||
59 | #define S3 (snd.ch[2]) | ||
60 | #define S4 (snd.ch[3]) | ||
61 | |||
62 | rcvar_t sound_exports[] = | ||
63 | { | ||
64 | RCV_END | ||
65 | }; | ||
66 | |||
67 | |||
68 | static void s1_freq_d(int d) | ||
69 | { | ||
70 | if (RATE > (d<<4)) S1.freq = 0; | ||
71 | else S1.freq = (RATE << 17)/d; | ||
72 | } | ||
73 | |||
74 | static void s1_freq(void) | ||
75 | { | ||
76 | s1_freq_d(2048 - (((R_NR14&7)<<8) + R_NR13)); | ||
77 | } | ||
78 | |||
79 | static void s2_freq(void) | ||
80 | { | ||
81 | int d = 2048 - (((R_NR24&7)<<8) + R_NR23); | ||
82 | if (RATE > (d<<4)) S2.freq = 0; | ||
83 | else S2.freq = (RATE << 17)/d; | ||
84 | } | ||
85 | |||
86 | static void s3_freq(void) | ||
87 | { | ||
88 | int d = 2048 - (((R_NR34&7)<<8) + R_NR33); | ||
89 | if (RATE > (d<<3)) S3.freq = 0; | ||
90 | else S3.freq = (RATE << 21)/d; | ||
91 | } | ||
92 | |||
93 | static void s4_freq(void) | ||
94 | { | ||
95 | S4.freq = (freqtab[R_NR43&7] >> (R_NR43 >> 4)) * RATE; | ||
96 | if (S4.freq >> 18) S4.freq = 1<<18; | ||
97 | } | ||
98 | |||
99 | void sound_dirty(void) | ||
100 | { | ||
101 | S1.swlen = ((R_NR10>>4) & 7) << 14; | ||
102 | S1.len = (64-(R_NR11&63)) << 13; | ||
103 | S1.envol = R_NR12 >> 4; | ||
104 | S1.endir = (R_NR12>>3) & 1; | ||
105 | S1.endir |= S1.endir - 1; | ||
106 | S1.enlen = (R_NR12 & 7) << 15; | ||
107 | s1_freq(); | ||
108 | S2.len = (64-(R_NR21&63)) << 13; | ||
109 | S2.envol = R_NR22 >> 4; | ||
110 | S2.endir = (R_NR22>>3) & 1; | ||
111 | S2.endir |= S2.endir - 1; | ||
112 | S2.enlen = (R_NR22 & 7) << 15; | ||
113 | s2_freq(); | ||
114 | S3.len = (256-R_NR31) << 20; | ||
115 | s3_freq(); | ||
116 | S4.len = (64-(R_NR41&63)) << 13; | ||
117 | S4.envol = R_NR42 >> 4; | ||
118 | S4.endir = (R_NR42>>3) & 1; | ||
119 | S4.endir |= S4.endir - 1; | ||
120 | S4.enlen = (R_NR42 & 7) << 15; | ||
121 | s4_freq(); | ||
122 | } | ||
123 | |||
124 | void sound_off(void) | ||
125 | { | ||
126 | memset(&S1, 0, sizeof S1); | ||
127 | memset(&S2, 0, sizeof S2); | ||
128 | memset(&S3, 0, sizeof S3); | ||
129 | memset(&S4, 0, sizeof S4); | ||
130 | R_NR10 = 0x80; | ||
131 | R_NR11 = 0xBF; | ||
132 | R_NR12 = 0xF3; | ||
133 | R_NR14 = 0xBF; | ||
134 | R_NR21 = 0x3F; | ||
135 | R_NR22 = 0x00; | ||
136 | R_NR24 = 0xBF; | ||
137 | R_NR30 = 0x7F; | ||
138 | R_NR31 = 0xFF; | ||
139 | R_NR32 = 0x9F; | ||
140 | R_NR33 = 0xBF; | ||
141 | R_NR41 = 0xFF; | ||
142 | R_NR42 = 0x00; | ||
143 | R_NR43 = 0x00; | ||
144 | R_NR44 = 0xBF; | ||
145 | R_NR50 = 0x77; | ||
146 | R_NR51 = 0xF3; | ||
147 | R_NR52 = 0xF1; | ||
148 | sound_dirty(); | ||
149 | } | ||
150 | |||
151 | void sound_reset(void) | ||
152 | { | ||
153 | memset(&snd, 0, sizeof snd); | ||
154 | if (pcm.hz) snd.rate = (1<<21) / pcm.hz; | ||
155 | else snd.rate = 0; | ||
156 | memcpy(WAVE, hw.cgb ? cgbwave : dmgwave, 16); | ||
157 | memcpy(ram.hi+0x30, WAVE, 16); | ||
158 | sound_off(); | ||
159 | } | ||
160 | |||
161 | |||
162 | void sound_mix(void) | ||
163 | { | ||
164 | int s, l, r, f, n; | ||
165 | |||
166 | if (!RATE || cpu.snd < RATE) return; | ||
167 | |||
168 | for (; cpu.snd >= RATE; cpu.snd -= RATE) | ||
169 | { | ||
170 | l = r = 0; | ||
171 | |||
172 | if (S1.on) | ||
173 | { | ||
174 | s = sqwave[R_NR11>>6][(S1.pos>>18)&7] & S1.envol; | ||
175 | S1.pos += S1.freq; | ||
176 | if ((R_NR14 & 64) && ((S1.cnt += RATE) >= S1.len)) | ||
177 | S1.on = 0; | ||
178 | if (S1.enlen && (S1.encnt += RATE) >= S1.enlen) | ||
179 | { | ||
180 | S1.encnt -= S1.enlen; | ||
181 | S1.envol += S1.endir; | ||
182 | if (S1.envol < 0) S1.envol = 0; | ||
183 | if (S1.envol > 15) S1.envol = 15; | ||
184 | } | ||
185 | if (S1.swlen && (S1.swcnt += RATE) >= S1.swlen) | ||
186 | { | ||
187 | S1.swcnt -= S1.swlen; | ||
188 | f = S1.swfreq; | ||
189 | n = (R_NR10 & 7); | ||
190 | if (R_NR10 & 8) f -= (f >> n); | ||
191 | else f += (f >> n); | ||
192 | if (f > 2047) | ||
193 | S1.on = 0; | ||
194 | else | ||
195 | { | ||
196 | S1.swfreq = f; | ||
197 | R_NR13 = f; | ||
198 | R_NR14 = (R_NR14 & 0xF8) | (f>>8); | ||
199 | s1_freq_d(2048 - f); | ||
200 | } | ||
201 | } | ||
202 | s <<= 2; | ||
203 | if (R_NR51 & 1) r += s; | ||
204 | if (R_NR51 & 16) l += s; | ||
205 | } | ||
206 | |||
207 | if (S2.on) | ||
208 | { | ||
209 | s = sqwave[R_NR21>>6][(S2.pos>>18)&7] & S2.envol; | ||
210 | S2.pos += S2.freq; | ||
211 | if ((R_NR24 & 64) && ((S2.cnt += RATE) >= S2.len)) | ||
212 | S2.on = 0; | ||
213 | if (S2.enlen && (S2.encnt += RATE) >= S2.enlen) | ||
214 | { | ||
215 | S2.encnt -= S2.enlen; | ||
216 | S2.envol += S2.endir; | ||
217 | if (S2.envol < 0) S2.envol = 0; | ||
218 | if (S2.envol > 15) S2.envol = 15; | ||
219 | } | ||
220 | s <<= 2; | ||
221 | if (R_NR51 & 2) r += s; | ||
222 | if (R_NR51 & 32) l += s; | ||
223 | } | ||
224 | |||
225 | if (S3.on) | ||
226 | { | ||
227 | s = WAVE[(S3.pos>>22) & 15]; | ||
228 | if (S3.pos & (1<<21)) s &= 15; | ||
229 | else s >>= 4; | ||
230 | s -= 8; | ||
231 | S3.pos += S3.freq; | ||
232 | if ((R_NR34 & 64) && ((S3.cnt += RATE) >= S3.len)) | ||
233 | S3.on = 0; | ||
234 | if (R_NR32 & 96) s <<= (3 - ((R_NR32>>5)&3)); | ||
235 | else s = 0; | ||
236 | if (R_NR51 & 4) r += s; | ||
237 | if (R_NR51 & 64) l += s; | ||
238 | } | ||
239 | |||
240 | if (S4.on) | ||
241 | { | ||
242 | if (R_NR43 & 8) s = 1 & (noise7[ | ||
243 | (S4.pos>>20)&15] >> (7-((S4.pos>>17)&7))); | ||
244 | else s = 1 & (noise15[ | ||
245 | (S4.pos>>20)&4095] >> (7-((S4.pos>>17)&7))); | ||
246 | s = (-s) & S4.envol; | ||
247 | S4.pos += S4.freq; | ||
248 | if ((R_NR44 & 64) && ((S4.cnt += RATE) >= S4.len)) | ||
249 | S4.on = 0; | ||
250 | if (S4.enlen && (S4.encnt += RATE) >= S4.enlen) | ||
251 | { | ||
252 | S4.encnt -= S4.enlen; | ||
253 | S4.envol += S4.endir; | ||
254 | if (S4.envol < 0) S4.envol = 0; | ||
255 | if (S4.envol > 15) S4.envol = 15; | ||
256 | } | ||
257 | s += s << 1; | ||
258 | if (R_NR51 & 8) r += s; | ||
259 | if (R_NR51 & 128) l += s; | ||
260 | } | ||
261 | |||
262 | l *= (R_NR50 & 0x07); | ||
263 | r *= ((R_NR50 & 0x70)>>4); | ||
264 | l >>= 4; | ||
265 | r >>= 4; | ||
266 | |||
267 | if (l > 127) l = 127; | ||
268 | else if (l < -128) l = -128; | ||
269 | if (r > 127) r = 127; | ||
270 | else if (r < -128) r = -128; | ||
271 | |||
272 | if (pcm.buf) | ||
273 | { | ||
274 | if (pcm.pos >= pcm.len) | ||
275 | pcm_submit(); | ||
276 | if (pcm.stereo) | ||
277 | { | ||
278 | pcm.buf[pcm.pos++] = l+128; | ||
279 | pcm.buf[pcm.pos++] = r+128; | ||
280 | } | ||
281 | else pcm.buf[pcm.pos++] = ((l+r)>>1)+128; | ||
282 | } | ||
283 | } | ||
284 | R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3); | ||
285 | } | ||
286 | |||
287 | |||
288 | |||
289 | byte sound_read(byte r) | ||
290 | { | ||
291 | sound_mix(); | ||
292 | /* printf("read %02X: %02X\n", r, REG(r)); */ | ||
293 | return REG(r); | ||
294 | } | ||
295 | |||
296 | void s1_init(void) | ||
297 | { | ||
298 | S1.swcnt = 0; | ||
299 | S1.swfreq = ((R_NR14&7)<<8) + R_NR13; | ||
300 | S1.envol = R_NR12 >> 4; | ||
301 | S1.endir = (R_NR12>>3) & 1; | ||
302 | S1.endir |= S1.endir - 1; | ||
303 | S1.enlen = (R_NR12 & 7) << 15; | ||
304 | if (!S1.on) S1.pos = 0; | ||
305 | S1.on = 1; | ||
306 | S1.cnt = 0; | ||
307 | S1.encnt = 0; | ||
308 | } | ||
309 | |||
310 | void s2_init(void) | ||
311 | { | ||
312 | S2.envol = R_NR22 >> 4; | ||
313 | S2.endir = (R_NR22>>3) & 1; | ||
314 | S2.endir |= S2.endir - 1; | ||
315 | S2.enlen = (R_NR22 & 7) << 15; | ||
316 | if (!S2.on) S2.pos = 0; | ||
317 | S2.on = 1; | ||
318 | S2.cnt = 0; | ||
319 | S2.encnt = 0; | ||
320 | } | ||
321 | |||
322 | void s3_init(void) | ||
323 | { | ||
324 | int i; | ||
325 | if (!S3.on) S3.pos = 0; | ||
326 | S3.cnt = 0; | ||
327 | S3.on = R_NR30 >> 7; | ||
328 | if (S3.on) for (i = 0; i < 16; i++) | ||
329 | ram.hi[i+0x30] = 0x13 ^ ram.hi[i+0x31]; | ||
330 | } | ||
331 | |||
332 | void s4_init(void) | ||
333 | { | ||
334 | S4.envol = R_NR42 >> 4; | ||
335 | S4.endir = (R_NR42>>3) & 1; | ||
336 | S4.endir |= S4.endir - 1; | ||
337 | S4.enlen = (R_NR42 & 7) << 15; | ||
338 | S4.on = 1; | ||
339 | S4.pos = 0; | ||
340 | S4.cnt = 0; | ||
341 | S4.encnt = 0; | ||
342 | } | ||
343 | |||
344 | |||
345 | void sound_write(byte r, byte b) | ||
346 | { | ||
347 | #if 0 | ||
348 | static void *timer; | ||
349 | if (!timer) timer = sys_timer(); | ||
350 | printf("write %02X: %02X @ %d\n", r, b, sys_elapsed(timer)); | ||
351 | #endif | ||
352 | |||
353 | if (!(R_NR52 & 128) && r != RI_NR52) return; | ||
354 | if ((r & 0xF0) == 0x30) | ||
355 | { | ||
356 | if (S3.on) sound_mix(); | ||
357 | if (!S3.on) | ||
358 | WAVE[r-0x30] = ram.hi[r] = b; | ||
359 | return; | ||
360 | } | ||
361 | sound_mix(); | ||
362 | switch (r) | ||
363 | { | ||
364 | case RI_NR10: | ||
365 | R_NR10 = b; | ||
366 | S1.swlen = ((R_NR10>>4) & 7) << 14; | ||
367 | S1.swfreq = ((R_NR14&7)<<8) + R_NR13; | ||
368 | break; | ||
369 | case RI_NR11: | ||
370 | R_NR11 = b; | ||
371 | S1.len = (64-(R_NR11&63)) << 13; | ||
372 | break; | ||
373 | case RI_NR12: | ||
374 | R_NR12 = b; | ||
375 | S1.envol = R_NR12 >> 4; | ||
376 | S1.endir = (R_NR12>>3) & 1; | ||
377 | S1.endir |= S1.endir - 1; | ||
378 | S1.enlen = (R_NR12 & 7) << 15; | ||
379 | break; | ||
380 | case RI_NR13: | ||
381 | R_NR13 = b; | ||
382 | s1_freq(); | ||
383 | break; | ||
384 | case RI_NR14: | ||
385 | R_NR14 = b; | ||
386 | s1_freq(); | ||
387 | if (b & 128) s1_init(); | ||
388 | break; | ||
389 | case RI_NR21: | ||
390 | R_NR21 = b; | ||
391 | S2.len = (64-(R_NR21&63)) << 13; | ||
392 | break; | ||
393 | case RI_NR22: | ||
394 | R_NR22 = b; | ||
395 | S2.envol = R_NR22 >> 4; | ||
396 | S2.endir = (R_NR22>>3) & 1; | ||
397 | S2.endir |= S2.endir - 1; | ||
398 | S2.enlen = (R_NR22 & 7) << 15; | ||
399 | break; | ||
400 | case RI_NR23: | ||
401 | R_NR23 = b; | ||
402 | s2_freq(); | ||
403 | break; | ||
404 | case RI_NR24: | ||
405 | R_NR24 = b; | ||
406 | s2_freq(); | ||
407 | if (b & 128) s2_init(); | ||
408 | break; | ||
409 | case RI_NR30: | ||
410 | R_NR30 = b; | ||
411 | if (!(b & 128)) S3.on = 0; | ||
412 | break; | ||
413 | case RI_NR31: | ||
414 | R_NR31 = b; | ||
415 | S3.len = (256-R_NR31) << 13; | ||
416 | break; | ||
417 | case RI_NR32: | ||
418 | R_NR32 = b; | ||
419 | break; | ||
420 | case RI_NR33: | ||
421 | R_NR33 = b; | ||
422 | s3_freq(); | ||
423 | break; | ||
424 | case RI_NR34: | ||
425 | R_NR34 = b; | ||
426 | s3_freq(); | ||
427 | if (b & 128) s3_init(); | ||
428 | break; | ||
429 | case RI_NR41: | ||
430 | R_NR41 = b; | ||
431 | S4.len = (64-(R_NR41&63)) << 13; | ||
432 | break; | ||
433 | case RI_NR42: | ||
434 | R_NR42 = b; | ||
435 | S4.envol = R_NR42 >> 4; | ||
436 | S4.endir = (R_NR42>>3) & 1; | ||
437 | S4.endir |= S4.endir - 1; | ||
438 | S4.enlen = (R_NR42 & 7) << 15; | ||
439 | break; | ||
440 | case RI_NR43: | ||
441 | R_NR43 = b; | ||
442 | s4_freq(); | ||
443 | break; | ||
444 | case RI_NR44: | ||
445 | R_NR44 = b; | ||
446 | if (b & 128) s4_init(); | ||
447 | break; | ||
448 | case RI_NR50: | ||
449 | R_NR50 = b; | ||
450 | break; | ||
451 | case RI_NR51: | ||
452 | R_NR51 = b; | ||
453 | break; | ||
454 | case RI_NR52: | ||
455 | R_NR52 = b; | ||
456 | if (!(R_NR52 & 128)) | ||
457 | sound_off(); | ||
458 | break; | ||
459 | default: | ||
460 | return; | ||
461 | } | ||
462 | } | ||
463 | |||
464 | |||
465 | |||
466 | |||
diff --git a/apps/plugins/rockboy/sound.h b/apps/plugins/rockboy/sound.h new file mode 100644 index 0000000000..1a24ee600f --- /dev/null +++ b/apps/plugins/rockboy/sound.h | |||
@@ -0,0 +1,41 @@ | |||
1 | |||
2 | |||
3 | #ifndef __SOUND_H__ | ||
4 | #define __SOUND_H__ | ||
5 | |||
6 | |||
7 | struct sndchan | ||
8 | { | ||
9 | int on; | ||
10 | unsigned pos; | ||
11 | int cnt, encnt, swcnt; | ||
12 | int len, enlen, swlen; | ||
13 | int swfreq; | ||
14 | int freq; | ||
15 | int envol, endir; | ||
16 | }; | ||
17 | |||
18 | |||
19 | struct snd | ||
20 | { | ||
21 | int rate; | ||
22 | struct sndchan ch[4]; | ||
23 | byte wave[16]; | ||
24 | }; | ||
25 | |||
26 | |||
27 | extern struct snd snd; | ||
28 | |||
29 | byte sound_read(byte r); | ||
30 | void sound_write(byte r, byte b); | ||
31 | void sound_dirty(void); | ||
32 | void sound_off(void); | ||
33 | void sound_reset(void); | ||
34 | void sound_mix(void); | ||
35 | void s1_init(void); | ||
36 | void s2_init(void); | ||
37 | void s3_init(void); | ||
38 | void s4_init(void); | ||
39 | |||
40 | #endif | ||
41 | |||
diff --git a/apps/plugins/rockboy/split.c b/apps/plugins/rockboy/split.c new file mode 100644 index 0000000000..5d8af08ee1 --- /dev/null +++ b/apps/plugins/rockboy/split.c | |||
@@ -0,0 +1,59 @@ | |||
1 | |||
2 | #include "rockmacros.h" | ||
3 | |||
4 | /* | ||
5 | * splitline is a destructive argument parser, much like a very primitive | ||
6 | * form of a shell parser. it supports quotes for embedded spaces and | ||
7 | * literal quotes with the backslash escape. | ||
8 | */ | ||
9 | |||
10 | char *splitnext(char **pos) | ||
11 | { | ||
12 | char *a, *d, *s; | ||
13 | |||
14 | d = s = *pos; | ||
15 | while (*s == ' ' || *s == '\t') s++; | ||
16 | a = s; | ||
17 | while (*s && *s != ' ' && *s != '\t') | ||
18 | { | ||
19 | if (*s == '"') | ||
20 | { | ||
21 | s++; | ||
22 | while (*s && *s != '"') | ||
23 | { | ||
24 | if (*s == '\\') | ||
25 | s++; | ||
26 | if (*s) | ||
27 | *(d++) = *(s++); | ||
28 | } | ||
29 | if (*s == '"') s++; | ||
30 | } | ||
31 | else | ||
32 | { | ||
33 | if (*s == '\\') | ||
34 | s++; | ||
35 | *(d++) = *(s++); | ||
36 | } | ||
37 | } | ||
38 | while (*s == ' ' || *s == '\t') s++; | ||
39 | *d = 0; | ||
40 | *pos = s; | ||
41 | return a; | ||
42 | } | ||
43 | |||
44 | int splitline(char **argv, int max, char *line) | ||
45 | { | ||
46 | char *s; | ||
47 | int i; | ||
48 | |||
49 | s = line; | ||
50 | for (i = 0; *s && i < max + 1; i++) | ||
51 | argv[i] = splitnext(&s); | ||
52 | argv[i] = 0; | ||
53 | return i; | ||
54 | } | ||
55 | |||
56 | |||
57 | |||
58 | |||
59 | |||
diff --git a/apps/plugins/rockboy/split.h b/apps/plugins/rockboy/split.h new file mode 100644 index 0000000000..a371430946 --- /dev/null +++ b/apps/plugins/rockboy/split.h | |||
@@ -0,0 +1 @@ | |||
int splitline(char **argv, int max, char *line); | |||
diff --git a/apps/plugins/rockboy/sys_rockbox.c b/apps/plugins/rockboy/sys_rockbox.c new file mode 100644 index 0000000000..43cd8ad29e --- /dev/null +++ b/apps/plugins/rockboy/sys_rockbox.c | |||
@@ -0,0 +1,271 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 Michiel van der Kolk, Jens Arnold | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "rockmacros.h" | ||
21 | #include "fb.h" | ||
22 | #include "input.h" | ||
23 | #include "rc.h" | ||
24 | #include "lcd.h" | ||
25 | #include "hw.h" | ||
26 | #include "config.h" | ||
27 | |||
28 | rcvar_t joy_exports[] = | ||
29 | { | ||
30 | RCV_END | ||
31 | }; | ||
32 | |||
33 | rcvar_t vid_exports[] = | ||
34 | { | ||
35 | RCV_END | ||
36 | }; | ||
37 | |||
38 | struct fb fb; | ||
39 | byte *video_base_buf; | ||
40 | |||
41 | extern int debug_trace; | ||
42 | |||
43 | static byte frameb[145][160]; | ||
44 | |||
45 | void vid_settitle(char *title) | ||
46 | { | ||
47 | rb->splash(HZ*2, true, title); | ||
48 | } | ||
49 | |||
50 | void joy_init(void) | ||
51 | { | ||
52 | } | ||
53 | |||
54 | void joy_close(void) | ||
55 | { | ||
56 | } | ||
57 | |||
58 | #if CONFIG_KEYPAD == IRIVER_H100_PAD | ||
59 | #define ROCKBOY_PAD_A BUTTON_ON | ||
60 | #define ROCKBOY_PAD_B BUTTON_OFF | ||
61 | #define ROCKBOY_PAD_START BUTTON_REC | ||
62 | #define ROCKBOY_PAD_SELECT BUTTON_MODE | ||
63 | #define ROCKBOY_QUIT BUTTON_SELECT | ||
64 | |||
65 | #elif CONFIG_KEYPAD == RECORDER_PAD | ||
66 | #define ROCKBOY_PAD_A BUTTON_F1 | ||
67 | #define ROCKBOY_PAD_B BUTTON_F2 | ||
68 | #define ROCKBOY_PAD_START BUTTON_F3 | ||
69 | #define ROCKBOY_PAD_SELECT BUTTON_PLAY | ||
70 | #define ROCKBOY_QUIT BUTTON_OFF | ||
71 | |||
72 | #endif | ||
73 | |||
74 | unsigned int oldbuttonstate = 0, newbuttonstate; | ||
75 | |||
76 | void ev_poll(void) | ||
77 | { | ||
78 | event_t ev; | ||
79 | int released, pressed; | ||
80 | newbuttonstate = rb->button_status(); | ||
81 | released = ~newbuttonstate & oldbuttonstate; | ||
82 | pressed = newbuttonstate & ~oldbuttonstate; | ||
83 | oldbuttonstate = newbuttonstate; | ||
84 | |||
85 | if(released) { | ||
86 | ev.type = EV_RELEASE; | ||
87 | if(released & BUTTON_LEFT) { ev.code=PAD_LEFT; ev_postevent(&ev); } | ||
88 | if(released & BUTTON_RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);} | ||
89 | if(released & BUTTON_DOWN) { ev.code=PAD_DOWN; ev_postevent(&ev); } | ||
90 | if(released & BUTTON_UP) { ev.code=PAD_UP; ev_postevent(&ev); } | ||
91 | if(released & ROCKBOY_PAD_A) { ev.code=PAD_A; ev_postevent(&ev); } | ||
92 | if(released & ROCKBOY_PAD_B) { ev.code=PAD_B; ev_postevent(&ev); } | ||
93 | if(released & ROCKBOY_PAD_START) { | ||
94 | ev.code=PAD_START; | ||
95 | ev_postevent(&ev); | ||
96 | } | ||
97 | if(released & ROCKBOY_PAD_SELECT) { | ||
98 | ev.code=PAD_SELECT; | ||
99 | ev_postevent(&ev); | ||
100 | } | ||
101 | } | ||
102 | if(pressed) { /* button press */ | ||
103 | ev.type = EV_PRESS; | ||
104 | if(pressed & BUTTON_LEFT) { ev.code=PAD_LEFT; ev_postevent(&ev); } | ||
105 | if(pressed & BUTTON_RIGHT) { ev.code=PAD_RIGHT; ev_postevent(&ev);} | ||
106 | if(pressed & BUTTON_DOWN) { ev.code=PAD_DOWN; ev_postevent(&ev); } | ||
107 | if(pressed & BUTTON_UP) { ev.code=PAD_UP; ev_postevent(&ev); } | ||
108 | if(pressed & ROCKBOY_PAD_A) { ev.code=PAD_A; ev_postevent(&ev); } | ||
109 | if(pressed & ROCKBOY_PAD_B) { ev.code=PAD_B; ev_postevent(&ev); } | ||
110 | if(pressed & ROCKBOY_PAD_START) { | ||
111 | ev.code=PAD_START; | ||
112 | ev_postevent(&ev); | ||
113 | } | ||
114 | if(pressed & ROCKBOY_PAD_SELECT) { | ||
115 | ev.code=PAD_SELECT; | ||
116 | ev_postevent(&ev); | ||
117 | } | ||
118 | if(pressed & ROCKBOY_QUIT) { | ||
119 | die(""); | ||
120 | cleanshut=1; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | } | ||
125 | |||
126 | void vid_setpal(int i, int r, int g, int b) | ||
127 | { | ||
128 | (void)i; | ||
129 | (void)r; | ||
130 | (void)g; | ||
131 | (void)b; | ||
132 | } | ||
133 | |||
134 | void vid_init(void) | ||
135 | { | ||
136 | } | ||
137 | |||
138 | void vid_begin(void) | ||
139 | { | ||
140 | fb.pelsize=1; // 8 bit framebuffer.. (too much.. but lowest gnuboy will support.. so yea... | ||
141 | fb.h=144; | ||
142 | fb.w=160; | ||
143 | fb.pitch=160; | ||
144 | fb.enabled=1; | ||
145 | fb.dirty=0; | ||
146 | video_base_buf=fb.ptr=(byte *)frameb; | ||
147 | } | ||
148 | |||
149 | void vid_update(int scanline) | ||
150 | { | ||
151 | int cnt=0,scanline_remapped; | ||
152 | byte *frameb; | ||
153 | #if LCD_HEIGHT == 64 /* Archos */ | ||
154 | int balance = 0; | ||
155 | if (scanline >= 128) | ||
156 | return; | ||
157 | scanline_remapped = scanline / 16; | ||
158 | frameb = rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH; | ||
159 | while (cnt < 160) { | ||
160 | balance += LCD_WIDTH; | ||
161 | if (balance > 0) | ||
162 | { | ||
163 | #ifdef SIMULATOR /* simulator uses C */ | ||
164 | register unsigned scrbyte = 0; | ||
165 | if (scan.buf[0][cnt] & 0x02) scrbyte |= 0x01; | ||
166 | if (scan.buf[1][cnt] & 0x02) scrbyte |= 0x02; | ||
167 | if (scan.buf[2][cnt] & 0x02) scrbyte |= 0x04; | ||
168 | if (scan.buf[3][cnt] & 0x02) scrbyte |= 0x08; | ||
169 | if (scan.buf[4][cnt] & 0x02) scrbyte |= 0x10; | ||
170 | if (scan.buf[5][cnt] & 0x02) scrbyte |= 0x20; | ||
171 | if (scan.buf[6][cnt] & 0x02) scrbyte |= 0x40; | ||
172 | if (scan.buf[7][cnt] & 0x02) scrbyte |= 0x80; | ||
173 | *(frameb++) = scrbyte; | ||
174 | #else | ||
175 | asm volatile ( | ||
176 | "mov.b @%0,r0 \n" | ||
177 | "add %1,%0 \n" | ||
178 | "tst #0x02, r0 \n" /* ~bit 1 */ | ||
179 | "rotcr r1 \n" | ||
180 | "mov.b @%0,r0 \n" | ||
181 | "add %1,%0 \n" | ||
182 | "tst #0x02, r0 \n" /* ~bit 1 */ | ||
183 | "rotcr r1 \n" | ||
184 | "mov.b @%0,r0 \n" | ||
185 | "add %1,%0 \n" | ||
186 | "tst #0x02, r0 \n" /* ~bit 1 */ | ||
187 | "rotcr r1 \n" | ||
188 | "mov.b @%0,r0 \n" | ||
189 | "add %1,%0 \n" | ||
190 | "tst #0x02, r0 \n" /* ~bit 1 */ | ||
191 | "rotcr r1 \n" | ||
192 | "mov.b @%0,r0 \n" | ||
193 | "add %1,%0 \n" | ||
194 | "tst #0x02, r0 \n" /* ~bit 1 */ | ||
195 | "rotcr r1 \n" | ||
196 | "mov.b @%0,r0 \n" | ||
197 | "add %1,%0 \n" | ||
198 | "tst #0x02, r0 \n" /* ~bit 1 */ | ||
199 | "rotcr r1 \n" | ||
200 | "mov.b @%0,r0 \n" | ||
201 | "add %1,%0 \n" | ||
202 | "tst #0x02, r0 \n" /* ~bit 1 */ | ||
203 | "rotcr r1 \n" | ||
204 | "mov.b @%0,r0 \n" | ||
205 | "add %1,%0 \n" | ||
206 | "tst #0x02, r0 \n" /* ~bit 1 */ | ||
207 | "rotcr r1 \n" | ||
208 | |||
209 | "shlr16 r1 \n" | ||
210 | "shlr8 r1 \n" | ||
211 | "not r1,r1 \n" /* account for negated bits */ | ||
212 | "mov.b r1,@%2 \n" | ||
213 | : /* outputs */ | ||
214 | : /* inputs */ | ||
215 | /* %0 */ "r"(scan.buf[0] + cnt), | ||
216 | /* %1 */ "r"(256), /* scan.buf line length */ | ||
217 | /* %2 */ "r"(frameb++) | ||
218 | : /* clobbers */ | ||
219 | "r0", "r1" | ||
220 | ); | ||
221 | #endif | ||
222 | balance -= 160; | ||
223 | } | ||
224 | cnt ++; | ||
225 | } | ||
226 | rb->lcd_update_rect(0, (scanline/2) & ~7, LCD_WIDTH, 8); | ||
227 | #else /* LCD_HEIGHT != 64, iRiver */ | ||
228 | if (scanline >= 128) | ||
229 | return; | ||
230 | scanline_remapped = scanline / 8; | ||
231 | frameb = rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH; | ||
232 | while (cnt < 160) { | ||
233 | register unsigned scrbyte = 0; | ||
234 | if (scan.buf[0][cnt] & 0x02) scrbyte |= 0x01; | ||
235 | if (scan.buf[1][cnt] & 0x02) scrbyte |= 0x02; | ||
236 | if (scan.buf[2][cnt] & 0x02) scrbyte |= 0x04; | ||
237 | if (scan.buf[3][cnt] & 0x02) scrbyte |= 0x08; | ||
238 | if (scan.buf[4][cnt] & 0x02) scrbyte |= 0x10; | ||
239 | if (scan.buf[5][cnt] & 0x02) scrbyte |= 0x20; | ||
240 | if (scan.buf[6][cnt] & 0x02) scrbyte |= 0x40; | ||
241 | if (scan.buf[7][cnt] & 0x02) scrbyte |= 0x80; | ||
242 | *(frameb++) = scrbyte; | ||
243 | cnt++; | ||
244 | } | ||
245 | rb->lcd_update_rect(0, scanline & ~7, LCD_WIDTH, 8); | ||
246 | #endif | ||
247 | } | ||
248 | |||
249 | void vid_end(void) | ||
250 | { | ||
251 | } | ||
252 | |||
253 | long timerresult; | ||
254 | |||
255 | void *sys_timer(void) | ||
256 | { | ||
257 | timerresult=*rb->current_tick; | ||
258 | return &timerresult; | ||
259 | } | ||
260 | |||
261 | // returns microseconds passed since sys_timer | ||
262 | int sys_elapsed(long *oldtick) | ||
263 | { | ||
264 | return ((*rb->current_tick-(*oldtick))*1000000)/HZ; | ||
265 | } | ||
266 | |||
267 | void sys_sleep(int us) | ||
268 | { | ||
269 | if (us <= 0) return; | ||
270 | // rb->sleep(HZ*us/1000000); | ||
271 | } | ||
diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config index 2290a8e635..08bd7ff939 100644 --- a/apps/plugins/viewers.config +++ b/apps/plugins/viewers.config | |||
@@ -6,6 +6,8 @@ rvf,video.rock,5D 7F 5D 7F 5D 7F | |||
6 | mp3,vbrfix.rock,10 08 58 38 04 02 | 6 | mp3,vbrfix.rock,10 08 58 38 04 02 |
7 | m3u,search.rock,00 00 00 00 00 00 | 7 | m3u,search.rock,00 00 00 00 00 00 |
8 | txt,sort.rock, 00 00 00 00 00 00 | 8 | txt,sort.rock, 00 00 00 00 00 00 |
9 | gb,rockboy.rock, 0C 2A 59 7A 2E 0C | ||
10 | cgb,rockboy.rock, 0C 2A 59 7A 2E 0C | ||
9 | mp2,mpa2wav.rock, 00 00 00 00 00 00 | 11 | mp2,mpa2wav.rock, 00 00 00 00 00 00 |
10 | mp3,mpa2wav.rock, 00 00 00 00 00 00 | 12 | mp3,mpa2wav.rock, 00 00 00 00 00 00 |
11 | ac3,a52towav.rock, 00 00 00 00 00 00 | 13 | ac3,a52towav.rock, 00 00 00 00 00 00 |