summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/Makefile14
-rw-r--r--apps/plugins/SOURCES4
-rw-r--r--apps/plugins/rockboy.c81
-rwxr-xr-xapps/plugins/rockboy/COPYING339
-rw-r--r--apps/plugins/rockboy/Makefile106
-rwxr-xr-xapps/plugins/rockboy/README199
-rwxr-xr-xapps/plugins/rockboy/Version5
-rwxr-xr-xapps/plugins/rockboy/archos.lds46
-rw-r--r--apps/plugins/rockboy/cpu.c880
-rw-r--r--apps/plugins/rockboy/cpu.h41
-rw-r--r--apps/plugins/rockboy/cpucore.h290
-rw-r--r--apps/plugins/rockboy/cpuregs.h56
-rw-r--r--apps/plugins/rockboy/debug.c699
-rw-r--r--apps/plugins/rockboy/defs.h36
-rw-r--r--apps/plugins/rockboy/emu.c117
-rw-r--r--apps/plugins/rockboy/emu.h2
-rw-r--r--apps/plugins/rockboy/events.c61
-rw-r--r--apps/plugins/rockboy/exports.c42
-rw-r--r--apps/plugins/rockboy/exports.h2
-rw-r--r--apps/plugins/rockboy/fastmem.c138
-rw-r--r--apps/plugins/rockboy/fastmem.h22
-rw-r--r--apps/plugins/rockboy/fb.h35
-rw-r--r--apps/plugins/rockboy/hw.c183
-rw-r--r--apps/plugins/rockboy/hw.h47
-rw-r--r--apps/plugins/rockboy/inflate.c514
-rw-r--r--apps/plugins/rockboy/input.h24
-rw-r--r--apps/plugins/rockboy/lcd.c956
-rw-r--r--apps/plugins/rockboy/lcd.h74
-rw-r--r--apps/plugins/rockboy/lcdc.c180
-rw-r--r--apps/plugins/rockboy/lcdc.h4
-rw-r--r--apps/plugins/rockboy/loader.c383
-rw-r--r--apps/plugins/rockboy/loader.h28
-rw-r--r--apps/plugins/rockboy/main.c83
-rw-r--r--apps/plugins/rockboy/mem.c578
-rw-r--r--apps/plugins/rockboy/mem.h80
-rw-r--r--apps/plugins/rockboy/noise.h532
-rw-r--r--apps/plugins/rockboy/nosound.c43
-rw-r--r--apps/plugins/rockboy/palette.c153
-rw-r--r--apps/plugins/rockboy/palette.h6
-rw-r--r--apps/plugins/rockboy/pcm.h21
-rw-r--r--apps/plugins/rockboy/rc.h71
-rw-r--r--apps/plugins/rockboy/rccmds.c122
-rw-r--r--apps/plugins/rockboy/rcvars.c233
-rw-r--r--apps/plugins/rockboy/regs.h181
-rw-r--r--apps/plugins/rockboy/rockboy.c137
-rw-r--r--apps/plugins/rockboy/rockmacros.h88
-rw-r--r--apps/plugins/rockboy/rtc.c135
-rw-r--r--apps/plugins/rockboy/rtc.h25
-rw-r--r--apps/plugins/rockboy/save.c286
-rw-r--r--apps/plugins/rockboy/save.h4
-rw-r--r--apps/plugins/rockboy/sound.c466
-rw-r--r--apps/plugins/rockboy/sound.h41
-rw-r--r--apps/plugins/rockboy/split.c59
-rw-r--r--apps/plugins/rockboy/split.h1
-rw-r--r--apps/plugins/rockboy/sys_rockbox.c271
-rw-r--r--apps/plugins/viewers.config2
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)
34DEFS := $(SRC:%.c=$(OBJDIR)/%.def) 34DEFS := $(SRC:%.c=$(OBJDIR)/%.def)
35DIRS = . 35DIRS = .
36 36
37all: $(OBJDIR)/libplugin.a $(ROCKS) $(DEPFILE) 37#for any recorder and iRiver model
38ifneq (,$(strip $(foreach tgt,RECORDER IRIVER,$(findstring $(tgt),$(TARGET)))))
39 SUBDIRS += rockboy
40endif
41
42.PHONY: $(SUBDIRS)
43all: $(OBJDIR)/libplugin.a $(ROCKS) $(SUBDIRS) $(DEPFILE)
38 44
39ifndef SIMVER 45ifndef 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
98clean: 109clean:
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
29oscilloscope.c 29oscilloscope.c
30pong.c 30pong.c
31rockblox.c 31rockblox.c
32#if (CONFIG_KEYPAD == RECORDER_PAD) && !defined(SIMULATOR)
33/* loader, only needed for Archos */
34rockboy.c
35#endif
32sliding_puzzle.c 36sliding_puzzle.c
33snake.c 37snake.c
34snake2.c 38snake2.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
28struct plugin_api* rb;
29unsigned char *mp3buf;
30int mp3buf_size;
31
32/* this is the plugin entry point */
33enum 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
12freedom to share and change it. By contrast, the GNU General Public
13License is intended to guarantee your freedom to share and change free
14software--to make sure the software is free for all its users. This
15General Public License applies to most of the Free Software
16Foundation's software and to any other program whose authors commit to
17using it. (Some other Free Software Foundation software is covered by
18the GNU Library General Public License instead.) You can apply it to
19your programs, too.
20
21 When we speak of free software, we are referring to freedom, not
22price. Our General Public Licenses are designed to make sure that you
23have the freedom to distribute copies of free software (and charge for
24this service if you wish), that you receive source code or can get it
25if you want it, that you can change the software or use pieces of it
26in 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
29anyone to deny you these rights or to ask you to surrender the rights.
30These restrictions translate to certain responsibilities for you if you
31distribute copies of the software, or if you modify it.
32
33 For example, if you distribute copies of such a program, whether
34gratis or for a fee, you must give the recipients all the rights that
35you have. You must make sure that they, too, receive or can get the
36source code. And you must show them these terms so they know their
37rights.
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,
41distribute and/or modify the software.
42
43 Also, for each author's protection and ours, we want to make certain
44that everyone understands that there is no warranty for this free
45software. If the software is modified by someone else and passed on, we
46want its recipients to know that what they have is not the original, so
47that any problems introduced by others will not reflect on the original
48authors' reputations.
49
50 Finally, any free program is threatened constantly by software
51patents. We wish to avoid the danger that redistributors of a free
52program will individually obtain patent licenses, in effect making the
53program proprietary. To prevent this, we have made it clear that any
54patent must be licensed for everyone's free use or not licensed at all.
55
56 The precise terms and conditions for copying, distribution and
57modification 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
63a notice placed by the copyright holder saying it may be distributed
64under the terms of this General Public License. The "Program", below,
65refers to any such program or work, and a "work based on the Program"
66means either the Program or any derivative work under copyright law:
67that is to say, a work containing the Program or a portion of it,
68either verbatim or with modifications and/or translated into another
69language. (Hereinafter, translation is included without limitation in
70the term "modification".) Each licensee is addressed as "you".
71
72Activities other than copying, distribution and modification are not
73covered by this License; they are outside its scope. The act of
74running the Program is not restricted, and the output from the Program
75is covered only if its contents constitute a work based on the
76Program (independent of having been made by running the Program).
77Whether that is true depends on what the Program does.
78
79 1. You may copy and distribute verbatim copies of the Program's
80source code as you receive it, in any medium, provided that you
81conspicuously and appropriately publish on each copy an appropriate
82copyright notice and disclaimer of warranty; keep intact all the
83notices that refer to this License and to the absence of any warranty;
84and give any other recipients of the Program a copy of this License
85along with the Program.
86
87You may charge a fee for the physical act of transferring a copy, and
88you 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
91of it, thus forming a work based on the Program, and copy and
92distribute such modifications or work under the terms of Section 1
93above, 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
114These requirements apply to the modified work as a whole. If
115identifiable sections of that work are not derived from the Program,
116and can be reasonably considered independent and separate works in
117themselves, then this License, and its terms, do not apply to those
118sections when you distribute them as separate works. But when you
119distribute the same sections as part of a whole which is a work based
120on the Program, the distribution of the whole must be on the terms of
121this License, whose permissions for other licensees extend to the
122entire whole, and thus to each and every part regardless of who wrote it.
123
124Thus, it is not the intent of this section to claim rights or contest
125your rights to work written entirely by you; rather, the intent is to
126exercise the right to control the distribution of derivative or
127collective works based on the Program.
128
129In addition, mere aggregation of another work not based on the Program
130with the Program (or with a work based on the Program) on a volume of
131a storage or distribution medium does not bring the other work under
132the scope of this License.
133
134 3. You may copy and distribute the Program (or a work based on it,
135under Section 2) in object code or executable form under the terms of
136Sections 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
155The source code for a work means the preferred form of the work for
156making modifications to it. For an executable work, complete source
157code means all the source code for all modules it contains, plus any
158associated interface definition files, plus the scripts used to
159control compilation and installation of the executable. However, as a
160special exception, the source code distributed need not include
161anything that is normally distributed (in either source or binary
162form) with the major components (compiler, kernel, and so on) of the
163operating system on which the executable runs, unless that component
164itself accompanies the executable.
165
166If distribution of executable or object code is made by offering
167access to copy from a designated place, then offering equivalent
168access to copy the source code from the same place counts as
169distribution of the source code, even though third parties are not
170compelled to copy the source along with the object code.
171
172 4. You may not copy, modify, sublicense, or distribute the Program
173except as expressly provided under this License. Any attempt
174otherwise to copy, modify, sublicense or distribute the Program is
175void, and will automatically terminate your rights under this License.
176However, parties who have received copies, or rights, from you under
177this License will not have their licenses terminated so long as such
178parties remain in full compliance.
179
180 5. You are not required to accept this License, since you have not
181signed it. However, nothing else grants you permission to modify or
182distribute the Program or its derivative works. These actions are
183prohibited by law if you do not accept this License. Therefore, by
184modifying or distributing the Program (or any work based on the
185Program), you indicate your acceptance of this License to do so, and
186all its terms and conditions for copying, distributing or modifying
187the Program or works based on it.
188
189 6. Each time you redistribute the Program (or any work based on the
190Program), the recipient automatically receives a license from the
191original licensor to copy, distribute or modify the Program subject to
192these terms and conditions. You may not impose any further
193restrictions on the recipients' exercise of the rights granted herein.
194You are not responsible for enforcing compliance by third parties to
195this License.
196
197 7. If, as a consequence of a court judgment or allegation of patent
198infringement or for any other reason (not limited to patent issues),
199conditions are imposed on you (whether by court order, agreement or
200otherwise) that contradict the conditions of this License, they do not
201excuse you from the conditions of this License. If you cannot
202distribute so as to satisfy simultaneously your obligations under this
203License and any other pertinent obligations, then as a consequence you
204may not distribute the Program at all. For example, if a patent
205license would not permit royalty-free redistribution of the Program by
206all those who receive copies directly or indirectly through you, then
207the only way you could satisfy both it and this License would be to
208refrain entirely from distribution of the Program.
209
210If any portion of this section is held invalid or unenforceable under
211any particular circumstance, the balance of the section is intended to
212apply and the section as a whole is intended to apply in other
213circumstances.
214
215It is not the purpose of this section to induce you to infringe any
216patents or other property right claims or to contest validity of any
217such claims; this section has the sole purpose of protecting the
218integrity of the free software distribution system, which is
219implemented by public license practices. Many people have made
220generous contributions to the wide range of software distributed
221through that system in reliance on consistent application of that
222system; it is up to the author/donor to decide if he or she is willing
223to distribute software through any other system and a licensee cannot
224impose that choice.
225
226This section is intended to make thoroughly clear what is believed to
227be a consequence of the rest of this License.
228
229 8. If the distribution and/or use of the Program is restricted in
230certain countries either by patents or by copyrighted interfaces, the
231original copyright holder who places the Program under this License
232may add an explicit geographical distribution limitation excluding
233those countries, so that distribution is permitted only in or among
234countries not thus excluded. In such case, this License incorporates
235the limitation as if written in the body of this License.
236
237 9. The Free Software Foundation may publish revised and/or new versions
238of the General Public License from time to time. Such new versions will
239be similar in spirit to the present version, but may differ in detail to
240address new problems or concerns.
241
242Each version is given a distinguishing version number. If the Program
243specifies a version number of this License which applies to it and "any
244later version", you have the option of following the terms and conditions
245either of that version or of any later version published by the Free
246Software Foundation. If the Program does not specify a version number of
247this License, you may choose any version ever published by the Free Software
248Foundation.
249
250 10. If you wish to incorporate parts of the Program into other free
251programs whose distribution conditions are different, write to the author
252to ask for permission. For software which is copyrighted by the Free
253Software Foundation, write to the Free Software Foundation; we sometimes
254make exceptions for this. Our decision will be guided by the two goals
255of preserving the free status of all derivatives of our free software and
256of 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
261FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268REPAIR OR CORRECTION.
269
270 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278POSSIBILITY 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
285possible use to the public, the best way to achieve this is to make it
286free 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
289to attach them to the start of each source file to most effectively
290convey the exclusion of warranty; and each file should have at least
291the "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
310Also add information on how to contact you by electronic and paper mail.
311
312If the program is interactive, make it output a short notice like this
313when 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
320The hypothetical commands `show w' and `show c' should show the appropriate
321parts of the General Public License. Of course, the commands you use may
322be called something other than `show w' and `show c'; they could even be
323mouse-clicks or menu items--whatever suits your program.
324
325You should also get your employer (if you work as a programmer) or your
326school, if any, to sign a "copyright disclaimer" for the program, if
327necessary. 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
335This General Public License does not permit incorporating your program into
336proprietary programs. If your program is a subroutine library, you may
337consider it more useful to permit linking proprietary applications with the
338library. If this is what you want to do, use the GNU Library General
339Public 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
10INCLUDES = -I$(APPSDIR) -I.. -I. -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
11 -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers
12CFLAGS = $(GCCOPTS) -O3 $(INCLUDES) $(TARGET) $(EXTRA_DEFINES) \
13 -DMEM=${MEMORYSIZE} -DPLUGIN
14
15ifdef APPEXTRA
16 INCLUDES += -I$(APPSDIR)/$(APPEXTRA)
17endif
18
19LINKFILE := $(OBJDIR)/link.lds
20DEPFILE = $(OBJDIR)/dep-rockboy
21SRC = 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
24SOURCES = $(SRC)
25OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
26DIRS = .
27
28ifndef SIMVER
29ifneq (,$(findstring RECORDER,$(TARGET))) ## Archos recorder targets
30 LDS := archos.lds
31 OUTPUT = $(OUTDIR)/rockboy.ovl
32else ## iRiver target
33 LDS := ../plugin.lds
34 OUTPUT = $(OUTDIR)/rockboy.rock
35endif
36else ## simulators
37 OUTPUT = $(OUTDIR)/rockboy.rock
38endif
39
40all: $(OUTPUT)
41
42ifndef 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 $< $@
51else
52
53ifeq ($(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 $@
60ifeq ($(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
64else
65 @chmod -x $@
66endif
67
68else # end of x11-simulator
69###################################################
70# This is the win32 simulator version
71DLLTOOLFLAGS = --export-all
72DLLWRAPFLAGS = -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 $@
79ifeq ($(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
83else
84 @chmod -x $@
85endif
86endif # end of win32-simulator
87
88endif # end of simulator section
89
90
91include $(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
100clean:
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
2GNUBOY README
3
4
5 INTRO
6
7Welcome to gnuboy, one of the few pieces of Free Software to emulate
8the Game Boy handheld game console. Written in ANSI C with a few
9optional assembler optimizations for particular cpus, gnuboy supports
10a 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
26Additionally, gnuboy should run on any other *nix variants that have
27ANSI C compilers and that are remotely POSIX compliant. As gnuboy is
28Free Software, you're welcome to fix any problems you encounter
29building it for a particular system, or to port it to entirely new
30systems.
31
32
33 EMULATION
34
35gnuboy emulates nearly all aspects of the (Color) Gameboy, including
36all 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
49Aspects 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
60Only the two marked by * are known to affect the playability of
61actual games or demos; the rest are just listed for completeness'
62sake.
63
64
65 FEATURES
66
67In addition to basic emulation, gnuboy provides the following
68features:
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
81For information on configuring and using these features, see the
82additional documentation in the "docs" directory.
83
84
85 COMPATIBILITY
86
87Out of over 300 results reported by testers, all games are known to
88work 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
117Please report any other incompatibilities discovered directly to
118gnuboy@unix-fu.org, so that they can be documented and hopefully
119fixed.
120
121
122 FUTURE / WISHLIST
123
124Here'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
139Features 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
167Ideas and suggestions for other features are welcome, but won't
168necessarily be used. You're of course also free to add features
169yourself, and if they fit well into the main tree they may eventually
170get included in the official release. See the file HACKING for more
171details on modifying and/or contributing.
172
173
174 THANKS
175
176Thanks goes out to everyone who's expressed interest in gnuboy by
177writing -- users, porters, authors of other emulators, and so forth.
178Apologies if we don't get a personal response out to everyone, but
179either way, consider your feedback appreciated.
180
181
182 EPILOGUE
183
184OK, 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" /*
2VERSION = 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
6OUTPUT_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
14MEMORY
15{
16 OVERLAY_RAM : ORIGIN = OVERLAY_ORIGIN, LENGTH = OVERLAY_LENGTH
17}
18
19SECTIONS
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
20struct 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)++); \
40F = (F & (FL|FC)) | incflag_table[(r)]; }
41
42#define DEC(r) { ((r)--); \
43F = (F & (FL|FC)) | decflag_table[(r)]; }
44
45#define INCW(r) ( (r)++ )
46
47#define DECW(r) ( (r)-- )
48
49#define ADD(n) { \
50W(acc) = (un16)A + (un16)(n); \
51F = (ZFLAG(LB(acc))) \
52| (FH & ((A ^ (n) ^ LB(acc)) << 1)) \
53| (HB(acc) << 4); \
54A = LB(acc); }
55
56#define ADC(n) { \
57W(acc) = (un16)A + (un16)(n) + (un16)((F&FC)>>4); \
58F = (ZFLAG(LB(acc))) \
59| (FH & ((A ^ (n) ^ LB(acc)) << 1)) \
60| (HB(acc) << 4); \
61A = LB(acc); }
62
63#define ADDW(n) { \
64DW(acc) = (un32)HL + (un32)(n); \
65F = (F & (FZ)) \
66| (FH & ((H ^ ((n)>>8) ^ HB(acc)) << 1)) \
67| (acc.b[HI][LO] << 4); \
68HL = W(acc); }
69
70#define ADDSP(n) { \
71DW(acc) = (un32)SP + (un32)(n8)(n); \
72F = (FH & (((SP>>8) ^ ((n)>>8) ^ HB(acc)) << 1)) \
73| (acc.b[HI][LO] << 4); \
74SP = W(acc); }
75
76#define LDHLSP(n) { \
77DW(acc) = (un32)SP + (un32)(n8)(n); \
78F = (FH & (((SP>>8) ^ ((n)>>8) ^ HB(acc)) << 1)) \
79| (acc.b[HI][LO] << 4); \
80HL = W(acc); }
81
82#define CP(n) { \
83W(acc) = (un16)A - (un16)(n); \
84F = 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) { \
92W(acc) = (un16)A - (un16)(n) - (un16)((F&FC)>>4); \
93F = FN \
94| (ZFLAG((n8)LB(acc))) \
95| (FH & ((A ^ (n) ^ LB(acc)) << 1)) \
96| ((un8)(-(n8)HB(acc)) << 4); \
97A = LB(acc); }
98
99#define AND(n) { A &= (n); \
100F = ZFLAG(A) | FH; }
101
102#define XOR(n) { A ^= (n); \
103F = ZFLAG(A); }
104
105#define OR(n) { A |= (n); \
106F = ZFLAG(A); }
107
108#define RLCA(r) { (r) = ((r)>>7) | ((r)<<1); \
109F = (((r)&0x01)<<4); }
110
111#define RRCA(r) { (r) = ((r)<<7) | ((r)>>1); \
112F = (((r)&0x80)>>3); }
113
114#define RLA(r) { \
115LB(acc) = (((r)&0x80)>>3); \
116(r) = ((r)<<1) | ((F&FC)>>4); \
117F = LB(acc); }
118
119#define RRA(r) { \
120LB(acc) = (((r)&0x01)<<4); \
121(r) = ((r)>>1) | ((F&FC)<<3); \
122F = 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) { \
130LB(acc) = (((r)&0x80)>>3); \
131(r) <<= 1; \
132F = ZFLAG((r)) | LB(acc); }
133
134#define SRA(r) { \
135LB(acc) = (((r)&0x01)<<4); \
136(r) = (un8)(((n8)(r))>>1); \
137F = ZFLAG((r)) | LB(acc); }
138
139#define SRL(r) { \
140LB(acc) = (((r)&0x01)<<4); \
141(r) >>= 1; \
142F = ZFLAG((r)) | LB(acc); }
143
144#define CPL(r) { \
145(r) = ~(r); \
146F |= (FH|FN); }
147
148#define SCF { F = (F & (FZ)) | FC; }
149
150#define CCF { F = (F & (FZ|FC)) ^ FC; }
151
152#define DAA { \
153A += (LB(acc) = daa_table[((((int)F)&0x70)<<4) | A]); \
154F = (F & (FN)) | ZFLAG(A) | daa_carry_table[LB(acc)>>2]; }
155
156#define SWAP(r) { \
157(r) = swap_table[(r)]; \
158F = 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) \
165case 0x00|(n): RLC(r); break; \
166case 0x08|(n): RRC(r); break; \
167case 0x10|(n): RL(r); break; \
168case 0x18|(n): RR(r); break; \
169case 0x20|(n): SLA(r); break; \
170case 0x28|(n): SRA(r); break; \
171case 0x30|(n): SWAP(r); break; \
172case 0x38|(n): SRL(r); break; \
173case 0x40|(n): BIT(0, r); break; \
174case 0x48|(n): BIT(1, r); break; \
175case 0x50|(n): BIT(2, r); break; \
176case 0x58|(n): BIT(3, r); break; \
177case 0x60|(n): BIT(4, r); break; \
178case 0x68|(n): BIT(5, r); break; \
179case 0x70|(n): BIT(6, r); break; \
180case 0x78|(n): BIT(7, r); break; \
181case 0x80|(n): RES(0, r); break; \
182case 0x88|(n): RES(1, r); break; \
183case 0x90|(n): RES(2, r); break; \
184case 0x98|(n): RES(3, r); break; \
185case 0xA0|(n): RES(4, r); break; \
186case 0xA8|(n): RES(5, r); break; \
187case 0xB0|(n): RES(6, r); break; \
188case 0xB8|(n): RES(7, r); break; \
189case 0xC0|(n): SET(0, r); break; \
190case 0xC8|(n): SET(1, r); break; \
191case 0xD0|(n): SET(2, r); break; \
192case 0xD8|(n): SET(3, r); break; \
193case 0xE0|(n): SET(4, r); break; \
194case 0xE8|(n): SET(5, r); break; \
195case 0xF0|(n): SET(6, r); break; \
196case 0xF8|(n): SET(7, r); break;
197
198
199#define ALU_CASES(base, imm, op, label) \
200case (imm): b = FETCH; goto label; \
201case (base): b = B; goto label; \
202case (base)+1: b = C; goto label; \
203case (base)+2: b = D; goto label; \
204case (base)+3: b = E; goto label; \
205case (base)+4: b = H; goto label; \
206case (base)+5: b = L; goto label; \
207case (base)+6: b = readb(HL); goto label; \
208case (base)+7: b = A; \
209label: 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
243void 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
266void 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
276void 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
300void lcdc_advance(int cnt)
301{
302 cpu.lcdc -= cnt;
303 if (cpu.lcdc <= 0) lcdc_trans();
304}
305
306void sound_advance(int cnt)
307{
308 cpu.snd += cnt;
309}
310
311void 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
319int 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
355extern int debug_trace;
356
357int 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;
367next:
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
861int 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
11union reg
12{
13 byte b[2][2];
14 word w[2];
15 un32 d; /* padding for alignment, carry */
16};
17
18struct 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
29extern struct cpu cpu;
30
31
32void cpu_reset(void);
33void div_advance(int cnt);
34void timer_advance(int cnt);
35void lcdc_advance(int cnt);
36void sound_advance(int cnt);
37void cpu_timers(int cnt);
38int 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
5static 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
28static 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
53static 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
73static 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
93static 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
113static 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
133static 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
272static 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
16static 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
276static 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
536static 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
559int debug_trace = 0;
560
561rcvar_t debug_exports[] =
562{
563 RCV_BOOL("trace", &debug_trace),
564 RCV_END
565};
566
567void 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
18typedef unsigned char byte;
19
20typedef unsigned char un8;
21typedef unsigned short un16;
22typedef unsigned int un32;
23
24typedef signed char n8;
25typedef signed short n16;
26typedef signed int n32;
27
28typedef un16 word;
29typedef 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
15static int framelen = 16743;
16static int framecount;
17
18rcvar_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
31void 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
43void 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
56void 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
66void 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 @@
1void emu_reset(void);
2void 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
12char keystates[MAX_KEYS];
13int nkeysdown;
14
15#define MAX_EVENTS 32
16
17static event_t eventqueue[MAX_EVENTS];
18static int eventhead, eventpos;
19
20
21int 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
32int 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
7extern rcvar_t emu_exports[], loader_exports[],
8 lcd_exports[], rtc_exports[], sound_exports[],
9 vid_exports[], joy_exports[], pcm_exports[];
10
11
12rcvar_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
26void init_exports(void)
27{
28 rcvar_t **s = sources;
29
30 while (*s)
31 rc_exportvars(*(s++));
32}
33
34
35void 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 @@
1void init_exports(void);
2void 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
15const byte himask[256];
16
17const 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
29const 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
51byte 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
58void 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
65int 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
85void 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
114byte readhi(int a)
115{
116 return readb(a | 0xff00);
117}
118
119void writehi(int a, byte b)
120{
121 writeb(a | 0xff00, b);
122}
123
124#if 0
125byte readhi(int a)
126{
127 byte (*rd)() = hi_read[a];
128 return rd ? rd(a) : (ram.hi[a] | himask[a]);
129}
130
131void 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
10byte readb(int a);
11void writeb(int a, byte b);
12int readw(int a);
13void writew(int a, int w);
14byte readhi(int a);
15void writehi(int a, byte b);
16#if 0
17byte readhi(int a);
18void 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
11struct 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
28extern 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
14struct 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
25void 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
48void 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
60void 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
91void 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
117void 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
141void pad_press(byte k)
142{
143 if (hw.pad & k)
144 return;
145 hw.pad |= k;
146 pad_refresh();
147}
148
149void pad_release(byte k)
150{
151 if (!(hw.pad & k))
152 return;
153 hw.pad &= ~k;
154 pad_refresh();
155}
156
157void pad_set(byte k, int st)
158{
159 st ? pad_press(k) : pad_release(k);
160}
161
162void 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
26struct hw
27{
28 byte ilines;
29 byte pad;
30 int hdma;
31 int cgb,gba;
32};
33
34
35extern struct hw hw;
36
37void hw_interrupt(byte i, byte mask);
38void hw_dma(byte b);
39void hw_hdma_cmd(byte c);
40void hw_hdma(void);
41void pad_refresh(void);
42void pad_press(byte k);
43void pad_release(byte k);
44void pad_set(byte k, int st);
45void 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
20static unsigned int
21peek_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
42static unsigned int
43read_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
53static void
54make_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
78static int
79decode_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
121static int
122get_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 */
250static unsigned int buffer_ptr = 0;
251
252/* The buffer itself */
253static unsigned char buffer[BUFFER_SIZE];
254
255static void
256pushout (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
264static unsigned char
265pushin (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
271static int
272get_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
387static int
388inflate (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
461int
462unzip (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
10typedef 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
21int ev_postevent(event_t *ev);
22int 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
17struct lcd lcd;
18
19struct 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
45byte patpix[4096][8][8];
46byte patdirty[1024];
47byte anydirty;
48
49// static int scale = 1;
50
51static int rgb332;
52
53static int sprsort = 1;
54static int sprdebug;
55static int scanline_ind=0;
56
57#define DEF_PAL { 0x98d0e0, 0x68a0b0, 0x60707C, 0x2C3C3C }
58
59static int dmg_pal[4][4] = { DEF_PAL, DEF_PAL, DEF_PAL, DEF_PAL };
60
61static int usefilter, filterdmg;
62static int filter[3][4] = {
63 { 195, 25, 0, 35 },
64 { 25, 170, 25, 35 },
65 { 25, 60, 125, 40 }
66 };
67
68rcvar_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
85static 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
97void 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
293void 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
394void 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
422void 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
445static void blendcpy(byte *dest, byte *src, byte b, int cnt)
446{
447 while (cnt--) *(dest++) = *(src++) | b;
448}
449
450static 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
456void 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
486void 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
512void 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
545void 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
567static void recolor(byte *buf, byte fill, int cnt)
568{
569 while (cnt--) *(buf++) |= fill;
570}
571
572void 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
592void 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
658void 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
721void 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
735void 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/*
809static 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
876void 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
883void 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
905void 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
913void vram_dirty(void)
914{
915 anydirty = 1;
916 memset(patdirty, 1, sizeof patdirty);
917}
918
919void 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
934void 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
8struct vissprite
9{
10 byte *buf;
11 int x;
12 byte pal, pri, pad[6];
13};
14
15struct 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
28struct obj
29{
30 byte y;
31 byte x;
32 byte pat;
33 byte flags;
34};
35
36struct 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
47extern struct lcd lcd;
48extern struct scan scan;
49
50
51
52
53
54#endif
55
56
57
58void updatepatpix(void);
59void tilebuf(void);
60void bg_scan(void);
61void wnd_scan(void);
62void bg_scan_pri(void);
63void wnd_scan_pri(void);
64void spr_count(void);
65void spr_enum(void);
66void spr_scan(void);
67void lcd_begin(void);
68void lcd_refreshline(void);
69void pal_write(int i, byte b);
70void pal_write_dmg(int i, int mapnum, byte d);
71void vram_write(int a, byte b);
72void vram_dirty(void);
73void pal_dirty(void);
74void 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
25void 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
44void 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
60static 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
71void 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
85void 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 @@
1void stat_trigger(void);
2void stat_write(byte b);
3void lcdc_change(byte b);
4void 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
17static 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
40static 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
47static 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
54static 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
70static int ramsize_table[256] =
71{
72 1, 1, 1, 4, 16,
73 4 /* FIXME - what value should this be?! */
74};
75
76
77static char *romfile;
78static char sramfile[500];
79static char rtcfile[500];
80static char saveprefix[500];
81
82static char *savename;
83static char *savedir = "/.rockbox/rockboy";
84
85static int saveslot;
86
87static int forcebatt, nobatt;
88static int forcedmg;
89
90static int memfill = -1, memrand = -1;
91
92//static byte romMemory[4*1025*1024];
93int mp3_buffer_size;
94void *bufferpos;
95
96static 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
108static 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
129int 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
190int 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
213int 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
234void 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
251void 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
271void 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
280void 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
290void 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/*
305static char *base(char *s)
306{
307 char *p;
308 p = strrchr(s, '/');
309 if (p) return p+1;
310 return s;
311}
312
313
314static 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
324void cleanup(void)
325{
326 sram_save();
327 rtc_save();
328 // IDEA - if error, write emergency savestate..?
329}
330
331void 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
363rcvar_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
7typedef struct loader_s
8{
9 char *rom;
10 char *base;
11 char *sram;
12 char *state;
13 int ramloaded;
14} loader_t;
15
16
17extern loader_t loader;
18
19
20int rom_load(void);
21int sram_load(void);
22int sram_save(void);
23void loader_init(char *s);
24void 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
15static 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
31void 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
48int 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
14struct mbc mbc;
15struct rom rom;
16struct 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
31void 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
95void 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
241byte 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
298void 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
446void 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
516byte 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
565void 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
19struct 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
32struct rom
33{
34 byte (*bank)[16384];
35 char name[20];
36};
37
38struct ram
39{
40 byte hi[256];
41 byte ibank[8][4096];
42 byte (*sbank)[8192];
43 int loaded;
44};
45
46
47extern struct mbc mbc;
48extern struct rom rom;
49extern struct ram ram;
50
51
52
53
54
55void mem_updatemap(void);
56void ioreg_write(byte r, byte b);
57void mbc_write(int a, byte b);
58void mem_write(int a, byte b);
59byte mem_read(int a);
60void 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
8static byte noise7[] =
9{
10 0xfd,0xf3,0xd7,0x0d,0xd3,0x15,0x82,0xf1,
11 0xdb,0x25,0x21,0x39,0x68,0x8c,0xd5,0x00,
12};
13
14static 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
10struct pcm pcm;
11
12static byte buf[4096];
13
14
15rcvar_t pcm_exports[] =
16{
17 RCV_END
18};
19
20
21void pcm_init(void)
22{
23 pcm.hz = 11025;
24 pcm.buf = buf;
25 pcm.len = sizeof buf;
26 pcm.pos = 0;
27}
28
29void pcm_close(void)
30{
31 memset(&pcm, 0, sizeof pcm);
32}
33
34int 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
9static byte palmap[32768];
10static byte pallock[256];
11static int palrev[256];
12
13/* Course color mapping, for when palette is exhausted. */
14static byte crsmap[4][32768];
15static int crsrev[4][256];
16static const int crsmask[4] = { 0x7BDE, 0x739C, 0x6318, 0x4210 };
17
18enum plstatus
19{
20 pl_unused = 0,
21 pl_linger,
22 pl_active,
23 pl_locked
24};
25
26/*
27static 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
57static 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
68static 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
83void 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
91byte 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
116void pal_release(byte n)
117{
118 if (pallock[n] >= pl_locked)
119 pallock[n]--;
120}
121
122
123void 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
132void 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 @@
1void pal_lock(byte n);
2byte pal_getcolor(int c, int r, int g, int b);
3void pal_release(byte n);
4void pal_expire(void);
5void pal_set332(void);
6void 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
8struct pcm
9{
10 int hz, len;
11 int stereo;
12 byte *buf;
13 int pos;
14};
15
16extern 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
9typedef enum rctype
10{
11 rcv_end,
12 rcv_int,
13 rcv_string,
14 rcv_vector,
15 rcv_bool
16} rcvtype_t;
17
18
19typedef 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
33typedef 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
42void rc_export(rcvar_t *v);
43void rc_exportvars(rcvar_t *vars);
44
45int rc_findvar(char *name);
46
47int rc_setvar_n(int i, int c, char **v);
48int rc_setvar(char *name, int c, char **v);
49
50int rc_getint_n(int i);
51int *rc_getvec_n(int i);
52char *rc_getstr_n(int i);
53
54int rc_getint(char *name);
55int *rc_getvec(char *name);
56char *rc_getstr(char *name);
57
58int rc_bindkey(char *keyname, char *cmd);
59int rc_unbindkey(char *keyname);
60void rc_unbindall(void);
61
62int rc_sourcefile(char *filename);
63void rc_dokey(int key, int st);
64
65int 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
18static 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
31static int cmd_reset(int argc, char **argv)
32{
33 (void)argc;
34 (void)argv;
35 emu_reset();
36 return 0;
37}
38
39static int cmd_savestate(int argc, char **argv)
40{
41 state_save(argc > 1 ? atoi(argv[1]) : -1);
42 return 0;
43}
44
45static 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
57rccmd_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
70int 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
16static rcvar_t rcvars[150];
17
18static int nvars;
19
20
21
22
23
24void 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
37void rc_exportvars(rcvar_t *vars)
38{
39 while(vars->type)
40 rc_export(vars++);
41}
42
43
44
45int 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
58int 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
111int 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
151int 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
162void *rc_getmem_n(int i)
163{
164 return rcvars[i].mem;
165}
166
167
168void *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
176int 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
188int *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
201char *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
212int rc_getint(char *name)
213{
214 return rc_getint_n(rc_findvar(name));
215}
216
217int *rc_getvec(char *name)
218{
219 return rc_getvec_n(rc_findvar(name));
220}
221
222char *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 */
27extern unsigned char ovl_start_addr[];
28extern unsigned char ovl_end_addr[];
29
30const 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 */
44struct plugin_api* rb;
45int shut,cleanshut;
46char *errormsg;
47int gnuboy_main(char *rom);
48
49/* libc functions */
50
51int isdigit(int c) {
52 return c>='0' && c<= '9';
53}
54
55int isalpha(int c) {
56 return (c>='a' && c<='z')||(c>='A' && c<='Z');
57}
58
59int isupper(int c) {
60 return c>='A'&&c<='Z';
61}
62
63int isalnum(int c) {
64 return isdigit(c)||isalpha(c);
65}
66
67void die(char *message, ...)
68{
69 shut=1;
70 errormsg=message;
71}
72
73void *mp3_bufferbase;
74void *mp3_bufferpointer;
75unsigned int mp3_buffer_free;
76
77void *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
100void 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 */
107enum 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)
28void *my_malloc(size_t size);
29
30extern struct plugin_api* rb;
31extern int shut,cleanshut;
32void vid_update(int scanline);
33void vid_init(void);
34void vid_begin(void);
35void vid_end(void);
36void die(char *message, ...);
37void setmallocpos(void *pointer);
38void vid_settitle(char *title);
39void *sys_timer(void);
40int sys_elapsed(long *oldtick);
41void sys_sleep(int us);
42int pcm_submit(void);
43void pcm_init(void);
44void doevents(void);
45int isupper(int c);
46int isdigit(int c);
47void 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
12struct rtc rtc;
13
14static int syncrtc = 1;
15
16rcvar_t rtc_exports[] =
17{
18 RCV_BOOL("syncrtc", &syncrtc),
19 RCV_END
20};
21
22
23void 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
39void 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
70void 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
96void 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
105void 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
7struct 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
17extern struct rtc rtc;
18
19void rtc_latch(byte b);
20void rtc_write(byte b);
21void rtc_tick(void);
22void rtc_save_internal(int fd);
23void 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
31struct svar
32{
33 int len;
34 char key[4];
35 void *ptr;
36};
37
38static int ver;
39static int sramblock, iramblock, vramblock;
40static int hramofs, hiofs, palofs, oamofs, wavofs;
41
42struct 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
155void 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
212void 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 @@
1void loadstate(int fd);
2void savestate(int fd);
3void state_save(int n);
4void 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
15static 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
23static 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
32static 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
40static 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
52struct snd snd;
53int 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
62rcvar_t sound_exports[] =
63 {
64 RCV_END
65 };
66
67
68static void s1_freq_d(int d)
69{
70 if (RATE > (d<<4)) S1.freq = 0;
71 else S1.freq = (RATE << 17)/d;
72}
73
74static void s1_freq(void)
75{
76 s1_freq_d(2048 - (((R_NR14&7)<<8) + R_NR13));
77}
78
79static 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
86static 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
93static 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
99void 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
124void 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
151void 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
162void 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
289byte sound_read(byte r)
290{
291 sound_mix();
292 /* printf("read %02X: %02X\n", r, REG(r)); */
293 return REG(r);
294}
295
296void 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
310void 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
322void 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
332void 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
345void 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
7struct 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
19struct snd
20{
21 int rate;
22 struct sndchan ch[4];
23 byte wave[16];
24};
25
26
27extern struct snd snd;
28
29byte sound_read(byte r);
30void sound_write(byte r, byte b);
31void sound_dirty(void);
32void sound_off(void);
33void sound_reset(void);
34void sound_mix(void);
35void s1_init(void);
36void s2_init(void);
37void s3_init(void);
38void 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
10char *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
44int 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
28rcvar_t joy_exports[] =
29{
30 RCV_END
31};
32
33rcvar_t vid_exports[] =
34{
35 RCV_END
36};
37
38struct fb fb;
39byte *video_base_buf;
40
41extern int debug_trace;
42
43static byte frameb[145][160];
44
45void vid_settitle(char *title)
46{
47 rb->splash(HZ*2, true, title);
48}
49
50void joy_init(void)
51{
52}
53
54void 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
74unsigned int oldbuttonstate = 0, newbuttonstate;
75
76void 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
126void 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
134void vid_init(void)
135{
136}
137
138void 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
149void 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
249void vid_end(void)
250{
251}
252
253long timerresult;
254
255void *sys_timer(void)
256{
257 timerresult=*rb->current_tick;
258 return &timerresult;
259}
260
261// returns microseconds passed since sys_timer
262int sys_elapsed(long *oldtick)
263{
264 return ((*rb->current_tick-(*oldtick))*1000000)/HZ;
265}
266
267void 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
6mp3,vbrfix.rock,10 08 58 38 04 02 6mp3,vbrfix.rock,10 08 58 38 04 02
7m3u,search.rock,00 00 00 00 00 00 7m3u,search.rock,00 00 00 00 00 00
8txt,sort.rock, 00 00 00 00 00 00 8txt,sort.rock, 00 00 00 00 00 00
9gb,rockboy.rock, 0C 2A 59 7A 2E 0C
10cgb,rockboy.rock, 0C 2A 59 7A 2E 0C
9mp2,mpa2wav.rock, 00 00 00 00 00 00 11mp2,mpa2wav.rock, 00 00 00 00 00 00
10mp3,mpa2wav.rock, 00 00 00 00 00 00 12mp3,mpa2wav.rock, 00 00 00 00 00 00
11ac3,a52towav.rock, 00 00 00 00 00 00 13ac3,a52towav.rock, 00 00 00 00 00 00