mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
Rockboy - gameboy emulation for rockbox, based on gnuboy. Still a bit early, but already playable on iRiver H1xx and the simulators. The archos recorder version is currently rather slow...
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6104 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
48dad47df9
commit
384de10246
56 changed files with 9225 additions and 1 deletions
|
@ -34,7 +34,13 @@ OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
|
|||
DEFS := $(SRC:%.c=$(OBJDIR)/%.def)
|
||||
DIRS = .
|
||||
|
||||
all: $(OBJDIR)/libplugin.a $(ROCKS) $(DEPFILE)
|
||||
#for any recorder and iRiver model
|
||||
ifneq (,$(strip $(foreach tgt,RECORDER IRIVER,$(findstring $(tgt),$(TARGET)))))
|
||||
SUBDIRS += rockboy
|
||||
endif
|
||||
|
||||
.PHONY: $(SUBDIRS)
|
||||
all: $(OBJDIR)/libplugin.a $(ROCKS) $(SUBDIRS) $(DEPFILE)
|
||||
|
||||
ifndef SIMVER
|
||||
$(OBJDIR)/%.elf: $(OBJDIR)/%.o $(LINKFILE) $(OBJDIR)/libplugin.a
|
||||
|
@ -95,10 +101,16 @@ $(LINKFILE): $(LDS)
|
|||
@echo "build $@"
|
||||
@cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) $(DEFINES) -E -P - >$@
|
||||
|
||||
$(SUBDIRS):
|
||||
@echo "MAKE in $@"
|
||||
@mkdir -p $(OBJDIR)/$@
|
||||
@$(MAKE) -C $@ TARGET=$(TARGET) DEBUG=$(DEBUG) OUTDIR=$(OBJDIR) OBJDIR=$(OBJDIR)/$@ VERSION=$(VERSION) EXTRA_DEFINES="$(EXTRA_DEFINES)" MEM=${MEMORYSIZE}
|
||||
|
||||
clean:
|
||||
@echo "cleaning plugins"
|
||||
@rm -f $(ROCKS) $(LINKFILE) $(OBJDIR)/*.rock $(DEPFILE) $(ELFS) \
|
||||
$(OBJS) $(DEFS)
|
||||
@$(MAKE) -C lib clean
|
||||
@$(MAKE) -C rockboy clean
|
||||
|
||||
-include $(DEPFILE)
|
||||
|
|
|
@ -29,6 +29,10 @@ oscillograph.c
|
|||
oscilloscope.c
|
||||
pong.c
|
||||
rockblox.c
|
||||
#if (CONFIG_KEYPAD == RECORDER_PAD) && !defined(SIMULATOR)
|
||||
/* loader, only needed for Archos */
|
||||
rockboy.c
|
||||
#endif
|
||||
sliding_puzzle.c
|
||||
snake.c
|
||||
snake2.c
|
||||
|
|
81
apps/plugins/rockboy.c
Normal file
81
apps/plugins/rockboy.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2005 Jens Arnold
|
||||
*
|
||||
* Overlay loader for rockboy on Archos
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "plugin.h"
|
||||
|
||||
#if MEM <= 8 && !defined(SIMULATOR)
|
||||
|
||||
#define OVL_NAME "/.rockbox/viewers/rockboy.ovl"
|
||||
#define OVL_DISPLAYNAME "RockBoy"
|
||||
|
||||
struct plugin_api* rb;
|
||||
unsigned char *mp3buf;
|
||||
int mp3buf_size;
|
||||
|
||||
/* this is the plugin entry point */
|
||||
enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||
{
|
||||
int fh, readsize;
|
||||
struct {
|
||||
unsigned long magic;
|
||||
unsigned char *start_addr;
|
||||
unsigned char *end_addr;
|
||||
enum plugin_status(*entry_point)(struct plugin_api*, void*);
|
||||
} header;
|
||||
|
||||
/* this macro should be called as the first thing you do in the plugin.
|
||||
it test that the api version and model the plugin was compiled for
|
||||
matches the machine it is running on */
|
||||
TEST_PLUGIN_API(api);
|
||||
rb = api;
|
||||
|
||||
fh = rb->open(OVL_NAME, O_RDONLY);
|
||||
if (fh < 0)
|
||||
{
|
||||
rb->splash(2*HZ, true, "Couldn't open " OVL_DISPLAYNAME " overlay.");
|
||||
return PLUGIN_ERROR;
|
||||
}
|
||||
readsize = rb->read(fh, &header, sizeof(header));
|
||||
if (readsize != sizeof(header) || header.magic != 0x524f564c)
|
||||
{
|
||||
rb->close(fh);
|
||||
rb->splash(2*HZ, true, OVL_NAME " is not a valid Rockbox overlay.");
|
||||
return PLUGIN_ERROR;
|
||||
}
|
||||
|
||||
mp3buf = rb->plugin_get_mp3_buffer(&mp3buf_size);
|
||||
if (header.start_addr < mp3buf || header.end_addr > mp3buf + mp3buf_size)
|
||||
{
|
||||
rb->close(fh);
|
||||
rb->splash(2*HZ, true, OVL_DISPLAYNAME
|
||||
" overlay doesn't fit into memory.");
|
||||
return PLUGIN_ERROR;
|
||||
}
|
||||
rb->lseek(fh, 0, SEEK_SET);
|
||||
readsize = rb->read(fh, header.start_addr, header.end_addr - header.start_addr);
|
||||
rb->close(fh);
|
||||
if (readsize != header.end_addr - header.start_addr)
|
||||
{
|
||||
rb->splash(2*HZ, true, "Error loading " OVL_DISPLAYNAME " overlay.");
|
||||
return PLUGIN_ERROR;
|
||||
}
|
||||
return header.entry_point(api, parameter);
|
||||
}
|
||||
#endif
|
339
apps/plugins/rockboy/COPYING
Executable file
339
apps/plugins/rockboy/COPYING
Executable file
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
106
apps/plugins/rockboy/Makefile
Normal file
106
apps/plugins/rockboy/Makefile
Normal file
|
@ -0,0 +1,106 @@
|
|||
# __________ __ ___.
|
||||
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
# \/ \/ \/ \/ \/
|
||||
# $Id$
|
||||
#
|
||||
|
||||
INCLUDES = -I$(APPSDIR) -I.. -I. -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
|
||||
-I$(FIRMDIR)/common -I$(FIRMDIR)/drivers
|
||||
CFLAGS = $(GCCOPTS) -O3 $(INCLUDES) $(TARGET) $(EXTRA_DEFINES) \
|
||||
-DMEM=${MEMORYSIZE} -DPLUGIN
|
||||
|
||||
ifdef APPEXTRA
|
||||
INCLUDES += -I$(APPSDIR)/$(APPEXTRA)
|
||||
endif
|
||||
|
||||
LINKFILE := $(OBJDIR)/link.lds
|
||||
DEPFILE = $(OBJDIR)/dep-rockboy
|
||||
SRC = cpu.c emu.c events.c exports.c fastmem.c hw.c lcd.c lcdc.c loader.c \
|
||||
main.c mem.c nosound.c rccmds.c rcvars.c rtc.c save.c sound.c split.c \
|
||||
sys_rockbox.c rockboy.c
|
||||
SOURCES = $(SRC)
|
||||
OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
|
||||
DIRS = .
|
||||
|
||||
ifndef SIMVER
|
||||
ifneq (,$(findstring RECORDER,$(TARGET))) ## Archos recorder targets
|
||||
LDS := archos.lds
|
||||
OUTPUT = $(OUTDIR)/rockboy.ovl
|
||||
else ## iRiver target
|
||||
LDS := ../plugin.lds
|
||||
OUTPUT = $(OUTDIR)/rockboy.rock
|
||||
endif
|
||||
else ## simulators
|
||||
OUTPUT = $(OUTDIR)/rockboy.rock
|
||||
endif
|
||||
|
||||
all: $(OUTPUT)
|
||||
|
||||
ifndef SIMVER
|
||||
$(OBJDIR)/rockboy.elf: $(OBJS) $(LINKFILE) $(OUTDIR)/libplugin.a
|
||||
@echo "LD $@"
|
||||
@$(CC) $(GCCOPTS) -O -nostdlib -o $@ $(OBJS) -L$(OUTDIR) -lplugin -lgcc \
|
||||
-T$(LINKFILE) -Wl,-Map,$(OBJDIR)/rockboy.map
|
||||
|
||||
$(OUTPUT): $(OBJDIR)/rockboy.elf
|
||||
@echo "OBJCOPY $<"
|
||||
@$(OC) -O binary $< $@
|
||||
else
|
||||
|
||||
ifeq ($(SIMVER), x11)
|
||||
###################################################
|
||||
# This is the X11 simulator version
|
||||
|
||||
$(OUTPUT): $(OBJS) $(OUTDIR)/libplugin.a
|
||||
@echo "LD $@"
|
||||
@$(CC) $(CFLAGS) -shared $(OBJS) -L$(OUTDIR) -lplugin -o $@
|
||||
ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
|
||||
# 'x' must be kept or you'll have "Win32 error 5"
|
||||
# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
|
||||
# #define ERROR_ACCESS_DENIED 5L
|
||||
else
|
||||
@chmod -x $@
|
||||
endif
|
||||
|
||||
else # end of x11-simulator
|
||||
###################################################
|
||||
# This is the win32 simulator version
|
||||
DLLTOOLFLAGS = --export-all
|
||||
DLLWRAPFLAGS = -s --entry _DllMain@12 --target=i386-mingw32 -mno-cygwin
|
||||
|
||||
$(OUTPUT): $(OBJS) $(OUTDIR)/libplugin.a
|
||||
@echo "DLL $@"
|
||||
@$(DLLTOOL) $(DLLTOOLFLAGS) -z $(OBJDIR)/$*.def $(OBJS)
|
||||
@$(DLLWRAP) $(DLLWRAPFLAGS) --def $(OBJDIR)/$*.def $(OBJS) \
|
||||
$(OUTDIR)/libplugin.a -o $@
|
||||
ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
|
||||
# 'x' must be kept or you'll have "Win32 error 5"
|
||||
# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
|
||||
# #define ERROR_ACCESS_DENIED 5L
|
||||
else
|
||||
@chmod -x $@
|
||||
endif
|
||||
endif # end of win32-simulator
|
||||
|
||||
endif # end of simulator section
|
||||
|
||||
|
||||
include $(TOOLSDIR)/make.inc
|
||||
|
||||
# MEM should be passed on to this makefile with the chosen memory size given
|
||||
# in number of MB
|
||||
$(LINKFILE): $(LDS)
|
||||
@echo "build $@"
|
||||
@cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) $(DEFINES) \
|
||||
-E -P - >$@
|
||||
|
||||
clean:
|
||||
@echo "cleaning rockboy"
|
||||
@rm -rf $(OBJDIR)/rockboy
|
||||
@rm -f $(OBJDIR)/rockboy.*
|
||||
|
||||
-include $(DEPFILE)
|
||||
|
199
apps/plugins/rockboy/README
Executable file
199
apps/plugins/rockboy/README
Executable file
|
@ -0,0 +1,199 @@
|
|||
|
||||
GNUBOY README
|
||||
|
||||
|
||||
INTRO
|
||||
|
||||
Welcome to gnuboy, one of the few pieces of Free Software to emulate
|
||||
the Game Boy handheld game console. Written in ANSI C with a few
|
||||
optional assembler optimizations for particular cpus, gnuboy supports
|
||||
a wide range of host systems, and has been tested successfully on:
|
||||
|
||||
GNU/Linux
|
||||
FreeBSD
|
||||
OpenBSD
|
||||
BeOS
|
||||
Linux/390 (IBM S/390 Mainframe)
|
||||
SunOS/Sun Ultra60
|
||||
IRIX/SGI O2
|
||||
IRIX/SGI Indy
|
||||
AIX/Unknown
|
||||
DR-DOS
|
||||
MS-DOS
|
||||
Windows DOS box
|
||||
Windows 9x/NT/2k
|
||||
|
||||
Additionally, gnuboy should run on any other *nix variants that have
|
||||
ANSI C compilers and that are remotely POSIX compliant. As gnuboy is
|
||||
Free Software, you're welcome to fix any problems you encounter
|
||||
building it for a particular system, or to port it to entirely new
|
||||
systems.
|
||||
|
||||
|
||||
EMULATION
|
||||
|
||||
gnuboy emulates nearly all aspects of the (Color) Gameboy, including
|
||||
all of the following and much more:
|
||||
|
||||
Full GBZ80 instruction set.
|
||||
Scanline-based LCD engine.
|
||||
Ten sprites per scanline limit.
|
||||
Support for all CGB graphics extensions.
|
||||
Sprite DMA, HDMA, and GDMA.
|
||||
All four sound channels including digital samples.
|
||||
MBC1, MBC2, MBC3 (including clock), and MBC5 mappers.
|
||||
Wave pattern memory corruption when sound channel 3 is played.
|
||||
Pad, timer, divide counter, and other basic hardware registers.
|
||||
CGB double-speed CPU mode.
|
||||
|
||||
Aspects not emulated at this time include:
|
||||
|
||||
* Serial IO (link cable).
|
||||
Undocumented 'extra' ram in OAM space on Gameboy Color.
|
||||
All Super Gameboy extensions.
|
||||
* GBC, HuC1, and HuC3 IR ports.
|
||||
* Obscure mappers such as TAMA5.
|
||||
Sorting sprites by X coordinate in DMG mode.
|
||||
HALT instruction skipping in DMG mode.
|
||||
CPU stalls during HDMA and GDMA.
|
||||
|
||||
Only the two marked by * are known to affect the playability of
|
||||
actual games or demos; the rest are just listed for completeness'
|
||||
sake.
|
||||
|
||||
|
||||
FEATURES
|
||||
|
||||
In addition to basic emulation, gnuboy provides the following
|
||||
features:
|
||||
|
||||
Highly flexible keybinding and configuration subsystem.
|
||||
State saving and loading at any point.
|
||||
Very precise timing/synchronization, preserved across save/load.
|
||||
Joystick support on Linux, DOS, and all SDL-based ports.
|
||||
Fully customizable palettes for DMG games.
|
||||
Screen scaling by a factor of 2, 3, or 4 in all ports.
|
||||
Hardware-based screen scaling on platforms where it's available.
|
||||
Debug traces to stdout.
|
||||
Dynamic palette allocation when run in 256-color modes...
|
||||
OR simulated 3/3/2 bits per channel in 256-color modes.
|
||||
|
||||
For information on configuring and using these features, see the
|
||||
additional documentation in the "docs" directory.
|
||||
|
||||
|
||||
COMPATIBILITY
|
||||
|
||||
Out of over 300 results reported by testers, all games are known to
|
||||
work perfectly on gnuboy with the following exceptions:
|
||||
|
||||
Fighting Phoenix (Japanese) may or may not work since it uses the
|
||||
HuC1 memory controller, which is not implemented properly. There has
|
||||
been no report either way so far.
|
||||
|
||||
Pocket Bomberman (Japanese version, which uses HuC1) runs, but can
|
||||
be made to crash if the player jumps into the ceiling in the first
|
||||
level. It's not clear whether this bug is MBC-related, something
|
||||
else, or an actual bug in the original game.
|
||||
|
||||
Monster Go! Go! Go! (Japanese) is unplayable. The cause of the
|
||||
problem is not fully known, but it's either a very bad dump or it's
|
||||
using some sort of specialized MBC that's not documented.
|
||||
|
||||
Final Fantasy Adventure has visual problems with the fade between
|
||||
screens. Does not affect gameplay.
|
||||
|
||||
Bubble Bobble 2 has some minor tile glitches right before gameplay
|
||||
actually begins. Cause unknown. Does not affect gameplay.
|
||||
|
||||
Alone in the Dark is reported to have minor visual glitches. I
|
||||
haven't seen it myself so I can't judge their severity.
|
||||
|
||||
Both new Zelda games are reported to have a visual glitch at the
|
||||
beginning of the game, and on certain other screens. I haven't seen
|
||||
the problem myself, but supposedly it impacts gameplay to some
|
||||
extent.
|
||||
|
||||
Please report any other incompatibilities discovered directly to
|
||||
gnuboy@unix-fu.org, so that they can be documented and hopefully
|
||||
fixed.
|
||||
|
||||
|
||||
FUTURE / WISHLIST
|
||||
|
||||
Here's a brief list of what may appear in gnuboy in the future:
|
||||
|
||||
Screenshots.
|
||||
Integrated debugger.
|
||||
Super Gameboy support.
|
||||
Serial link over the internet.
|
||||
Serial link to a real Gameboy with a custom cable.
|
||||
Configurable color filters to provide more authentic LCD look.
|
||||
Custom colorization of DMG games on a per-tile basis.
|
||||
Support for more colorspaces in the hardware scaler.
|
||||
Recording audio.
|
||||
GBS player built from the same source tree.
|
||||
Full recording and playback of emulation.
|
||||
So-called "high level emulation" of certain typical dumb loops.
|
||||
|
||||
Features that are not likely to appear soon or at all include:
|
||||
|
||||
Rumble support - this would be nice, but SDL doesn't seem to support
|
||||
force-feedback yet. We'll see about it in the long-term though.
|
||||
|
||||
Eagle/2xSaI/etc. - probably not feasible since these libraries don't
|
||||
appear to be compatible with the terms of the GPL. We might work on
|
||||
our own interpolation engine eventually, but that's low priority.
|
||||
|
||||
GUI/GUI-like features - such things are best handled by external
|
||||
front-ends. We might eventually add a mechanism for external
|
||||
programs to communicate with gnuboy and reconfigure it while it's
|
||||
running, however.
|
||||
|
||||
Plugins - NO! The way I see it, plugins are just an attempt to work
|
||||
around the GPL. In any case, even if you are adding plugin support
|
||||
yourself, you are bound by the terms of the GPL when linking ANY
|
||||
code to gnuboy, including dynamic-linked modules. However we'd
|
||||
rather not deal with this mess to begin with.
|
||||
|
||||
Compressed ROMs/Saves - this one is very iffy. On most systems, this
|
||||
is redundant; *nix users can just pipe the rom through a
|
||||
decompression program, and Windows users can just double-click or
|
||||
drag files from their favorite GUI unzipper program. Linking to zlib
|
||||
isn't really acceptable since it's massively bloated and we don't
|
||||
want to include it with gnuboy or add external dependencies. We may,
|
||||
however, write our own tiny decompressor to use at some point.
|
||||
|
||||
Ideas and suggestions for other features are welcome, but won't
|
||||
necessarily be used. You're of course also free to add features
|
||||
yourself, and if they fit well into the main tree they may eventually
|
||||
get included in the official release. See the file HACKING for more
|
||||
details on modifying and/or contributing.
|
||||
|
||||
|
||||
THANKS
|
||||
|
||||
Thanks goes out to everyone who's expressed interest in gnuboy by
|
||||
writing -- users, porters, authors of other emulators, and so forth.
|
||||
Apologies if we don't get a personal response out to everyone, but
|
||||
either way, consider your feedback appreciated.
|
||||
|
||||
|
||||
EPILOGUE
|
||||
|
||||
OK, that looks like about it. More to come, stick around...
|
||||
|
||||
|
||||
|
||||
-Laguna <laguna@aerifal.cx>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
5
apps/plugins/rockboy/Version
Executable file
5
apps/plugins/rockboy/Version
Executable file
|
@ -0,0 +1,5 @@
|
|||
#define VERSION "1.0.3" /*
|
||||
VERSION = 1.0.3
|
||||
# */
|
||||
|
||||
|
46
apps/plugins/rockboy/archos.lds
Executable file
46
apps/plugins/rockboy/archos.lds
Executable file
|
@ -0,0 +1,46 @@
|
|||
#include "config.h"
|
||||
|
||||
/* linker script for rockboy as an overlay,
|
||||
* only used/ necessary for SH-based archos targets */
|
||||
|
||||
OUTPUT_FORMAT(elf32-sh)
|
||||
|
||||
#define DRAMORIG 0x09000000
|
||||
#define PLUGIN_LENGTH 0x8000
|
||||
|
||||
#define OVERLAY_LENGTH 0x68000
|
||||
#define OVERLAY_ORIGIN (DRAMORIG + (MEMORYSIZE * 0x100000) - PLUGIN_LENGTH - OVERLAY_LENGTH)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
OVERLAY_RAM : ORIGIN = OVERLAY_ORIGIN, LENGTH = OVERLAY_LENGTH
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.header : {
|
||||
_ovl_start_addr = .;
|
||||
*(.header)
|
||||
} > OVERLAY_RAM
|
||||
|
||||
.text : {
|
||||
*(.entry)
|
||||
*(.text)
|
||||
} > OVERLAY_RAM
|
||||
|
||||
.data : {
|
||||
*(.data)
|
||||
} > OVERLAY_RAM
|
||||
|
||||
.bss : {
|
||||
*(.bss)
|
||||
} > OVERLAY_RAM
|
||||
|
||||
.rodata : {
|
||||
*(.rodata)
|
||||
*(.rodata.str1.1)
|
||||
*(.rodata.str1.4)
|
||||
. = ALIGN(0x4);
|
||||
_ovl_end_addr = .;
|
||||
} > OVERLAY_RAM
|
||||
}
|
880
apps/plugins/rockboy/cpu.c
Normal file
880
apps/plugins/rockboy/cpu.c
Normal file
|
@ -0,0 +1,880 @@
|
|||
|
||||
|
||||
|
||||
#include "rockmacros.h"
|
||||
#include "defs.h"
|
||||
#include "regs.h"
|
||||
#include "hw.h"
|
||||
#include "cpu.h"
|
||||
#include "lcdc.h"
|
||||
#include "mem.h"
|
||||
#include "fastmem.h"
|
||||
#include "cpuregs.h"
|
||||
#include "cpucore.h"
|
||||
|
||||
#ifdef USE_ASM
|
||||
#include "asm.h"
|
||||
#endif
|
||||
|
||||
|
||||
struct cpu cpu;
|
||||
|
||||
|
||||
|
||||
|
||||
#define ZFLAG(n) ( (n) ? 0 : FZ )
|
||||
|
||||
|
||||
#define PUSH(w) ( (SP -= 2), (writew(xSP, (w))) )
|
||||
#define POP(w) ( ((w) = readw(xSP)), (SP += 2) )
|
||||
|
||||
|
||||
#define FETCH_OLD ( mbc.rmap[PC>>12] \
|
||||
? mbc.rmap[PC>>12][PC++] \
|
||||
: mem_read(PC++) )
|
||||
|
||||
#define FETCH (readb(PC++))
|
||||
|
||||
|
||||
#define INC(r) { ((r)++); \
|
||||
F = (F & (FL|FC)) | incflag_table[(r)]; }
|
||||
|
||||
#define DEC(r) { ((r)--); \
|
||||
F = (F & (FL|FC)) | decflag_table[(r)]; }
|
||||
|
||||
#define INCW(r) ( (r)++ )
|
||||
|
||||
#define DECW(r) ( (r)-- )
|
||||
|
||||
#define ADD(n) { \
|
||||
W(acc) = (un16)A + (un16)(n); \
|
||||
F = (ZFLAG(LB(acc))) \
|
||||
| (FH & ((A ^ (n) ^ LB(acc)) << 1)) \
|
||||
| (HB(acc) << 4); \
|
||||
A = LB(acc); }
|
||||
|
||||
#define ADC(n) { \
|
||||
W(acc) = (un16)A + (un16)(n) + (un16)((F&FC)>>4); \
|
||||
F = (ZFLAG(LB(acc))) \
|
||||
| (FH & ((A ^ (n) ^ LB(acc)) << 1)) \
|
||||
| (HB(acc) << 4); \
|
||||
A = LB(acc); }
|
||||
|
||||
#define ADDW(n) { \
|
||||
DW(acc) = (un32)HL + (un32)(n); \
|
||||
F = (F & (FZ)) \
|
||||
| (FH & ((H ^ ((n)>>8) ^ HB(acc)) << 1)) \
|
||||
| (acc.b[HI][LO] << 4); \
|
||||
HL = W(acc); }
|
||||
|
||||
#define ADDSP(n) { \
|
||||
DW(acc) = (un32)SP + (un32)(n8)(n); \
|
||||
F = (FH & (((SP>>8) ^ ((n)>>8) ^ HB(acc)) << 1)) \
|
||||
| (acc.b[HI][LO] << 4); \
|
||||
SP = W(acc); }
|
||||
|
||||
#define LDHLSP(n) { \
|
||||
DW(acc) = (un32)SP + (un32)(n8)(n); \
|
||||
F = (FH & (((SP>>8) ^ ((n)>>8) ^ HB(acc)) << 1)) \
|
||||
| (acc.b[HI][LO] << 4); \
|
||||
HL = W(acc); }
|
||||
|
||||
#define CP(n) { \
|
||||
W(acc) = (un16)A - (un16)(n); \
|
||||
F = FN \
|
||||
| (ZFLAG(LB(acc))) \
|
||||
| (FH & ((A ^ (n) ^ LB(acc)) << 1)) \
|
||||
| ((un8)(-(n8)HB(acc)) << 4); }
|
||||
|
||||
#define SUB(n) { CP((n)); A = LB(acc); }
|
||||
|
||||
#define SBC(n) { \
|
||||
W(acc) = (un16)A - (un16)(n) - (un16)((F&FC)>>4); \
|
||||
F = FN \
|
||||
| (ZFLAG((n8)LB(acc))) \
|
||||
| (FH & ((A ^ (n) ^ LB(acc)) << 1)) \
|
||||
| ((un8)(-(n8)HB(acc)) << 4); \
|
||||
A = LB(acc); }
|
||||
|
||||
#define AND(n) { A &= (n); \
|
||||
F = ZFLAG(A) | FH; }
|
||||
|
||||
#define XOR(n) { A ^= (n); \
|
||||
F = ZFLAG(A); }
|
||||
|
||||
#define OR(n) { A |= (n); \
|
||||
F = ZFLAG(A); }
|
||||
|
||||
#define RLCA(r) { (r) = ((r)>>7) | ((r)<<1); \
|
||||
F = (((r)&0x01)<<4); }
|
||||
|
||||
#define RRCA(r) { (r) = ((r)<<7) | ((r)>>1); \
|
||||
F = (((r)&0x80)>>3); }
|
||||
|
||||
#define RLA(r) { \
|
||||
LB(acc) = (((r)&0x80)>>3); \
|
||||
(r) = ((r)<<1) | ((F&FC)>>4); \
|
||||
F = LB(acc); }
|
||||
|
||||
#define RRA(r) { \
|
||||
LB(acc) = (((r)&0x01)<<4); \
|
||||
(r) = ((r)>>1) | ((F&FC)<<3); \
|
||||
F = LB(acc); }
|
||||
|
||||
#define RLC(r) { RLCA(r); F |= ZFLAG(r); }
|
||||
#define RRC(r) { RRCA(r); F |= ZFLAG(r); }
|
||||
#define RL(r) { RLA(r); F |= ZFLAG(r); }
|
||||
#define RR(r) { RRA(r); F |= ZFLAG(r); }
|
||||
|
||||
#define SLA(r) { \
|
||||
LB(acc) = (((r)&0x80)>>3); \
|
||||
(r) <<= 1; \
|
||||
F = ZFLAG((r)) | LB(acc); }
|
||||
|
||||
#define SRA(r) { \
|
||||
LB(acc) = (((r)&0x01)<<4); \
|
||||
(r) = (un8)(((n8)(r))>>1); \
|
||||
F = ZFLAG((r)) | LB(acc); }
|
||||
|
||||
#define SRL(r) { \
|
||||
LB(acc) = (((r)&0x01)<<4); \
|
||||
(r) >>= 1; \
|
||||
F = ZFLAG((r)) | LB(acc); }
|
||||
|
||||
#define CPL(r) { \
|
||||
(r) = ~(r); \
|
||||
F |= (FH|FN); }
|
||||
|
||||
#define SCF { F = (F & (FZ)) | FC; }
|
||||
|
||||
#define CCF { F = (F & (FZ|FC)) ^ FC; }
|
||||
|
||||
#define DAA { \
|
||||
A += (LB(acc) = daa_table[((((int)F)&0x70)<<4) | A]); \
|
||||
F = (F & (FN)) | ZFLAG(A) | daa_carry_table[LB(acc)>>2]; }
|
||||
|
||||
#define SWAP(r) { \
|
||||
(r) = swap_table[(r)]; \
|
||||
F = ZFLAG((r)); }
|
||||
|
||||
#define BIT(n,r) { F = (F & FC) | ZFLAG(((r) & (1 << (n)))) | FH; }
|
||||
#define RES(n,r) { (r) &= ~(1 << (n)); }
|
||||
#define SET(n,r) { (r) |= (1 << (n)); }
|
||||
|
||||
#define CB_REG_CASES(r, n) \
|
||||
case 0x00|(n): RLC(r); break; \
|
||||
case 0x08|(n): RRC(r); break; \
|
||||
case 0x10|(n): RL(r); break; \
|
||||
case 0x18|(n): RR(r); break; \
|
||||
case 0x20|(n): SLA(r); break; \
|
||||
case 0x28|(n): SRA(r); break; \
|
||||
case 0x30|(n): SWAP(r); break; \
|
||||
case 0x38|(n): SRL(r); break; \
|
||||
case 0x40|(n): BIT(0, r); break; \
|
||||
case 0x48|(n): BIT(1, r); break; \
|
||||
case 0x50|(n): BIT(2, r); break; \
|
||||
case 0x58|(n): BIT(3, r); break; \
|
||||
case 0x60|(n): BIT(4, r); break; \
|
||||
case 0x68|(n): BIT(5, r); break; \
|
||||
case 0x70|(n): BIT(6, r); break; \
|
||||
case 0x78|(n): BIT(7, r); break; \
|
||||
case 0x80|(n): RES(0, r); break; \
|
||||
case 0x88|(n): RES(1, r); break; \
|
||||
case 0x90|(n): RES(2, r); break; \
|
||||
case 0x98|(n): RES(3, r); break; \
|
||||
case 0xA0|(n): RES(4, r); break; \
|
||||
case 0xA8|(n): RES(5, r); break; \
|
||||
case 0xB0|(n): RES(6, r); break; \
|
||||
case 0xB8|(n): RES(7, r); break; \
|
||||
case 0xC0|(n): SET(0, r); break; \
|
||||
case 0xC8|(n): SET(1, r); break; \
|
||||
case 0xD0|(n): SET(2, r); break; \
|
||||
case 0xD8|(n): SET(3, r); break; \
|
||||
case 0xE0|(n): SET(4, r); break; \
|
||||
case 0xE8|(n): SET(5, r); break; \
|
||||
case 0xF0|(n): SET(6, r); break; \
|
||||
case 0xF8|(n): SET(7, r); break;
|
||||
|
||||
|
||||
#define ALU_CASES(base, imm, op, label) \
|
||||
case (imm): b = FETCH; goto label; \
|
||||
case (base): b = B; goto label; \
|
||||
case (base)+1: b = C; goto label; \
|
||||
case (base)+2: b = D; goto label; \
|
||||
case (base)+3: b = E; goto label; \
|
||||
case (base)+4: b = H; goto label; \
|
||||
case (base)+5: b = L; goto label; \
|
||||
case (base)+6: b = readb(HL); goto label; \
|
||||
case (base)+7: b = A; \
|
||||
label: op(b); break;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define JR ( PC += 1+(n8)readb(PC) )
|
||||
#define JP ( PC = readw(PC) )
|
||||
|
||||
#define CALL ( PUSH(PC+2), JP )
|
||||
|
||||
#define NOJR ( clen--, PC++ )
|
||||
#define NOJP ( clen--, PC+=2 )
|
||||
#define NOCALL ( clen-=3, PC+=2 )
|
||||
#define NORET ( clen-=3 )
|
||||
|
||||
#define RST(n) { PUSH(PC); PC = (n); }
|
||||
|
||||
#define RET ( POP(PC) )
|
||||
|
||||
#define EI ( IMA = 1 )
|
||||
#define DI ( cpu.halt = IMA = IME = 0 )
|
||||
|
||||
|
||||
|
||||
#define PRE_INT ( DI, PUSH(PC) )
|
||||
#define THROW_INT(n) ( (IF &= ~(1<<(n))), (PC = 0x40+((n)<<3)) )
|
||||
|
||||
|
||||
|
||||
|
||||
void cpu_reset(void)
|
||||
{
|
||||
cpu.speed = 0;
|
||||
cpu.halt = 0;
|
||||
cpu.div = 0;
|
||||
cpu.tim = 0;
|
||||
cpu.lcdc = 40;
|
||||
|
||||
IME = 0;
|
||||
IMA = 0;
|
||||
|
||||
PC = 0x0100;
|
||||
SP = 0xFFFE;
|
||||
AF = 0x01B0;
|
||||
BC = 0x0013;
|
||||
DE = 0x00D8;
|
||||
HL = 0x014D;
|
||||
|
||||
if (hw.cgb) A = 0x11;
|
||||
if (hw.gba) B = 0x01;
|
||||
}
|
||||
|
||||
|
||||
void div_advance(int cnt)
|
||||
{
|
||||
cpu.div += (cnt<<1);
|
||||
if (cpu.div >= 256)
|
||||
{
|
||||
R_DIV += (cpu.div >> 8);
|
||||
cpu.div &= 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
void timer_advance(int cnt)
|
||||
{
|
||||
int unit, tima;
|
||||
|
||||
if (!(R_TAC & 0x04)) return;
|
||||
|
||||
unit = ((-R_TAC) & 3) << 1;
|
||||
cpu.tim += (cnt<<unit);
|
||||
|
||||
if (cpu.tim >= 512)
|
||||
{
|
||||
tima = R_TIMA + (cpu.tim >> 9);
|
||||
cpu.tim &= 0x1ff;
|
||||
if (tima >= 256)
|
||||
{
|
||||
hw_interrupt(IF_TIMER, IF_TIMER);
|
||||
hw_interrupt(0, IF_TIMER);
|
||||
}
|
||||
while (tima >= 256)
|
||||
tima = tima - 256 + R_TMA;
|
||||
R_TIMA = tima;
|
||||
}
|
||||
}
|
||||
|
||||
void lcdc_advance(int cnt)
|
||||
{
|
||||
cpu.lcdc -= cnt;
|
||||
if (cpu.lcdc <= 0) lcdc_trans();
|
||||
}
|
||||
|
||||
void sound_advance(int cnt)
|
||||
{
|
||||
cpu.snd += cnt;
|
||||
}
|
||||
|
||||
void cpu_timers(int cnt)
|
||||
{
|
||||
div_advance(cnt << cpu.speed);
|
||||
timer_advance(cnt << cpu.speed);
|
||||
lcdc_advance(cnt);
|
||||
sound_advance(cnt);
|
||||
}
|
||||
|
||||
int cpu_idle(int max)
|
||||
{
|
||||
int cnt, unit;
|
||||
|
||||
if (!(cpu.halt && IME)) return 0;
|
||||
if (R_IF & R_IE)
|
||||
{
|
||||
cpu.halt = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Make sure we don't miss lcdc status events! */
|
||||
if ((R_IE & (IF_VBLANK | IF_STAT)) && (max > cpu.lcdc))
|
||||
max = cpu.lcdc;
|
||||
|
||||
/* If timer interrupt cannot happen, this is very simple! */
|
||||
if (!((R_IE & IF_TIMER) && (R_TAC & 0x04)))
|
||||
{
|
||||
cpu_timers(max);
|
||||
return max;
|
||||
}
|
||||
|
||||
/* Figure out when the next timer interrupt will happen */
|
||||
unit = ((-R_TAC) & 3) << 1;
|
||||
cnt = (511 - cpu.tim + (1<<unit)) >> unit;
|
||||
cnt += (255 - R_TIMA) << (9 - unit);
|
||||
|
||||
if (max < cnt)
|
||||
cnt = max;
|
||||
|
||||
cpu_timers(cnt);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#ifndef ASM_CPU_EMULATE
|
||||
|
||||
extern int debug_trace;
|
||||
|
||||
int cpu_emulate(int cycles)
|
||||
{
|
||||
int i;
|
||||
byte op, cbop;
|
||||
int clen;
|
||||
static union reg acc;
|
||||
static byte b;
|
||||
static word w;
|
||||
|
||||
i = cycles;
|
||||
next:
|
||||
if ((clen = cpu_idle(i)))
|
||||
{
|
||||
i -= clen;
|
||||
if (i > 0) goto next;
|
||||
return cycles-i;
|
||||
}
|
||||
|
||||
if (IME && (IF & IE))
|
||||
{
|
||||
PRE_INT;
|
||||
switch ((byte)(IF & IE))
|
||||
{
|
||||
case 0x01: case 0x03: case 0x05: case 0x07:
|
||||
case 0x09: case 0x0B: case 0x0D: case 0x0F:
|
||||
case 0x11: case 0x13: case 0x15: case 0x17:
|
||||
case 0x19: case 0x1B: case 0x1D: case 0x1F:
|
||||
THROW_INT(0); break;
|
||||
case 0x02: case 0x06: case 0x0A: case 0x0E:
|
||||
case 0x12: case 0x16: case 0x1A: case 0x1E:
|
||||
THROW_INT(1); break;
|
||||
case 0x04: case 0x0C: case 0x14: case 0x1C:
|
||||
THROW_INT(2); break;
|
||||
case 0x08: case 0x18:
|
||||
THROW_INT(3); break;
|
||||
case 0x10:
|
||||
THROW_INT(4); break;
|
||||
}
|
||||
}
|
||||
IME = IMA;
|
||||
|
||||
// if (debug_trace) debug_disassemble(PC, 1);
|
||||
|
||||
op = FETCH;
|
||||
clen = cycles_table[op];
|
||||
|
||||
switch(op)
|
||||
{
|
||||
case 0x00: /* NOP */
|
||||
case 0x40: /* LD B,B */
|
||||
case 0x49: /* LD C,C */
|
||||
case 0x52: /* LD D,D */
|
||||
case 0x5B: /* LD E,E */
|
||||
case 0x64: /* LD H,H */
|
||||
case 0x6D: /* LD L,L */
|
||||
case 0x7F: /* LD A,A */
|
||||
break;
|
||||
|
||||
case 0x41: /* LD B,C */
|
||||
B = C; break;
|
||||
case 0x42: /* LD B,D */
|
||||
B = D; break;
|
||||
case 0x43: /* LD B,E */
|
||||
B = E; break;
|
||||
case 0x44: /* LD B,H */
|
||||
B = H; break;
|
||||
case 0x45: /* LD B,L */
|
||||
B = L; break;
|
||||
case 0x46: /* LD B,(HL) */
|
||||
B = readb(xHL); break;
|
||||
case 0x47: /* LD B,A */
|
||||
B = A; break;
|
||||
|
||||
case 0x48: /* LD C,B */
|
||||
C = B; break;
|
||||
case 0x4A: /* LD C,D */
|
||||
C = D; break;
|
||||
case 0x4B: /* LD C,E */
|
||||
C = E; break;
|
||||
case 0x4C: /* LD C,H */
|
||||
C = H; break;
|
||||
case 0x4D: /* LD C,L */
|
||||
C = L; break;
|
||||
case 0x4E: /* LD C,(HL) */
|
||||
C = readb(xHL); break;
|
||||
case 0x4F: /* LD C,A */
|
||||
C = A; break;
|
||||
|
||||
case 0x50: /* LD D,B */
|
||||
D = B; break;
|
||||
case 0x51: /* LD D,C */
|
||||
D = C; break;
|
||||
case 0x53: /* LD D,E */
|
||||
D = E; break;
|
||||
case 0x54: /* LD D,H */
|
||||
D = H; break;
|
||||
case 0x55: /* LD D,L */
|
||||
D = L; break;
|
||||
case 0x56: /* LD D,(HL) */
|
||||
D = readb(xHL); break;
|
||||
case 0x57: /* LD D,A */
|
||||
D = A; break;
|
||||
|
||||
case 0x58: /* LD E,B */
|
||||
E = B; break;
|
||||
case 0x59: /* LD E,C */
|
||||
E = C; break;
|
||||
case 0x5A: /* LD E,D */
|
||||
E = D; break;
|
||||
case 0x5C: /* LD E,H */
|
||||
E = H; break;
|
||||
case 0x5D: /* LD E,L */
|
||||
E = L; break;
|
||||
case 0x5E: /* LD E,(HL) */
|
||||
E = readb(xHL); break;
|
||||
case 0x5F: /* LD E,A */
|
||||
E = A; break;
|
||||
|
||||
case 0x60: /* LD H,B */
|
||||
H = B; break;
|
||||
case 0x61: /* LD H,C */
|
||||
H = C; break;
|
||||
case 0x62: /* LD H,D */
|
||||
H = D; break;
|
||||
case 0x63: /* LD H,E */
|
||||
H = E; break;
|
||||
case 0x65: /* LD H,L */
|
||||
H = L; break;
|
||||
case 0x66: /* LD H,(HL) */
|
||||
H = readb(xHL); break;
|
||||
case 0x67: /* LD H,A */
|
||||
H = A; break;
|
||||
|
||||
case 0x68: /* LD L,B */
|
||||
L = B; break;
|
||||
case 0x69: /* LD L,C */
|
||||
L = C; break;
|
||||
case 0x6A: /* LD L,D */
|
||||
L = D; break;
|
||||
case 0x6B: /* LD L,E */
|
||||
L = E; break;
|
||||
case 0x6C: /* LD L,H */
|
||||
L = H; break;
|
||||
case 0x6E: /* LD L,(HL) */
|
||||
L = readb(xHL); break;
|
||||
case 0x6F: /* LD L,A */
|
||||
L = A; break;
|
||||
|
||||
case 0x70: /* LD (HL),B */
|
||||
b = B; goto __LD_HL;
|
||||
case 0x71: /* LD (HL),C */
|
||||
b = C; goto __LD_HL;
|
||||
case 0x72: /* LD (HL),D */
|
||||
b = D; goto __LD_HL;
|
||||
case 0x73: /* LD (HL),E */
|
||||
b = E; goto __LD_HL;
|
||||
case 0x74: /* LD (HL),H */
|
||||
b = H; goto __LD_HL;
|
||||
case 0x75: /* LD (HL),L */
|
||||
b = L; goto __LD_HL;
|
||||
case 0x77: /* LD (HL),A */
|
||||
b = A;
|
||||
__LD_HL:
|
||||
writeb(xHL,b);
|
||||
break;
|
||||
|
||||
case 0x78: /* LD A,B */
|
||||
A = B; break;
|
||||
case 0x79: /* LD A,C */
|
||||
A = C; break;
|
||||
case 0x7A: /* LD A,D */
|
||||
A = D; break;
|
||||
case 0x7B: /* LD A,E */
|
||||
A = E; break;
|
||||
case 0x7C: /* LD A,H */
|
||||
A = H; break;
|
||||
case 0x7D: /* LD A,L */
|
||||
A = L; break;
|
||||
case 0x7E: /* LD A,(HL) */
|
||||
A = readb(xHL); break;
|
||||
|
||||
case 0x01: /* LD BC,imm */
|
||||
BC = readw(xPC); PC += 2; break;
|
||||
case 0x11: /* LD DE,imm */
|
||||
DE = readw(xPC); PC += 2; break;
|
||||
case 0x21: /* LD HL,imm */
|
||||
HL = readw(xPC); PC += 2; break;
|
||||
case 0x31: /* LD SP,imm */
|
||||
SP = readw(xPC); PC += 2; break;
|
||||
|
||||
case 0x02: /* LD (BC),A */
|
||||
writeb(xBC, A); break;
|
||||
case 0x0A: /* LD A,(BC) */
|
||||
A = readb(xBC); break;
|
||||
case 0x12: /* LD (DE),A */
|
||||
writeb(xDE, A); break;
|
||||
case 0x1A: /* LD A,(DE) */
|
||||
A = readb(xDE); break;
|
||||
|
||||
case 0x22: /* LDI (HL),A */
|
||||
writeb(xHL, A); HL++; break;
|
||||
case 0x2A: /* LDI A,(HL) */
|
||||
A = readb(xHL); HL++; break;
|
||||
case 0x32: /* LDD (HL),A */
|
||||
writeb(xHL, A); HL--; break;
|
||||
case 0x3A: /* LDD A,(HL) */
|
||||
A = readb(xHL); HL--; break;
|
||||
|
||||
case 0x06: /* LD B,imm */
|
||||
B = FETCH; break;
|
||||
case 0x0E: /* LD C,imm */
|
||||
C = FETCH; break;
|
||||
case 0x16: /* LD D,imm */
|
||||
D = FETCH; break;
|
||||
case 0x1E: /* LD E,imm */
|
||||
E = FETCH; break;
|
||||
case 0x26: /* LD H,imm */
|
||||
H = FETCH; break;
|
||||
case 0x2E: /* LD L,imm */
|
||||
L = FETCH; break;
|
||||
case 0x36: /* LD (HL),imm */
|
||||
b = FETCH; writeb(xHL, b); break;
|
||||
case 0x3E: /* LD A,imm */
|
||||
A = FETCH; break;
|
||||
|
||||
case 0x08: /* LD (imm),SP */
|
||||
writew(readw(xPC), SP); PC += 2; break;
|
||||
case 0xEA: /* LD (imm),A */
|
||||
writeb(readw(xPC), A); PC += 2; break;
|
||||
|
||||
case 0xE0: /* LDH (imm),A */
|
||||
writehi(FETCH, A); break;
|
||||
case 0xE2: /* LDH (C),A */
|
||||
writehi(C, A); break;
|
||||
case 0xF0: /* LDH A,(imm) */
|
||||
A = readhi(FETCH); break;
|
||||
case 0xF2: /* LDH A,(C) (undocumented) */
|
||||
A = readhi(C); break;
|
||||
|
||||
|
||||
case 0xF8: /* LD HL,SP+imm */
|
||||
b = FETCH; LDHLSP(b); break;
|
||||
case 0xF9: /* LD SP,HL */
|
||||
SP = HL; break;
|
||||
case 0xFA: /* LD A,(imm) */
|
||||
A = readb(readw(xPC)); PC += 2; break;
|
||||
|
||||
ALU_CASES(0x80, 0xC6, ADD, __ADD)
|
||||
ALU_CASES(0x88, 0xCE, ADC, __ADC)
|
||||
ALU_CASES(0x90, 0xD6, SUB, __SUB)
|
||||
ALU_CASES(0x98, 0xDE, SBC, __SBC)
|
||||
ALU_CASES(0xA0, 0xE6, AND, __AND)
|
||||
ALU_CASES(0xA8, 0xEE, XOR, __XOR)
|
||||
ALU_CASES(0xB0, 0xF6, OR, __OR)
|
||||
ALU_CASES(0xB8, 0xFE, CP, __CP)
|
||||
|
||||
case 0x09: /* ADD HL,BC */
|
||||
w = BC; goto __ADDW;
|
||||
case 0x19: /* ADD HL,DE */
|
||||
w = DE; goto __ADDW;
|
||||
case 0x39: /* ADD HL,SP */
|
||||
w = SP; goto __ADDW;
|
||||
case 0x29: /* ADD HL,HL */
|
||||
w = HL;
|
||||
__ADDW:
|
||||
ADDW(w);
|
||||
break;
|
||||
|
||||
case 0x04: /* INC B */
|
||||
INC(B); break;
|
||||
case 0x0C: /* INC C */
|
||||
INC(C); break;
|
||||
case 0x14: /* INC D */
|
||||
INC(D); break;
|
||||
case 0x1C: /* INC E */
|
||||
INC(E); break;
|
||||
case 0x24: /* INC H */
|
||||
INC(H); break;
|
||||
case 0x2C: /* INC L */
|
||||
INC(L); break;
|
||||
case 0x34: /* INC (HL) */
|
||||
b = readb(xHL);
|
||||
INC(b);
|
||||
writeb(xHL, b);
|
||||
break;
|
||||
case 0x3C: /* INC A */
|
||||
INC(A); break;
|
||||
|
||||
case 0x03: /* INC BC */
|
||||
INCW(BC); break;
|
||||
case 0x13: /* INC DE */
|
||||
INCW(DE); break;
|
||||
case 0x23: /* INC HL */
|
||||
INCW(HL); break;
|
||||
case 0x33: /* INC SP */
|
||||
INCW(SP); break;
|
||||
|
||||
case 0x05: /* DEC B */
|
||||
DEC(B); break;
|
||||
case 0x0D: /* DEC C */
|
||||
DEC(C); break;
|
||||
case 0x15: /* DEC D */
|
||||
DEC(D); break;
|
||||
case 0x1D: /* DEC E */
|
||||
DEC(E); break;
|
||||
case 0x25: /* DEC H */
|
||||
DEC(H); break;
|
||||
case 0x2D: /* DEC L */
|
||||
DEC(L); break;
|
||||
case 0x35: /* DEC (HL) */
|
||||
b = readb(xHL);
|
||||
DEC(b);
|
||||
writeb(xHL, b);
|
||||
break;
|
||||
case 0x3D: /* DEC A */
|
||||
DEC(A); break;
|
||||
|
||||
case 0x0B: /* DEC BC */
|
||||
DECW(BC); break;
|
||||
case 0x1B: /* DEC DE */
|
||||
DECW(DE); break;
|
||||
case 0x2B: /* DEC HL */
|
||||
DECW(HL); break;
|
||||
case 0x3B: /* DEC SP */
|
||||
DECW(SP); break;
|
||||
|
||||
case 0x07: /* RLCA */
|
||||
RLCA(A); break;
|
||||
case 0x0F: /* RRCA */
|
||||
RRCA(A); break;
|
||||
case 0x17: /* RLA */
|
||||
RLA(A); break;
|
||||
case 0x1F: /* RRA */
|
||||
RRA(A); break;
|
||||
|
||||
case 0x27: /* DAA */
|
||||
DAA; break;
|
||||
case 0x2F: /* CPL */
|
||||
CPL(A); break;
|
||||
|
||||
case 0x18: /* JR */
|
||||
__JR:
|
||||
JR; break;
|
||||
case 0x20: /* JR NZ */
|
||||
if (!(F&FZ)) goto __JR; NOJR; break;
|
||||
case 0x28: /* JR Z */
|
||||
if (F&FZ) goto __JR; NOJR; break;
|
||||
case 0x30: /* JR NC */
|
||||
if (!(F&FC)) goto __JR; NOJR; break;
|
||||
case 0x38: /* JR C */
|
||||
if (F&FC) goto __JR; NOJR; break;
|
||||
|
||||
case 0xC3: /* JP */
|
||||
__JP:
|
||||
JP; break;
|
||||
case 0xC2: /* JP NZ */
|
||||
if (!(F&FZ)) goto __JP; NOJP; break;
|
||||
case 0xCA: /* JP Z */
|
||||
if (F&FZ) goto __JP; NOJP; break;
|
||||
case 0xD2: /* JP NC */
|
||||
if (!(F&FC)) goto __JP; NOJP; break;
|
||||
case 0xDA: /* JP C */
|
||||
if (F&FC) goto __JP; NOJP; break;
|
||||
case 0xE9: /* JP HL */
|
||||
PC = HL; break;
|
||||
|
||||
case 0xC9: /* RET */
|
||||
__RET:
|
||||
RET; break;
|
||||
case 0xC0: /* RET NZ */
|
||||
if (!(F&FZ)) goto __RET; NORET; break;
|
||||
case 0xC8: /* RET Z */
|
||||
if (F&FZ) goto __RET; NORET; break;
|
||||
case 0xD0: /* RET NC */
|
||||
if (!(F&FC)) goto __RET; NORET; break;
|
||||
case 0xD8: /* RET C */
|
||||
if (F&FC) goto __RET; NORET; break;
|
||||
case 0xD9: /* RETI */
|
||||
IME = IMA = 1; goto __RET;
|
||||
|
||||
case 0xCD: /* CALL */
|
||||
__CALL:
|
||||
CALL; break;
|
||||
case 0xC4: /* CALL NZ */
|
||||
if (!(F&FZ)) goto __CALL; NOCALL; break;
|
||||
case 0xCC: /* CALL Z */
|
||||
if (F&FZ) goto __CALL; NOCALL; break;
|
||||
case 0xD4: /* CALL NC */
|
||||
if (!(F&FC)) goto __CALL; NOCALL; break;
|
||||
case 0xDC: /* CALL C */
|
||||
if (F&FC) goto __CALL; NOCALL; break;
|
||||
|
||||
case 0xC7: /* RST 0 */
|
||||
b = 0x00; goto __RST;
|
||||
case 0xCF: /* RST 8 */
|
||||
b = 0x08; goto __RST;
|
||||
case 0xD7: /* RST 10 */
|
||||
b = 0x10; goto __RST;
|
||||
case 0xDF: /* RST 18 */
|
||||
b = 0x18; goto __RST;
|
||||
case 0xE7: /* RST 20 */
|
||||
b = 0x20; goto __RST;
|
||||
case 0xEF: /* RST 28 */
|
||||
b = 0x28; goto __RST;
|
||||
case 0xF7: /* RST 30 */
|
||||
b = 0x30; goto __RST;
|
||||
case 0xFF: /* RST 38 */
|
||||
b = 0x38;
|
||||
__RST:
|
||||
RST(b); break;
|
||||
|
||||
case 0xC1: /* POP BC */
|
||||
POP(BC); break;
|
||||
case 0xC5: /* PUSH BC */
|
||||
PUSH(BC); break;
|
||||
case 0xD1: /* POP DE */
|
||||
POP(DE); break;
|
||||
case 0xD5: /* PUSH DE */
|
||||
PUSH(DE); break;
|
||||
case 0xE1: /* POP HL */
|
||||
POP(HL); break;
|
||||
case 0xE5: /* PUSH HL */
|
||||
PUSH(HL); break;
|
||||
case 0xF1: /* POP AF */
|
||||
POP(AF); break;
|
||||
case 0xF5: /* PUSH AF */
|
||||
PUSH(AF); break;
|
||||
|
||||
case 0xE8: /* ADD SP,imm */
|
||||
b = FETCH; ADDSP(b); break;
|
||||
|
||||
case 0xF3: /* DI */
|
||||
DI; break;
|
||||
case 0xFB: /* EI */
|
||||
EI; break;
|
||||
|
||||
case 0x37: /* SCF */
|
||||
SCF; break;
|
||||
case 0x3F: /* CCF */
|
||||
CCF; break;
|
||||
|
||||
case 0x10: /* STOP */
|
||||
PC++;
|
||||
if (R_KEY1 & 1)
|
||||
{
|
||||
cpu.speed = cpu.speed ^ 1;
|
||||
R_KEY1 = (R_KEY1 & 0x7E) | (cpu.speed << 7);
|
||||
break;
|
||||
}
|
||||
/* NOTE - we do not implement dmg STOP whatsoever */
|
||||
break;
|
||||
|
||||
case 0x76: /* HALT */
|
||||
cpu.halt = 1;
|
||||
break;
|
||||
|
||||
case 0xCB: /* CB prefix */
|
||||
cbop = FETCH;
|
||||
clen = cb_cycles_table[cbop];
|
||||
switch (cbop)
|
||||
{
|
||||
CB_REG_CASES(B, 0);
|
||||
CB_REG_CASES(C, 1);
|
||||
CB_REG_CASES(D, 2);
|
||||
CB_REG_CASES(E, 3);
|
||||
CB_REG_CASES(H, 4);
|
||||
CB_REG_CASES(L, 5);
|
||||
CB_REG_CASES(A, 7);
|
||||
default:
|
||||
b = readb(xHL);
|
||||
switch(cbop)
|
||||
{
|
||||
CB_REG_CASES(b, 6);
|
||||
}
|
||||
if ((cbop & 0xC0) != 0x40) /* exclude BIT */
|
||||
writeb(xHL, b);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
die(
|
||||
"invalid opcode 0x%02X at address 0x%04X, rombank = %d\n",
|
||||
op, (PC-1) & 0xffff, mbc.rombank);
|
||||
break;
|
||||
}
|
||||
|
||||
clen <<= 1;
|
||||
div_advance(clen);
|
||||
timer_advance(clen);
|
||||
clen >>= cpu.speed;
|
||||
lcdc_advance(clen);
|
||||
sound_advance(clen);
|
||||
|
||||
i -= clen;
|
||||
if (i > 0) goto next;
|
||||
return cycles-i;
|
||||
}
|
||||
|
||||
#endif /* ASM_CPU_EMULATE */
|
||||
|
||||
|
||||
#ifndef ASM_CPU_STEP
|
||||
|
||||
int cpu_step(int max)
|
||||
{
|
||||
int cnt;
|
||||
if ((cnt = cpu_idle(max))) return cnt;
|
||||
return cpu_emulate(1);
|
||||
}
|
||||
|
||||
#endif /* ASM_CPU_STEP */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
41
apps/plugins/rockboy/cpu.h
Normal file
41
apps/plugins/rockboy/cpu.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
|
||||
|
||||
#ifndef __CPU_H__
|
||||
#define __CPU_H__
|
||||
|
||||
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
|
||||
union reg
|
||||
{
|
||||
byte b[2][2];
|
||||
word w[2];
|
||||
un32 d; /* padding for alignment, carry */
|
||||
};
|
||||
|
||||
struct cpu
|
||||
{
|
||||
union reg pc, sp, bc, de, hl, af;
|
||||
int ime, ima;
|
||||
int speed;
|
||||
int halt;
|
||||
int div, tim;
|
||||
int lcdc;
|
||||
int snd;
|
||||
};
|
||||
|
||||
extern struct cpu cpu;
|
||||
|
||||
|
||||
void cpu_reset(void);
|
||||
void div_advance(int cnt);
|
||||
void timer_advance(int cnt);
|
||||
void lcdc_advance(int cnt);
|
||||
void sound_advance(int cnt);
|
||||
void cpu_timers(int cnt);
|
||||
int cpu_emulate(int cycles);
|
||||
|
||||
|
||||
#endif
|
290
apps/plugins/rockboy/cpucore.h
Normal file
290
apps/plugins/rockboy/cpucore.h
Normal file
|
@ -0,0 +1,290 @@
|
|||
|
||||
#include "defs.h"
|
||||
|
||||
|
||||
static const byte cycles_table[256] =
|
||||
{
|
||||
1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1,
|
||||
1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1,
|
||||
3, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1,
|
||||
3, 3, 2, 2, 1, 3, 3, 3, 3, 2, 2, 2, 1, 1, 2, 1,
|
||||
|
||||
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
|
||||
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
|
||||
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
|
||||
2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1,
|
||||
|
||||
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
|
||||
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
|
||||
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
|
||||
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
|
||||
|
||||
5, 3, 4, 4, 6, 4, 2, 4, 5, 4, 4, 1, 6, 6, 2, 4,
|
||||
5, 3, 4, 0, 6, 4, 2, 4, 5, 4, 4, 0, 6, 0, 2, 4,
|
||||
3, 3, 2, 0, 0, 4, 2, 4, 4, 1, 4, 0, 0, 0, 2, 4,
|
||||
3, 3, 2, 1, 0, 4, 2, 4, 3, 2, 4, 1, 0, 0, 2, 4,
|
||||
};
|
||||
|
||||
static const byte cb_cycles_table[256] =
|
||||
{
|
||||
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
|
||||
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
|
||||
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
|
||||
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
|
||||
|
||||
2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,
|
||||
2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,
|
||||
2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,
|
||||
2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,
|
||||
|
||||
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
|
||||
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
|
||||
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
|
||||
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
|
||||
|
||||
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
|
||||
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
|
||||
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
|
||||
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
|
||||
};
|
||||
|
||||
|
||||
|
||||
static const byte zflag_table[256] =
|
||||
{
|
||||
FZ, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const byte incflag_table[256] =
|
||||
{
|
||||
FZ|FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const byte decflag_table[256] =
|
||||
{
|
||||
FZ|FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
|
||||
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH
|
||||
};
|
||||
|
||||
static const byte swap_table[256] =
|
||||
{
|
||||
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
|
||||
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
|
||||
0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
|
||||
0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
|
||||
0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
|
||||
0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
|
||||
0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
|
||||
0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
|
||||
0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
|
||||
0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
|
||||
0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
|
||||
0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
|
||||
0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
|
||||
0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
|
||||
0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
|
||||
0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF,
|
||||
};
|
||||
|
||||
static const byte daa_table[4096] =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
|
||||
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
|
||||
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
|
||||
};
|
||||
|
||||
static const byte daa_carry_table[64] =
|
||||
{
|
||||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||||
00, 00, 00, 00, 00, 00, 00, 00, FC, FC, 00, 00, 00, 00, 00, 00,
|
||||
FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC,
|
||||
FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, 00, FC,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
56
apps/plugins/rockboy/cpuregs.h
Normal file
56
apps/plugins/rockboy/cpuregs.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
|
||||
|
||||
#ifndef __CPUREGS_H__
|
||||
|
||||
#define __CPUREGS_H__
|
||||
|
||||
|
||||
|
||||
#include "defs.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#define LB(r) ((r).b[LO][LO])
|
||||
#define HB(r) ((r).b[LO][HI])
|
||||
#define W(r) ((r).w[LO])
|
||||
#define DW(r) ((r).d)
|
||||
|
||||
#define A HB(cpu.af)
|
||||
#define F LB(cpu.af)
|
||||
#define B HB(cpu.bc)
|
||||
#define C LB(cpu.bc)
|
||||
#define D HB(cpu.de)
|
||||
#define E LB(cpu.de)
|
||||
#define H HB(cpu.hl)
|
||||
#define L LB(cpu.hl)
|
||||
|
||||
#define AF W(cpu.af)
|
||||
#define BC W(cpu.bc)
|
||||
#define DE W(cpu.de)
|
||||
#define HL W(cpu.hl)
|
||||
|
||||
#define PC W(cpu.pc)
|
||||
#define SP W(cpu.sp)
|
||||
|
||||
#define xAF DW(cpu.af)
|
||||
#define xBC DW(cpu.bc)
|
||||
#define xDE DW(cpu.de)
|
||||
#define xHL DW(cpu.hl)
|
||||
|
||||
#define xPC DW(cpu.pc)
|
||||
#define xSP DW(cpu.sp)
|
||||
|
||||
#define IMA cpu.ima
|
||||
#define IME cpu.ime
|
||||
#define IF R_IF
|
||||
#define IE R_IE
|
||||
|
||||
#define FZ 0x80
|
||||
#define FN 0x40
|
||||
#define FH 0x20
|
||||
#define FC 0x10
|
||||
#define FL 0x0F /* low unused portion of flags */
|
||||
|
||||
|
||||
#endif /* __CPUREGS_H__ */
|
||||
|
||||
|
699
apps/plugins/rockboy/debug.c
Normal file
699
apps/plugins/rockboy/debug.c
Normal file
|
@ -0,0 +1,699 @@
|
|||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "rockmacros.h"
|
||||
#include "defs.h"
|
||||
#include "cpu.h"
|
||||
#include "mem.h"
|
||||
#include "fastmem.h"
|
||||
#include "regs.h"
|
||||
#include "rc.h"
|
||||
|
||||
#include "cpuregs.h"
|
||||
|
||||
|
||||
static char *mnemonic_table[256] =
|
||||
{
|
||||
"NOP",
|
||||
"LD BC,%w",
|
||||
"LD (BC),A",
|
||||
"INC BC",
|
||||
"INC B",
|
||||
"DEC B",
|
||||
"LD B,%b",
|
||||
"RLCA",
|
||||
"LD (%w),SP",
|
||||
"ADD HL,BC",
|
||||
"LD A,(BC)",
|
||||
"DEC BC",
|
||||
"INC C",
|
||||
"DEC C",
|
||||
"LD C,%b",
|
||||
"RRCA",
|
||||
"STOP",
|
||||
"LD DE,%w",
|
||||
"LD (DE),A",
|
||||
"INC DE",
|
||||
"INC D",
|
||||
"DEC D",
|
||||
"LD D,%b",
|
||||
"RLA",
|
||||
"JR %o",
|
||||
"ADD HL,DE",
|
||||
"LD A,(DE)",
|
||||
"DEC DE",
|
||||
"INC E",
|
||||
"DEC E",
|
||||
"LD E,%b",
|
||||
"RRA",
|
||||
"JR NZ,%o",
|
||||
"LD HL,%w",
|
||||
"LD (HLI),A",
|
||||
"INC HL",
|
||||
"INC H",
|
||||
"DEC H",
|
||||
"LD H,%b",
|
||||
"DAA",
|
||||
"JR Z,%o",
|
||||
"ADD HL,HL",
|
||||
"LD A,(HLI)",
|
||||
"DEC HL",
|
||||
"INC L",
|
||||
"DEC L",
|
||||
"LD L,%b",
|
||||
"CPL",
|
||||
"JR NC,%o",
|
||||
"LD SP,%w",
|
||||
"LD (HLD),A",
|
||||
"INC SP",
|
||||
"INC (HL)",
|
||||
"DEC (HL)",
|
||||
"LD (HL),%b",
|
||||
"SCF",
|
||||
"JR C,%o",
|
||||
"ADD HL,SP",
|
||||
"LD A,(HLD)",
|
||||
"DEC SP",
|
||||
"INC A",
|
||||
"DEC A",
|
||||
"LD A,%b",
|
||||
"CCF",
|
||||
"LD B,B",
|
||||
"LD B,C",
|
||||
"LD B,D",
|
||||
"LD B,E",
|
||||
"LD B,H",
|
||||
"LD B,L",
|
||||
"LD B,(HL)",
|
||||
"LD B,A",
|
||||
"LD C,B",
|
||||
"LD C,C",
|
||||
"LD C,D",
|
||||
"LD C,E",
|
||||
"LD C,H",
|
||||
"LD C,L",
|
||||
"LD C,(HL)",
|
||||
"LD C,A",
|
||||
"LD D,B",
|
||||
"LD D,C",
|
||||
"LD D,D",
|
||||
"LD D,E",
|
||||
"LD D,H",
|
||||
"LD D,L",
|
||||
"LD D,(HL)",
|
||||
"LD D,A",
|
||||
"LD E,B",
|
||||
"LD E,C",
|
||||
"LD E,D",
|
||||
"LD E,E",
|
||||
"LD E,H",
|
||||
"LD E,L",
|
||||
"LD E,(HL)",
|
||||
"LD E,A",
|
||||
"LD H,B",
|
||||
"LD H,C",
|
||||
"LD H,D",
|
||||
"LD H,E",
|
||||
"LD H,H",
|
||||
"LD H,L",
|
||||
"LD H,(HL)",
|
||||
"LD H,A",
|
||||
"LD L,B",
|
||||
"LD L,C",
|
||||
"LD L,D",
|
||||
"LD L,E",
|
||||
"LD L,H",
|
||||
"LD L,L",
|
||||
"LD L,(HL)",
|
||||
"LD L,A",
|
||||
"LD (HL),B",
|
||||
"LD (HL),C",
|
||||
"LD (HL),D",
|
||||
"LD (HL),E",
|
||||
"LD (HL),H",
|
||||
"LD (HL),L",
|
||||
"HALT",
|
||||
"LD (HL),A",
|
||||
"LD A,B",
|
||||
"LD A,C",
|
||||
"LD A,D",
|
||||
"LD A,E",
|
||||
"LD A,H",
|
||||
"LD A,L",
|
||||
"LD A,(HL)",
|
||||
"LD A,A",
|
||||
"ADD A,B",
|
||||
"ADD A,C",
|
||||
"ADD A,D",
|
||||
"ADD A,E",
|
||||
"ADD A,H",
|
||||
"ADD A,L",
|
||||
"ADD A,(HL)",
|
||||
"ADD A,A",
|
||||
"ADC A,B",
|
||||
"ADC A,C",
|
||||
"ADC A,D",
|
||||
"ADC A,E",
|
||||
"ADC A,H",
|
||||
"ADC A,L",
|
||||
"ADC A,(HL)",
|
||||
"ADC A",
|
||||
"SUB B",
|
||||
"SUB C",
|
||||
"SUB D",
|
||||
"SUB E",
|
||||
"SUB H",
|
||||
"SUB L",
|
||||
"SUB (HL)",
|
||||
"SUB A",
|
||||
"SBC A,B",
|
||||
"SBC A,C",
|
||||
"SBC A,D",
|
||||
"SBC A,E",
|
||||
"SBC A,H",
|
||||
"SBC A,L",
|
||||
"SBC A,(HL)",
|
||||
"SBC A,A",
|
||||
"AND B",
|
||||
"AND C",
|
||||
"AND D",
|
||||
"AND E",
|
||||
"AND H",
|
||||
"AND L",
|
||||
"AND (HL)",
|
||||
"AND A",
|
||||
"XOR B",
|
||||
"XOR C",
|
||||
"XOR D",
|
||||
"XOR E",
|
||||
"XOR H",
|
||||
"XOR L",
|
||||
"XOR (HL)",
|
||||
"XOR A",
|
||||
"OR B",
|
||||
"OR C",
|
||||
"OR D",
|
||||
"OR E",
|
||||
"OR H",
|
||||
"OR L",
|
||||
"OR (HL)",
|
||||
"OR A",
|
||||
"CP B",
|
||||
"CP C",
|
||||
"CP D",
|
||||
"CP E",
|
||||
"CP H",
|
||||
"CP L",
|
||||
"CP (HL)",
|
||||
"CP A",
|
||||
"RET NZ",
|
||||
"POP BC",
|
||||
"JP NZ,%w",
|
||||
"JP %w",
|
||||
"CALL NZ,%w",
|
||||
"PUSH BC",
|
||||
"ADD A,%b",
|
||||
"RST 0h",
|
||||
"RET Z",
|
||||
"RET",
|
||||
"JP Z,%w",
|
||||
NULL,
|
||||
"CALL Z,%w",
|
||||
"CALL %w",
|
||||
"ADC A,%b",
|
||||
"RST 8h",
|
||||
"RET NC",
|
||||
"POP DE",
|
||||
"JP NC,%w",
|
||||
NULL,
|
||||
"CALL NC,%w",
|
||||
"PUSH DE",
|
||||
"SUB %b",
|
||||
"RST 10h",
|
||||
"RET C",
|
||||
"RETI",
|
||||
"JP C,%w",
|
||||
NULL,
|
||||
"CALL C,%w",
|
||||
NULL,
|
||||
"SBC A,%b",
|
||||
"RST 18h",
|
||||
"LD (FF00+%b),A",
|
||||
"POP HL",
|
||||
"LD (FF00+C),A",
|
||||
NULL,
|
||||
NULL,
|
||||
"PUSH HL",
|
||||
"AND %b",
|
||||
"RST 20h",
|
||||
"ADD SP,%o",
|
||||
"JP HL",
|
||||
"LD (%w),A",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
"XOR %b",
|
||||
"RST 28h",
|
||||
"LD A,(FF00+%b)",
|
||||
"POP AF",
|
||||
"LD A,(FF00+C)",
|
||||
"DI",
|
||||
NULL,
|
||||
"PUSH AF",
|
||||
"OR %b",
|
||||
"RST 30h",
|
||||
"LD HL,SP%o",
|
||||
"LD SP,HL",
|
||||
"LD A,(%w)",
|
||||
"EI",
|
||||
NULL,
|
||||
NULL,
|
||||
"CP %b",
|
||||
"RST 38h"
|
||||
};
|
||||
|
||||
static char *cb_mnemonic_table[256] =
|
||||
{
|
||||
"RLC B",
|
||||
"RLC C",
|
||||
"RLC D",
|
||||
"RLC E",
|
||||
"RLC H",
|
||||
"RLC L",
|
||||
"RLC (HL)",
|
||||
"RLC A",
|
||||
"RRC B",
|
||||
"RRC C",
|
||||
"RRC D",
|
||||
"RRC E",
|
||||
"RRC H",
|
||||
"RRC L",
|
||||
"RRC (HL)",
|
||||
"RRC A",
|
||||
"RL B",
|
||||
"RL C",
|
||||
"RL D",
|
||||
"RL E",
|
||||
"RL H",
|
||||
"RL L",
|
||||
"RL (HL)",
|
||||
"RL A",
|
||||
"RR B",
|
||||
"RR C",
|
||||
"RR D",
|
||||
"RR E",
|
||||
"RR H",
|
||||
"RR L",
|
||||
"RR (HL)",
|
||||
"RR A",
|
||||
"SLA B",
|
||||
"SLA C",
|
||||
"SLA D",
|
||||
"SLA E",
|
||||
"SLA H",
|
||||
"SLA L",
|
||||
"SLA (HL)",
|
||||
"SLA A",
|
||||
"SRA B",
|
||||
"SRA C",
|
||||
"SRA D",
|
||||
"SRA E",
|
||||
"SRA H",
|
||||
"SRA L",
|
||||
"SRA (HL)",
|
||||
"SRA A",
|
||||
"SWAP B",
|
||||
"SWAP C",
|
||||
"SWAP D",
|
||||
"SWAP E",
|
||||
"SWAP H",
|
||||
"SWAP L",
|
||||
"SWAP (HL)",
|
||||
"SWAP A",
|
||||
"SRL B",
|
||||
"SRL C",
|
||||
"SRL D",
|
||||
"SRL E",
|
||||
"SRL H",
|
||||
"SRL L",
|
||||
"SRL (HL)",
|
||||
"SRL A",
|
||||
"BIT 0,B",
|
||||
"BIT 0,C",
|
||||
"BIT 0,D",
|
||||
"BIT 0,E",
|
||||
"BIT 0,H",
|
||||
"BIT 0,L",
|
||||
"BIT 0,(HL)",
|
||||
"BIT 0,A",
|
||||
"BIT 1,B",
|
||||
"BIT 1,C",
|
||||
"BIT 1,D",
|
||||
"BIT 1,E",
|
||||
"BIT 1,H",
|
||||
"BIT 1,L",
|
||||
"BIT 1,(HL)",
|
||||
"BIT 1,A",
|
||||
"BIT 2,B",
|
||||
"BIT 2,C",
|
||||
"BIT 2,D",
|
||||
"BIT 2,E",
|
||||
"BIT 2,H",
|
||||
"BIT 2,L",
|
||||
"BIT 2,(HL)",
|
||||
"BIT 2,A",
|
||||
"BIT 3,B",
|
||||
"BIT 3,C",
|
||||
"BIT 3,D",
|
||||
"BIT 3,E",
|
||||
"BIT 3,H",
|
||||
"BIT 3,L",
|
||||
"BIT 3,(HL)",
|
||||
"BIT 3,A",
|
||||
"BIT 4,B",
|
||||
"BIT 4,C",
|
||||
"BIT 4,D",
|
||||
"BIT 4,E",
|
||||
"BIT 4,H",
|
||||
"BIT 4,L",
|
||||
"BIT 4,(HL)",
|
||||
"BIT 4,A",
|
||||
"BIT 5,B",
|
||||
"BIT 5,C",
|
||||
"BIT 5,D",
|
||||
"BIT 5,E",
|
||||
"BIT 5,H",
|
||||
"BIT 5,L",
|
||||
"BIT 5,(HL)",
|
||||
"BIT 5,A",
|
||||
"BIT 6,B",
|
||||
"BIT 6,C",
|
||||
"BIT 6,D",
|
||||
"BIT 6,E",
|
||||
"BIT 6,H",
|
||||
"BIT 6,L",
|
||||
"BIT 6,(HL)",
|
||||
"BIT 6,A",
|
||||
"BIT 7,B",
|
||||
"BIT 7,C",
|
||||
"BIT 7,D",
|
||||
"BIT 7,E",
|
||||
"BIT 7,H",
|
||||
"BIT 7,L",
|
||||
"BIT 7,(HL)",
|
||||
"BIT 7,A",
|
||||
"RES 0,B",
|
||||
"RES 0,C",
|
||||
"RES 0,D",
|
||||
"RES 0,E",
|
||||
"RES 0,H",
|
||||
"RES 0,L",
|
||||
"RES 0,(HL)",
|
||||
"RES 0,A",
|
||||
"RES 1,B",
|
||||
"RES 1,C",
|
||||
"RES 1,D",
|
||||
"RES 1,E",
|
||||
"RES 1,H",
|
||||
"RES 1,L",
|
||||
"RES 1,(HL)",
|
||||
"RES 1,A",
|
||||
"RES 2,B",
|
||||
"RES 2,C",
|
||||
"RES 2,D",
|
||||
"RES 2,E",
|
||||
"RES 2,H",
|
||||
"RES 2,L",
|
||||
"RES 2,(HL)",
|
||||
"RES 2,A",
|
||||
"RES 3,B",
|
||||
"RES 3,C",
|
||||
"RES 3,D",
|
||||
"RES 3,E",
|
||||
"RES 3,H",
|
||||
"RES 3,L",
|
||||
"RES 3,(HL)",
|
||||
"RES 3,A",
|
||||
"RES 4,B",
|
||||
"RES 4,C",
|
||||
"RES 4,D",
|
||||
"RES 4,E",
|
||||
"RES 4,H",
|
||||
"RES 4,L",
|
||||
"RES 4,(HL)",
|
||||
"RES 4,A",
|
||||
"RES 5,B",
|
||||
"RES 5,C",
|
||||
"RES 5,D",
|
||||
"RES 5,E",
|
||||
"RES 5,H",
|
||||
"RES 5,L",
|
||||
"RES 5,(HL)",
|
||||
"RES 5,A",
|
||||
"RES 6,B",
|
||||
"RES 6,C",
|
||||
"RES 6,D",
|
||||
"RES 6,E",
|
||||
"RES 6,H",
|
||||
"RES 6,L",
|
||||
"RES 6,(HL)",
|
||||
"RES 6,A",
|
||||
"RES 7,B",
|
||||
"RES 7,C",
|
||||
"RES 7,D",
|
||||
"RES 7,E",
|
||||
"RES 7,H",
|
||||
"RES 7,L",
|
||||
"RES 7,(HL)",
|
||||
"RES 7,A",
|
||||
"SET 0,B",
|
||||
"SET 0,C",
|
||||
"SET 0,D",
|
||||
"SET 0,E",
|
||||
"SET 0,H",
|
||||
"SET 0,L",
|
||||
"SET 0,(HL)",
|
||||
"SET 0,A",
|
||||
"SET 1,B",
|
||||
"SET 1,C",
|
||||
"SET 1,D",
|
||||
"SET 1,E",
|
||||
"SET 1,H",
|
||||
"SET 1,L",
|
||||
"SET 1,(HL)",
|
||||
"SET 1,A",
|
||||
"SET 2,B",
|
||||
"SET 2,C",
|
||||
"SET 2,D",
|
||||
"SET 2,E",
|
||||
"SET 2,H",
|
||||
"SET 2,L",
|
||||
"SET 2,(HL)",
|
||||
"SET 2,A",
|
||||
"SET 3,B",
|
||||
"SET 3,C",
|
||||
"SET 3,D",
|
||||
"SET 3,E",
|
||||
"SET 3,H",
|
||||
"SET 3,L",
|
||||
"SET 3,(HL)",
|
||||
"SET 3,A",
|
||||
"SET 4,B",
|
||||
"SET 4,C",
|
||||
"SET 4,D",
|
||||
"SET 4,E",
|
||||
"SET 4,H",
|
||||
"SET 4,L",
|
||||
"SET 4,(HL)",
|
||||
"SET 4,A",
|
||||
"SET 5,B",
|
||||
"SET 5,C",
|
||||
"SET 5,D",
|
||||
"SET 5,E",
|
||||
"SET 5,H",
|
||||
"SET 5,L",
|
||||
"SET 5,(HL)",
|
||||
"SET 5,A",
|
||||
"SET 6,B",
|
||||
"SET 6,C",
|
||||
"SET 6,D",
|
||||
"SET 6,E",
|
||||
"SET 6,H",
|
||||
"SET 6,L",
|
||||
"SET 6,(HL)",
|
||||
"SET 6,A",
|
||||
"SET 7,B",
|
||||
"SET 7,C",
|
||||
"SET 7,D",
|
||||
"SET 7,E",
|
||||
"SET 7,H",
|
||||
"SET 7,L",
|
||||
"SET 7,(HL)",
|
||||
"SET 7,A"
|
||||
};
|
||||
|
||||
static byte operand_count[256] =
|
||||
{
|
||||
1, 3, 1, 1, 1, 1, 2, 1, 3, 1, 1, 1, 1, 1, 2, 1,
|
||||
1, 3, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1,
|
||||
2, 3, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1,
|
||||
2, 3, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 3, 3, 3, 1, 2, 1, 1, 1, 3, 2, 3, 3, 2, 1,
|
||||
1, 1, 3, 1, 3, 1, 2, 1, 1, 1, 3, 1, 3, 1, 2, 1,
|
||||
2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 1, 1, 2, 1,
|
||||
2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 1, 1, 2, 1
|
||||
};
|
||||
|
||||
|
||||
/* replace with a real interactive debugger eventually... */
|
||||
|
||||
int debug_trace = 0;
|
||||
|
||||
rcvar_t debug_exports[] =
|
||||
{
|
||||
RCV_BOOL("trace", &debug_trace),
|
||||
RCV_END
|
||||
};
|
||||
|
||||
void debug_disassemble(addr a, int c)
|
||||
{
|
||||
static int i, j, k;
|
||||
static byte code;
|
||||
static byte ops[3];
|
||||
static int opaddr;
|
||||
static char mnemonic[256];
|
||||
static char *pattern;
|
||||
char meow[500],buf[300];
|
||||
// int fd;
|
||||
if(!debug_trace) return;
|
||||
// fd=open("/rockboy.trace",O_WRONLY|O_APPEND);
|
||||
// if(fd<0)
|
||||
// return;
|
||||
|
||||
while (c > 0)
|
||||
{
|
||||
k = 0;
|
||||
opaddr = a;
|
||||
code = ops[k++] = readb(a); a++;
|
||||
if (code != 0xCB)
|
||||
{
|
||||
pattern = mnemonic_table[code];
|
||||
if (!pattern)
|
||||
pattern = "***INVALID***";
|
||||
}
|
||||
else
|
||||
{
|
||||
code = ops[k++] = readb(a); a++;
|
||||
pattern = cb_mnemonic_table[code];
|
||||
}
|
||||
i = j = 0;
|
||||
while (pattern[i])
|
||||
{
|
||||
if (pattern[i] == '%')
|
||||
{
|
||||
switch (pattern[++i])
|
||||
{
|
||||
case 'B':
|
||||
case 'b':
|
||||
ops[k] = readb(a); a++;
|
||||
j += snprintf(mnemonic + j,255-j,
|
||||
"%02Xh", ops[k++]);
|
||||
break;
|
||||
case 'W':
|
||||
case 'w':
|
||||
ops[k] = readb(a); a++;
|
||||
ops[k+1] = readb(a); a++;
|
||||
j += snprintf(mnemonic + j, 255-j,"%04Xh",
|
||||
((ops[k+1] << 8) | ops[k]));
|
||||
k += 2;
|
||||
break;
|
||||
case 'O':
|
||||
case 'o':
|
||||
ops[k] = readb(a); a++;
|
||||
j += snprintf(mnemonic + j, 255-j,"%+d",
|
||||
(n8)(ops[k++]));
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mnemonic[j++] = pattern[i++];
|
||||
}
|
||||
}
|
||||
mnemonic[j] = 0;
|
||||
snprintf(buf,299,"%04X ", opaddr);
|
||||
strcpy(meow,buf);
|
||||
switch (operand_count[ops[0]]) {
|
||||
case 1:
|
||||
snprintf(buf,299,"%02X ", ops[0]);
|
||||
strcat(meow,buf);
|
||||
break;
|
||||
case 2:
|
||||
snprintf(buf,299,"%02X %02X ", ops[0], ops[1]);
|
||||
strcat(meow,buf);
|
||||
break;
|
||||
case 3:
|
||||
snprintf(buf,299,"%02X %02X %02X ", ops[0], ops[1], ops[2]);
|
||||
strcat(meow,buf);
|
||||
break;
|
||||
}
|
||||
snprintf(buf,"%-16.16s", mnemonic);
|
||||
strcat(meow,buf);
|
||||
rb->lcd_putsxy(0,0,meow);
|
||||
rb->lcd_update();
|
||||
/* fprintf(fd,
|
||||
" SP=%04X.%04X BC=%04X.%02X.%02X DE=%04X.%02X "
|
||||
"HL=%04X.%02X A=%02X F=%02X %c%c%c%c%c",
|
||||
SP, readw(SP),
|
||||
BC, readb(BC), readb(0xFF00 | C),
|
||||
DE, readb(DE),
|
||||
HL, readb(HL), A,
|
||||
F, (IME ? 'I' : '-'),
|
||||
((F & 0x80) ? 'Z' : '-'),
|
||||
((F & 0x40) ? 'N' : '-'),
|
||||
((F & 0x20) ? 'H' : '-'),
|
||||
((F & 0x10) ? 'C' : '-')
|
||||
);
|
||||
fprintf(fd,
|
||||
" IE=%02X IF=%02X LCDC=%02X STAT=%02X LY=%02X LYC=%02X",
|
||||
R_IE, R_IF, R_LCDC, R_STAT, R_LY, R_LYC
|
||||
);*/
|
||||
c--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
36
apps/plugins/rockboy/defs.h
Normal file
36
apps/plugins/rockboy/defs.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
|
||||
|
||||
#ifndef __DEFS_H__
|
||||
#define __DEFS_H__
|
||||
|
||||
#include "rockmacros.h"
|
||||
|
||||
#ifdef LITTLE_ENDIAN
|
||||
#define LO 0
|
||||
#define HI 1
|
||||
#else
|
||||
#define LO 1
|
||||
#define HI 0
|
||||
#endif
|
||||
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
typedef unsigned char un8;
|
||||
typedef unsigned short un16;
|
||||
typedef unsigned int un32;
|
||||
|
||||
typedef signed char n8;
|
||||
typedef signed short n16;
|
||||
typedef signed int n32;
|
||||
|
||||
typedef un16 word;
|
||||
typedef word addr;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
117
apps/plugins/rockboy/emu.c
Normal file
117
apps/plugins/rockboy/emu.c
Normal file
|
@ -0,0 +1,117 @@
|
|||
|
||||
|
||||
|
||||
#include "rockmacros.h"
|
||||
#include "defs.h"
|
||||
#include "regs.h"
|
||||
#include "hw.h"
|
||||
#include "cpu.h"
|
||||
#include "mem.h"
|
||||
#include "lcd.h"
|
||||
#include "rc.h"
|
||||
#include "sound.h"
|
||||
#include "rtc.h"
|
||||
|
||||
static int framelen = 16743;
|
||||
static int framecount;
|
||||
|
||||
rcvar_t emu_exports[] =
|
||||
{
|
||||
RCV_INT("framelen", &framelen),
|
||||
RCV_INT("framecount", &framecount),
|
||||
RCV_END
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void emu_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* emu_reset is called to initialize the state of the emulated
|
||||
* system. It should set cpu registers, hardware registers, etc. to
|
||||
* their appropriate values at powerup time.
|
||||
*/
|
||||
|
||||
void emu_reset(void)
|
||||
{
|
||||
hw_reset();
|
||||
lcd_reset();
|
||||
cpu_reset();
|
||||
mbc_reset();
|
||||
sound_reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void emu_step(void)
|
||||
{
|
||||
cpu_emulate(cpu.lcdc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This mess needs to be moved to another module; it's just here to
|
||||
* make things work in the mean time. */
|
||||
|
||||
void emu_run(void)
|
||||
{
|
||||
void *timer = sys_timer();
|
||||
char meow[500];
|
||||
int delay;
|
||||
int framecount=0;
|
||||
|
||||
vid_begin();
|
||||
lcd_begin();
|
||||
while(shut==0)
|
||||
{
|
||||
cpu_emulate(2280);
|
||||
while (R_LY > 0 && R_LY < 144)
|
||||
emu_step();
|
||||
|
||||
vid_end();
|
||||
rtc_tick();
|
||||
sound_mix();
|
||||
if (!pcm_submit())
|
||||
{
|
||||
delay = framelen - sys_elapsed(timer);
|
||||
sys_sleep(delay);
|
||||
sys_elapsed(timer);
|
||||
}
|
||||
doevents();
|
||||
vid_begin();
|
||||
// if (framecount) { if (!--framecount) die("finished\n"); }
|
||||
|
||||
if (!(R_LCDC & 0x80))
|
||||
cpu_emulate(32832);
|
||||
|
||||
while (R_LY > 0) /* wait for next frame */
|
||||
emu_step();
|
||||
framecount++;
|
||||
snprintf(meow,499,"%d",framecount);
|
||||
rb->lcd_putsxy(0,0,meow);
|
||||
rb->lcd_update_rect(0,0,LCD_WIDTH,8);
|
||||
rb->yield();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
2
apps/plugins/rockboy/emu.h
Normal file
2
apps/plugins/rockboy/emu.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
void emu_reset(void);
|
||||
void emu_run(void);
|
61
apps/plugins/rockboy/events.c
Normal file
61
apps/plugins/rockboy/events.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* events.c
|
||||
*
|
||||
* Event queue.
|
||||
*/
|
||||
|
||||
|
||||
#include "rockmacros.h"
|
||||
#include "input.h"
|
||||
|
||||
|
||||
char keystates[MAX_KEYS];
|
||||
int nkeysdown;
|
||||
|
||||
#define MAX_EVENTS 32
|
||||
|
||||
static event_t eventqueue[MAX_EVENTS];
|
||||
static int eventhead, eventpos;
|
||||
|
||||
|
||||
int ev_postevent(event_t *ev)
|
||||
{
|
||||
int nextevent;
|
||||
nextevent = (eventhead+1)%MAX_EVENTS;
|
||||
if (nextevent == eventpos)
|
||||
return 0;
|
||||
eventqueue[eventhead] = *ev;
|
||||
eventhead = nextevent;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ev_getevent(event_t *ev)
|
||||
{
|
||||
if (eventpos == eventhead)
|
||||
{
|
||||
ev->type = EV_NONE;
|
||||
return 0;
|
||||
}
|
||||
*ev = eventqueue[eventpos];
|
||||
eventpos = (eventpos+1)%MAX_EVENTS;
|
||||
if (ev->type == EV_PRESS)
|
||||
{
|
||||
keystates[ev->code] = 1;
|
||||
nkeysdown++;
|
||||
}
|
||||
if (ev->type == EV_RELEASE)
|
||||
{
|
||||
keystates[ev->code] = 0;
|
||||
nkeysdown--;
|
||||
if (nkeysdown < 0) nkeysdown = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
42
apps/plugins/rockboy/exports.c
Normal file
42
apps/plugins/rockboy/exports.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
|
||||
|
||||
#include "rockmacros.h"
|
||||
|
||||
#include "rc.h"
|
||||
|
||||
extern rcvar_t emu_exports[], loader_exports[],
|
||||
lcd_exports[], rtc_exports[], sound_exports[],
|
||||
vid_exports[], joy_exports[], pcm_exports[];
|
||||
|
||||
|
||||
rcvar_t *sources[] =
|
||||
{
|
||||
emu_exports,
|
||||
loader_exports,
|
||||
lcd_exports,
|
||||
rtc_exports,
|
||||
sound_exports,
|
||||
vid_exports,
|
||||
joy_exports,
|
||||
pcm_exports,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
void init_exports(void)
|
||||
{
|
||||
rcvar_t **s = sources;
|
||||
|
||||
while (*s)
|
||||
rc_exportvars(*(s++));
|
||||
}
|
||||
|
||||
|
||||
void show_exports(void)
|
||||
{
|
||||
// TODO
|
||||
/*int i, j;
|
||||
for (i = 0; sources[i]; i++)
|
||||
for (j = 0; sources[i][j].name; j++)
|
||||
printf("%s\n", sources[i][j].name);*/
|
||||
}
|
2
apps/plugins/rockboy/exports.h
Normal file
2
apps/plugins/rockboy/exports.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
void init_exports(void);
|
||||
void show_exports(void);
|
138
apps/plugins/rockboy/fastmem.c
Normal file
138
apps/plugins/rockboy/fastmem.c
Normal file
|
@ -0,0 +1,138 @@
|
|||
|
||||
|
||||
#include "rockmacros.h"
|
||||
#include "fastmem.h"
|
||||
|
||||
|
||||
#define D 0 /* direct */
|
||||
#define C 1 /* direct cgb-only */
|
||||
#define R 2 /* io register */
|
||||
#define S 3 /* sound register */
|
||||
#define W 4 /* wave pattern */
|
||||
|
||||
#define F 0xFF /* fail */
|
||||
|
||||
const byte himask[256];
|
||||
|
||||
const byte hi_rmap[256] =
|
||||
{
|
||||
0, 0, R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S,
|
||||
S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, C, 0, C,
|
||||
0, C, C, C, C, C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, C, C, C, C, 0, 0, 0, 0,
|
||||
C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
const byte hi_wmap[256] =
|
||||
{
|
||||
R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R,
|
||||
S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S,
|
||||
S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S,
|
||||
S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S,
|
||||
R, R, R, R, R, R, R, R, R, R, R, R, 0, R, 0, R,
|
||||
0, C, C, C, C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, R, R, R, R, 0, 0, 0, 0,
|
||||
R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R
|
||||
};
|
||||
|
||||
|
||||
byte readb(int a)
|
||||
{
|
||||
byte *p = mbc.rmap[a>>12];
|
||||
if (p) return p[a];
|
||||
else return mem_read(a);
|
||||
}
|
||||
|
||||
void writeb(int a, byte b)
|
||||
{
|
||||
byte *p = mbc.wmap[a>>12];
|
||||
if (p) p[a] = b;
|
||||
else mem_write(a, b);
|
||||
}
|
||||
|
||||
int readw(int a)
|
||||
{
|
||||
if ((a+1) & 0xfff)
|
||||
{
|
||||
byte *p = mbc.rmap[a>>12];
|
||||
if (p)
|
||||
{
|
||||
#ifdef LITTLE_ENDIAN
|
||||
#ifndef ALLOW_UNALIGNED_IO
|
||||
if (a&1) return p[a] | (p[a+1]<<8);
|
||||
#endif
|
||||
return *(word *)(p+a);
|
||||
#else
|
||||
return p[a] | (p[a+1]<<8);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return mem_read(a) | (mem_read(a+1)<<8);
|
||||
}
|
||||
|
||||
void writew(int a, int w)
|
||||
{
|
||||
if ((a+1) & 0xfff)
|
||||
{
|
||||
byte *p = mbc.wmap[a>>12];
|
||||
if (p)
|
||||
{
|
||||
#ifdef LITTLE_ENDIAN
|
||||
#ifndef ALLOW_UNALIGNED_IO
|
||||
if (a&1)
|
||||
{
|
||||
p[a] = w;
|
||||
p[a+1] = w >> 8;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
*(word *)(p+a) = w;
|
||||
return;
|
||||
#else
|
||||
p[a] = w;
|
||||
p[a+1] = w >> 8;
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
mem_write(a, w);
|
||||
mem_write(a+1, w>>8);
|
||||
}
|
||||
|
||||
byte readhi(int a)
|
||||
{
|
||||
return readb(a | 0xff00);
|
||||
}
|
||||
|
||||
void writehi(int a, byte b)
|
||||
{
|
||||
writeb(a | 0xff00, b);
|
||||
}
|
||||
|
||||
#if 0
|
||||
byte readhi(int a)
|
||||
{
|
||||
byte (*rd)() = hi_read[a];
|
||||
return rd ? rd(a) : (ram.hi[a] | himask[a]);
|
||||
}
|
||||
|
||||
void writehi(int a, byte b)
|
||||
{
|
||||
byte (*wr)() = hi_write[a];
|
||||
if (wr) wr(a, b);
|
||||
else ram.hi[a] = b & ~himask[a];
|
||||
}
|
||||
#endif
|
||||
|
22
apps/plugins/rockboy/fastmem.h
Normal file
22
apps/plugins/rockboy/fastmem.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
#ifndef __FASTMEM_H__
|
||||
#define __FASTMEM_H__
|
||||
|
||||
|
||||
#include "defs.h"
|
||||
#include "mem.h"
|
||||
|
||||
|
||||
byte readb(int a);
|
||||
void writeb(int a, byte b);
|
||||
int readw(int a);
|
||||
void writew(int a, int w);
|
||||
byte readhi(int a);
|
||||
void writehi(int a, byte b);
|
||||
#if 0
|
||||
byte readhi(int a);
|
||||
void writehi(int a, byte b);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
35
apps/plugins/rockboy/fb.h
Normal file
35
apps/plugins/rockboy/fb.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
|
||||
#ifndef __FB_H__
|
||||
#define __FB_H__
|
||||
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
|
||||
|
||||
struct fb
|
||||
{
|
||||
byte *ptr;
|
||||
int w, h;
|
||||
int pelsize;
|
||||
int pitch;
|
||||
int indexed;
|
||||
struct
|
||||
{
|
||||
int l, r;
|
||||
} cc[4];
|
||||
int yuv;
|
||||
int enabled;
|
||||
int dirty;
|
||||
};
|
||||
|
||||
|
||||
extern struct fb fb;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
183
apps/plugins/rockboy/hw.c
Normal file
183
apps/plugins/rockboy/hw.c
Normal file
|
@ -0,0 +1,183 @@
|
|||
|
||||
|
||||
|
||||
#include "rockmacros.h"
|
||||
#include "defs.h"
|
||||
#include "cpu.h"
|
||||
#include "hw.h"
|
||||
#include "regs.h"
|
||||
#include "lcd.h"
|
||||
#include "mem.h"
|
||||
#include "fastmem.h"
|
||||
|
||||
|
||||
struct hw hw;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* hw_interrupt changes the virtual interrupt lines included in the
|
||||
* specified mask to the values the corresponding bits in i take, and
|
||||
* in doing so, raises the appropriate bit of R_IF for any interrupt
|
||||
* lines that transition from low to high.
|
||||
*/
|
||||
|
||||
void hw_interrupt(byte i, byte mask)
|
||||
{
|
||||
byte oldif = R_IF;
|
||||
i &= 0x1F & mask;
|
||||
R_IF |= i & (hw.ilines ^ i);
|
||||
|
||||
/* FIXME - is this correct? not sure the docs understand... */
|
||||
if ((R_IF & (R_IF ^ oldif) & R_IE) && cpu.ime) cpu.halt = 0;
|
||||
/* if ((i & (hw.ilines ^ i) & R_IE) && cpu.ime) cpu.halt = 0; */
|
||||
/* if ((i & R_IE) && cpu.ime) cpu.halt = 0; */
|
||||
|
||||
hw.ilines &= ~mask;
|
||||
hw.ilines |= i;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hw_dma performs plain old memory-to-oam dma, the original dmg
|
||||
* dma. Although on the hardware it takes a good deal of time, the cpu
|
||||
* continues running during this mode of dma, so no special tricks to
|
||||
* stall the cpu are necessary.
|
||||
*/
|
||||
|
||||
void hw_dma(byte b)
|
||||
{
|
||||
int i;
|
||||
addr a;
|
||||
|
||||
a = ((addr)b) << 8;
|
||||
for (i = 0; i < 160; i++, a++)
|
||||
lcd.oam.mem[i] = readb(a);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void hw_hdma_cmd(byte c)
|
||||
{
|
||||
int cnt;
|
||||
addr sa;
|
||||
int da;
|
||||
|
||||
/* Begin or cancel HDMA */
|
||||
if ((hw.hdma|c) & 0x80)
|
||||
{
|
||||
hw.hdma = c;
|
||||
R_HDMA5 = c & 0x7f;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Perform GDMA */
|
||||
sa = ((addr)R_HDMA1 << 8) | (R_HDMA2&0xf0);
|
||||
da = 0x8000 | ((int)(R_HDMA3&0x1f) << 8) | (R_HDMA4&0xf0);
|
||||
cnt = ((int)c)+1;
|
||||
/* FIXME - this should use cpu time! */
|
||||
/*cpu_timers(102 * cnt);*/
|
||||
cnt <<= 4;
|
||||
while (cnt--)
|
||||
writeb(da++, readb(sa++));
|
||||
R_HDMA1 = sa >> 8;
|
||||
R_HDMA2 = sa & 0xF0;
|
||||
R_HDMA3 = 0x1F & (da >> 8);
|
||||
R_HDMA4 = da & 0xF0;
|
||||
R_HDMA5 = 0xFF;
|
||||
}
|
||||
|
||||
|
||||
void hw_hdma(void)
|
||||
{
|
||||
int cnt;
|
||||
addr sa;
|
||||
int da;
|
||||
|
||||
sa = ((addr)R_HDMA1 << 8) | (R_HDMA2&0xf0);
|
||||
da = 0x8000 | ((int)(R_HDMA3&0x1f) << 8) | (R_HDMA4&0xf0);
|
||||
cnt = 16;
|
||||
while (cnt--)
|
||||
writeb(da++, readb(sa++));
|
||||
R_HDMA1 = sa >> 8;
|
||||
R_HDMA2 = sa & 0xF0;
|
||||
R_HDMA3 = 0x1F & (da >> 8);
|
||||
R_HDMA4 = da & 0xF0;
|
||||
R_HDMA5--;
|
||||
hw.hdma--;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pad_refresh updates the P1 register from the pad states, generating
|
||||
* the appropriate interrupts (by quickly raising and lowering the
|
||||
* interrupt line) if a transition has been made.
|
||||
*/
|
||||
|
||||
void pad_refresh()
|
||||
{
|
||||
byte oldp1;
|
||||
oldp1 = R_P1;
|
||||
R_P1 &= 0x30;
|
||||
R_P1 |= 0xc0;
|
||||
if (!(R_P1 & 0x10))
|
||||
R_P1 |= (hw.pad & 0x0F);
|
||||
if (!(R_P1 & 0x20))
|
||||
R_P1 |= (hw.pad >> 4);
|
||||
R_P1 ^= 0x0F;
|
||||
if (oldp1 & ~R_P1 & 0x0F)
|
||||
{
|
||||
hw_interrupt(IF_PAD, IF_PAD);
|
||||
hw_interrupt(0, IF_PAD);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These simple functions just update the state of a button on the
|
||||
* pad.
|
||||
*/
|
||||
|
||||
void pad_press(byte k)
|
||||
{
|
||||
if (hw.pad & k)
|
||||
return;
|
||||
hw.pad |= k;
|
||||
pad_refresh();
|
||||
}
|
||||
|
||||
void pad_release(byte k)
|
||||
{
|
||||
if (!(hw.pad & k))
|
||||
return;
|
||||
hw.pad &= ~k;
|
||||
pad_refresh();
|
||||
}
|
||||
|
||||
void pad_set(byte k, int st)
|
||||
{
|
||||
st ? pad_press(k) : pad_release(k);
|
||||
}
|
||||
|
||||
void hw_reset()
|
||||
{
|
||||
hw.ilines = hw.pad = 0;
|
||||
|
||||
memset(ram.hi, 0, sizeof ram.hi);
|
||||
|
||||
R_P1 = 0xFF;
|
||||
R_LCDC = 0x91;
|
||||
R_BGP = 0xFC;
|
||||
R_OBP0 = 0xFF;
|
||||
R_OBP1 = 0xFF;
|
||||
R_SVBK = 0x01;
|
||||
R_HDMA5 = 0xFF;
|
||||
R_VBK = 0xFE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
47
apps/plugins/rockboy/hw.h
Normal file
47
apps/plugins/rockboy/hw.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
|
||||
|
||||
|
||||
#ifndef __HW_H__
|
||||
#define __HW_H__
|
||||
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
|
||||
#define PAD_RIGHT 0x01
|
||||
#define PAD_LEFT 0x02
|
||||
#define PAD_UP 0x04
|
||||
#define PAD_DOWN 0x08
|
||||
#define PAD_A 0x10
|
||||
#define PAD_B 0x20
|
||||
#define PAD_SELECT 0x40
|
||||
#define PAD_START 0x80
|
||||
|
||||
#define IF_VBLANK 0x01
|
||||
#define IF_STAT 0x02
|
||||
#define IF_TIMER 0x04
|
||||
#define IF_SERIAL 0x08
|
||||
#define IF_PAD 0x10
|
||||
|
||||
struct hw
|
||||
{
|
||||
byte ilines;
|
||||
byte pad;
|
||||
int hdma;
|
||||
int cgb,gba;
|
||||
};
|
||||
|
||||
|
||||
extern struct hw hw;
|
||||
|
||||
void hw_interrupt(byte i, byte mask);
|
||||
void hw_dma(byte b);
|
||||
void hw_hdma_cmd(byte c);
|
||||
void hw_hdma(void);
|
||||
void pad_refresh(void);
|
||||
void pad_press(byte k);
|
||||
void pad_release(byte k);
|
||||
void pad_set(byte k, int st);
|
||||
void hw_reset(void);
|
||||
|
||||
#endif
|
514
apps/plugins/rockboy/inflate.c
Normal file
514
apps/plugins/rockboy/inflate.c
Normal file
|
@ -0,0 +1,514 @@
|
|||
|
||||
/* Slightly modified from its original form so as not to exit the
|
||||
* program on errors. The resulting file remains in the public
|
||||
* domain for all to use. */
|
||||
|
||||
/* --- GZIP file format uncompression routines --- */
|
||||
|
||||
/* The following routines (notably the unzip()) function below
|
||||
* uncompress gzipped data. They are terribly slow at the task, but
|
||||
* it is presumed that they work reasonably well. They don't do any
|
||||
* error checking, but they're probably not too vulnerable to buggy
|
||||
* data either. Another important limitation (but it would be pretty
|
||||
* easy to get around) is that the data must reside in memory, it is
|
||||
* not read as a stream. They have been very little tested. Anyway,
|
||||
* whatever these functions are good for, I put them in the public
|
||||
* domain. -- David Madore <david.madore@ens.fr> 1999/11/21 */
|
||||
|
||||
#include "rockmacros.h"
|
||||
|
||||
static unsigned int
|
||||
peek_bits (const unsigned char *data, long p, int q)
|
||||
/* Read q bits starting from bit p from the data pointed to by
|
||||
* data. Data is in little-endian format. */
|
||||
{
|
||||
unsigned int answer;
|
||||
int cnt; /* Number of bits already placed in answer */
|
||||
char ob, lb; /* Offset and length of bit field within current byte */
|
||||
|
||||
answer = 0;
|
||||
for ( cnt=0 ; cnt<q ; /* cnt updated in body */ )
|
||||
{
|
||||
ob = (p+cnt)%8;
|
||||
lb = 8-ob;
|
||||
if ( cnt+lb > q )
|
||||
lb = q-cnt;
|
||||
answer |= ((unsigned int)((data[(p+cnt)/8]>>ob)&((1U<<lb)-1)))<<cnt;
|
||||
cnt += lb;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
read_bits (const unsigned char *data, long *p, int q)
|
||||
/* Read q bits as per peek_bits(), but also increase p by q. */
|
||||
{
|
||||
unsigned int answer;
|
||||
|
||||
answer = peek_bits (data, *p, q);
|
||||
*p += q;
|
||||
return answer;
|
||||
}
|
||||
|
||||
static void
|
||||
make_code_table (const char size_table[], int table_length,
|
||||
unsigned int code_table[], int maxbits)
|
||||
/* Make a code table from a length table. See rfc1951, section
|
||||
* 3.2.2, for details on what this means. The size_table
|
||||
* contains the length of the Huffman codes for each letter, and
|
||||
* the code_table receives the computed codes themselves.
|
||||
* table_length is the size of the tables (alphabet length) and
|
||||
* maxbits is the maximal allowed code length. */
|
||||
{
|
||||
int i, j;
|
||||
unsigned int code;
|
||||
|
||||
code = 0;
|
||||
for ( i=1 ; i<=maxbits ; i++ )
|
||||
{
|
||||
for ( j=0 ; j<table_length ; j++ )
|
||||
{
|
||||
if ( size_table[j]==i )
|
||||
code_table[j] = code++;
|
||||
}
|
||||
code <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
decode_one (const unsigned char *data, long *p,
|
||||
const char size_table[], int table_length,
|
||||
const unsigned int code_table[], int maxbits)
|
||||
/* Decode one alphabet letter from the data, starting at bit p
|
||||
* (which will be increased by the appropriate amount) using
|
||||
* size_table and code_table to decipher the Huffman encoding. */
|
||||
{
|
||||
unsigned int code;
|
||||
int i, j;
|
||||
|
||||
code = 0;
|
||||
/* Read as many bits as are likely to be necessary - backward, of
|
||||
* course. */
|
||||
for ( i=0 ; i<maxbits ; i++ )
|
||||
code = (code<<1) + peek_bits (data, (*p)+i, 1);
|
||||
/* Now examine each symbol of the table to find one that matches the
|
||||
* first bits of the code read. */
|
||||
for ( j=0 ; j<table_length ; j++ )
|
||||
{
|
||||
if ( size_table[j]
|
||||
&& ( (code>>(maxbits-size_table[j])) == code_table[j] ) )
|
||||
{
|
||||
*p += size_table[j];
|
||||
return j;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* I don't know what these should be. The rfc1951 doesn't seem to say
|
||||
* (it only mentions them in the last paragraph of section 3.2.1). 15
|
||||
* is almost certainly safe, and it is the largest I can put given the
|
||||
* constraints on the size of integers in the C standard. */
|
||||
#define CLEN_MAXBITS 15
|
||||
#define HLIT_MAXBITS 15
|
||||
#define HDIST_MAXBITS 15
|
||||
|
||||
/* The magical table sizes... */
|
||||
#define CLEN_TSIZE 19
|
||||
#define HLIT_TSIZE 288
|
||||
#define HDIST_TSIZE 30
|
||||
|
||||
static int
|
||||
get_tables (const unsigned char *data, long *p,
|
||||
char hlit_size_table[HLIT_TSIZE],
|
||||
unsigned int hlit_code_table[HLIT_TSIZE],
|
||||
char hdist_size_table[HDIST_TSIZE],
|
||||
unsigned int hdist_code_table[HDIST_TSIZE])
|
||||
/* Fill the Huffman tables (first the code lengths table, and
|
||||
* then, using it, the literal/length table and the distance
|
||||
* table). See section 3.2.7 of rfc1951 for details. */
|
||||
{
|
||||
char hlit, hdist, hclen;
|
||||
const int clen_weird_tangle[CLEN_TSIZE]
|
||||
= { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
|
||||
char clen_size_table[CLEN_TSIZE];
|
||||
unsigned int clen_code_table[CLEN_TSIZE];
|
||||
int j;
|
||||
unsigned int b;
|
||||
int remainder; /* See note at end of section 3.2.7 of rfc1951. */
|
||||
char rem_val;
|
||||
|
||||
hlit = read_bits (data, p, 5);
|
||||
hdist = read_bits (data, p, 5);
|
||||
hclen = read_bits (data, p, 4);
|
||||
for ( j=0 ; j<4+hclen ; j++ )
|
||||
clen_size_table[clen_weird_tangle[j]]
|
||||
= read_bits (data, p, 3);
|
||||
for ( ; j<CLEN_TSIZE ; j++ )
|
||||
clen_size_table[clen_weird_tangle[j]] = 0;
|
||||
make_code_table (clen_size_table, CLEN_TSIZE,
|
||||
clen_code_table, CLEN_MAXBITS);
|
||||
remainder = 0;
|
||||
rem_val = 0;
|
||||
for ( j=0 ; j<257+hlit ; j++ )
|
||||
{
|
||||
b = decode_one (data, p, clen_size_table, CLEN_TSIZE,
|
||||
clen_code_table, CLEN_MAXBITS);
|
||||
if ( b<0 ) return -1;
|
||||
if ( b<16 )
|
||||
hlit_size_table[j] = b;
|
||||
else if ( b == 16 )
|
||||
{
|
||||
int k, l;
|
||||
|
||||
k = read_bits (data, p, 2);
|
||||
for ( l=0 ; l<k+3 && j+l<257+hlit ; l++ )
|
||||
hlit_size_table[j+l] = hlit_size_table[j-1];
|
||||
j += l-1;
|
||||
remainder = k+3-l; /* THIS IS SO UGLY! */
|
||||
rem_val = hlit_size_table[j-1];
|
||||
}
|
||||
else if ( b == 17 )
|
||||
{
|
||||
int k, l;
|
||||
|
||||
k = read_bits (data, p, 3);
|
||||
for ( l=0 ; l<k+3 && j+l<257+hlit ; l++ )
|
||||
hlit_size_table[j+l] = 0;
|
||||
j += l-1;
|
||||
remainder = k+3-l;
|
||||
rem_val = 0;
|
||||
}
|
||||
else if ( b == 18 )
|
||||
{
|
||||
int k, l;
|
||||
|
||||
k = read_bits (data, p, 7);
|
||||
for ( l=0 ; l<k+11 && j+l<257+hlit ; l++ )
|
||||
hlit_size_table[j+l] = 0;
|
||||
j += l-1;
|
||||
remainder = k+11-l;
|
||||
rem_val = 0;
|
||||
}
|
||||
}
|
||||
for ( ; j<HLIT_TSIZE ; j++ )
|
||||
hlit_size_table[j] = 0;
|
||||
make_code_table (hlit_size_table, HLIT_TSIZE,
|
||||
hlit_code_table, HLIT_MAXBITS);
|
||||
for ( j=0 ; j<remainder ; j++ )
|
||||
hdist_size_table[j] = rem_val;
|
||||
for ( ; j<1+hdist ; j++ )
|
||||
/* Can you spell: ``copy-paste''? */
|
||||
{
|
||||
b = decode_one (data, p, clen_size_table, CLEN_TSIZE,
|
||||
clen_code_table, CLEN_MAXBITS);
|
||||
if ( b<0 ) return -1;
|
||||
if ( b<16 )
|
||||
hdist_size_table[j] = b;
|
||||
else if ( b == 16 )
|
||||
{
|
||||
int k, l;
|
||||
|
||||
k = read_bits (data, p, 2);
|
||||
for ( l=0 ; l<k+3 && j+l<1+hdist ; l++ )
|
||||
hdist_size_table[j+l] = hdist_size_table[j-1];
|
||||
j += l-1;
|
||||
}
|
||||
else if ( b == 17 )
|
||||
{
|
||||
int k, l;
|
||||
|
||||
k = read_bits (data, p, 3);
|
||||
for ( l=0 ; l<k+3 && j+l<1+hdist ; l++ )
|
||||
hdist_size_table[j+l] = 0;
|
||||
j += l-1;
|
||||
}
|
||||
else if ( b == 18 )
|
||||
{
|
||||
int k, l;
|
||||
|
||||
k = read_bits (data, p, 7);
|
||||
for ( l=0 ; l<k+11 && j+l<1+hdist ; l++ )
|
||||
hdist_size_table[j+l] = 0;
|
||||
j += l-1;
|
||||
}
|
||||
}
|
||||
for ( ; j<HDIST_TSIZE ; j++ )
|
||||
hdist_size_table[j] = 0;
|
||||
make_code_table (hdist_size_table, HDIST_TSIZE,
|
||||
hdist_code_table, HDIST_MAXBITS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The (circular) output buffer. This lets us track
|
||||
* backreferences. */
|
||||
|
||||
/* Minimal buffer size. Also the only useful value. */
|
||||
#define BUFFER_SIZE 32768
|
||||
|
||||
/* Pointer to the character to be added to the buffer */
|
||||
static unsigned int buffer_ptr = 0;
|
||||
|
||||
/* The buffer itself */
|
||||
static unsigned char buffer[BUFFER_SIZE];
|
||||
|
||||
static void
|
||||
pushout (unsigned char ch)
|
||||
/* Store one byte in the output buffer so it may be retrieved if
|
||||
* it is referenced again. */
|
||||
{
|
||||
buffer[buffer_ptr++] = ch;
|
||||
buffer_ptr %= BUFFER_SIZE;
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
pushin (unsigned int dist)
|
||||
/* Retrieve one byte, dist bytes away, from the output buffer. */
|
||||
{
|
||||
return buffer[(buffer_ptr+(BUFFER_SIZE-dist))%BUFFER_SIZE];
|
||||
}
|
||||
|
||||
static int
|
||||
get_data (const unsigned char *data, long *p,
|
||||
const char hlit_size_table[HLIT_TSIZE],
|
||||
const unsigned int hlit_code_table[HLIT_TSIZE],
|
||||
const char hdist_size_table[HDIST_TSIZE],
|
||||
const unsigned int hdist_code_table[HDIST_TSIZE],
|
||||
void (* callback) (unsigned char d))
|
||||
/* Do the actual uncompressing. Call callback on each character
|
||||
* uncompressed. */
|
||||
{
|
||||
unsigned int b;
|
||||
|
||||
while ( 1 ) {
|
||||
b = decode_one (data, p, hlit_size_table, HLIT_TSIZE,
|
||||
hlit_code_table, HLIT_MAXBITS);
|
||||
if ( b<0 ) return -1;
|
||||
if ( b < 256 )
|
||||
/* Literal */
|
||||
{
|
||||
pushout ((unsigned char) b);
|
||||
callback ((unsigned char) b);
|
||||
}
|
||||
else if ( b == 256 )
|
||||
/* End of block */
|
||||
return 0;
|
||||
else if ( b >= 257 )
|
||||
/* Back reference */
|
||||
{
|
||||
unsigned int bb;
|
||||
unsigned int length, dist;
|
||||
unsigned int l;
|
||||
|
||||
switch ( b )
|
||||
{
|
||||
case 257: length = 3; break;
|
||||
case 258: length = 4; break;
|
||||
case 259: length = 5; break;
|
||||
case 260: length = 6; break;
|
||||
case 261: length = 7; break;
|
||||
case 262: length = 8; break;
|
||||
case 263: length = 9; break;
|
||||
case 264: length = 10; break;
|
||||
case 265: length = 11 + read_bits (data, p, 1); break;
|
||||
case 266: length = 13 + read_bits (data, p, 1); break;
|
||||
case 267: length = 15 + read_bits (data, p, 1); break;
|
||||
case 268: length = 17 + read_bits (data, p, 1); break;
|
||||
case 269: length = 19 + read_bits (data, p, 2); break;
|
||||
case 270: length = 23 + read_bits (data, p, 2); break;
|
||||
case 271: length = 27 + read_bits (data, p, 2); break;
|
||||
case 272: length = 31 + read_bits (data, p, 2); break;
|
||||
case 273: length = 35 + read_bits (data, p, 3); break;
|
||||
case 274: length = 43 + read_bits (data, p, 3); break;
|
||||
case 275: length = 51 + read_bits (data, p, 3); break;
|
||||
case 276: length = 59 + read_bits (data, p, 3); break;
|
||||
case 277: length = 67 + read_bits (data, p, 4); break;
|
||||
case 278: length = 83 + read_bits (data, p, 4); break;
|
||||
case 279: length = 99 + read_bits (data, p, 4); break;
|
||||
case 280: length = 115 + read_bits (data, p, 4); break;
|
||||
case 281: length = 131 + read_bits (data, p, 5); break;
|
||||
case 282: length = 163 + read_bits (data, p, 5); break;
|
||||
case 283: length = 195 + read_bits (data, p, 5); break;
|
||||
case 284: length = 227 + read_bits (data, p, 5); break;
|
||||
case 285: length = 258; break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
bb = decode_one (data, p, hdist_size_table, HDIST_TSIZE,
|
||||
hdist_code_table, HDIST_MAXBITS);
|
||||
switch ( bb )
|
||||
{
|
||||
case 0: dist = 1; break;
|
||||
case 1: dist = 2; break;
|
||||
case 2: dist = 3; break;
|
||||
case 3: dist = 4; break;
|
||||
case 4: dist = 5 + read_bits (data, p, 1); break;
|
||||
case 5: dist = 7 + read_bits (data, p, 1); break;
|
||||
case 6: dist = 9 + read_bits (data, p, 2); break;
|
||||
case 7: dist = 13 + read_bits (data, p, 2); break;
|
||||
case 8: dist = 17 + read_bits (data, p, 3); break;
|
||||
case 9: dist = 25 + read_bits (data, p, 3); break;
|
||||
case 10: dist = 33 + read_bits (data, p, 4); break;
|
||||
case 11: dist = 49 + read_bits (data, p, 4); break;
|
||||
case 12: dist = 65 + read_bits (data, p, 5); break;
|
||||
case 13: dist = 97 + read_bits (data, p, 5); break;
|
||||
case 14: dist = 129 + read_bits (data, p, 6); break;
|
||||
case 15: dist = 193 + read_bits (data, p, 6); break;
|
||||
case 16: dist = 257 + read_bits (data, p, 7); break;
|
||||
case 17: dist = 385 + read_bits (data, p, 7); break;
|
||||
case 18: dist = 513 + read_bits (data, p, 8); break;
|
||||
case 19: dist = 769 + read_bits (data, p, 8); break;
|
||||
case 20: dist = 1025 + read_bits (data, p, 9); break;
|
||||
case 21: dist = 1537 + read_bits (data, p, 9); break;
|
||||
case 22: dist = 2049 + read_bits (data, p, 10); break;
|
||||
case 23: dist = 3073 + read_bits (data, p, 10); break;
|
||||
case 24: dist = 4097 + read_bits (data, p, 11); break;
|
||||
case 25: dist = 6145 + read_bits (data, p, 11); break;
|
||||
case 26: dist = 8193 + read_bits (data, p, 12); break;
|
||||
case 27: dist = 12289 + read_bits (data, p, 12); break;
|
||||
case 28: dist = 16385 + read_bits (data, p, 13); break;
|
||||
case 29: dist = 24577 + read_bits (data, p, 13); break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
for ( l=0 ; l<length ; l++ )
|
||||
{
|
||||
unsigned char ch;
|
||||
|
||||
ch = pushin (dist);
|
||||
pushout (ch);
|
||||
callback (ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
inflate (const unsigned char *data, long *p,
|
||||
void (* callback) (unsigned char d))
|
||||
/* Main uncompression function for the deflate method */
|
||||
{
|
||||
char blast, btype;
|
||||
char hlit_size_table[HLIT_TSIZE];
|
||||
unsigned int hlit_code_table[HLIT_TSIZE];
|
||||
char hdist_size_table[HDIST_TSIZE];
|
||||
unsigned int hdist_code_table[HDIST_TSIZE];
|
||||
|
||||
again:
|
||||
blast = read_bits (data, p, 1);
|
||||
btype = read_bits (data, p, 2);
|
||||
if ( btype == 1 || btype == 2 )
|
||||
{
|
||||
if ( btype == 2 )
|
||||
{
|
||||
/* Dynamic Huffman tables */
|
||||
if (get_tables (data, p,
|
||||
hlit_size_table, hlit_code_table,
|
||||
hdist_size_table, hdist_code_table) < 0) return -1;
|
||||
}
|
||||
else
|
||||
/* Fixed Huffman codes */
|
||||
{
|
||||
int j;
|
||||
|
||||
for ( j=0 ; j<144 ; j++ )
|
||||
hlit_size_table[j] = 8;
|
||||
for ( ; j<256 ; j++ )
|
||||
hlit_size_table[j] = 9;
|
||||
for ( ; j<280 ; j++ )
|
||||
hlit_size_table[j] = 7;
|
||||
for ( ; j<HLIT_TSIZE ; j++ )
|
||||
hlit_size_table[j] = 8;
|
||||
make_code_table (hlit_size_table, HLIT_TSIZE,
|
||||
hlit_code_table, HLIT_MAXBITS);
|
||||
for ( j=0 ; j<HDIST_TSIZE ; j++ )
|
||||
hdist_size_table[j] = 5;
|
||||
make_code_table (hdist_size_table, HDIST_TSIZE,
|
||||
hdist_code_table, HDIST_MAXBITS);
|
||||
}
|
||||
if (get_data (data, p,
|
||||
hlit_size_table, hlit_code_table,
|
||||
hdist_size_table, hdist_code_table,
|
||||
callback) < 0) return -1;;
|
||||
}
|
||||
else if ( btype == 0 )
|
||||
/* Non compressed block */
|
||||
{
|
||||
unsigned int len, nlen;
|
||||
unsigned int l;
|
||||
unsigned char b;
|
||||
|
||||
*p = (*p+7)/8; /* Jump to next byte boundary */
|
||||
len = read_bits (data, p, 16);
|
||||
nlen = read_bits (data, p, 16);
|
||||
for ( l=0 ; l<len ; l++ )
|
||||
{
|
||||
b = read_bits (data, p, 8);
|
||||
pushout (b);
|
||||
callback (b);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if ( ! blast )
|
||||
goto again;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
unzip (const unsigned char *data, long *p,
|
||||
void (* callback) (unsigned char d))
|
||||
/* Uncompress gzipped data. data is a pointer to the data, p is
|
||||
* a pointer to a long that is initialized to 0 (unless for some
|
||||
* reason you want to start uncompressing further down the data),
|
||||
* and callback is a function taking an unsigned char and
|
||||
* returning void that will be called successively for every
|
||||
* uncompressed byte. */
|
||||
{
|
||||
unsigned char cm, flg;
|
||||
|
||||
if ( read_bits (data, p, 8) != 0x1f
|
||||
|| read_bits (data, p, 8) != 0x8b )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
cm = read_bits (data, p, 8);
|
||||
if ( cm != 0x8 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
flg = read_bits (data, p, 8);
|
||||
if ( flg & 0xe0 )
|
||||
/* fprintf (stderr, "Warning: unknown bits are set in flags.\n") */ ;
|
||||
read_bits (data, p, 32); /* Ignore modification time */
|
||||
read_bits (data, p, 8); /* Ignore extra flags */
|
||||
read_bits (data, p, 8); /* Ignore OS type */
|
||||
if ( flg & 0x4 )
|
||||
{
|
||||
/* Skip over extra data */
|
||||
unsigned int xlen;
|
||||
|
||||
xlen = read_bits (data, p, 16);
|
||||
*p += ((long)xlen)*8;
|
||||
}
|
||||
if ( flg & 0x8 )
|
||||
{
|
||||
/* Skip over file name */
|
||||
while ( read_bits (data, p, 8) );
|
||||
}
|
||||
if ( flg & 0x10 )
|
||||
{
|
||||
/* Skip over comment */
|
||||
while ( read_bits (data, p, 8) );
|
||||
}
|
||||
if ( flg & 0x2 )
|
||||
/* Ignore CRC16 */
|
||||
read_bits (data, p, 16);
|
||||
return inflate (data, p, callback);
|
||||
/* CRC32 and ISIZE are at the end. We don't even bother to look at
|
||||
* them. */
|
||||
}
|
||||
|
24
apps/plugins/rockboy/input.h
Normal file
24
apps/plugins/rockboy/input.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* input.h
|
||||
*
|
||||
* Definitions for input device stuff - buttons, keys, etc.
|
||||
*/
|
||||
|
||||
|
||||
#define MAX_KEYS 10
|
||||
|
||||
typedef struct event_s
|
||||
{
|
||||
int type;
|
||||
int code;
|
||||
} event_t;
|
||||
|
||||
#define EV_NONE 0
|
||||
#define EV_PRESS 1
|
||||
#define EV_RELEASE 2
|
||||
#define EV_REPEAT 3
|
||||
|
||||
int ev_postevent(event_t *ev);
|
||||
int ev_getevent(event_t *ev);
|
||||
|
||||
|
956
apps/plugins/rockboy/lcd.c
Normal file
956
apps/plugins/rockboy/lcd.c
Normal file
|
@ -0,0 +1,956 @@
|
|||
|
||||
|
||||
#include "config.h"
|
||||
#include "rockmacros.h"
|
||||
#include "defs.h"
|
||||
#include "regs.h"
|
||||
#include "hw.h"
|
||||
#include "mem.h"
|
||||
#include "lcd.h"
|
||||
#include "rc.h"
|
||||
#include "fb.h"
|
||||
#include "palette.h"
|
||||
#ifdef USE_ASM
|
||||
#include "asm.h"
|
||||
#endif
|
||||
|
||||
struct lcd lcd;
|
||||
|
||||
struct scan scan;
|
||||
|
||||
#define BG (scan.bg)
|
||||
#define WND (scan.wnd)
|
||||
#define BUF (scan.buf[scanline_ind])
|
||||
#define PRI (scan.pri)
|
||||
|
||||
#define PAL1 (scan.pal1)
|
||||
#define PAL2 (scan.pal2)
|
||||
#define PAL4 (scan.pal4)
|
||||
|
||||
#define VS (scan.vs) /* vissprites */
|
||||
#define NS (scan.ns)
|
||||
|
||||
#define L (scan.l) /* line */
|
||||
#define X (scan.x) /* screen position */
|
||||
#define Y (scan.y)
|
||||
#define S (scan.s) /* tilemap position */
|
||||
#define T (scan.t)
|
||||
#define U (scan.u) /* position within tile */
|
||||
#define V (scan.v)
|
||||
#define WX (scan.wx)
|
||||
#define WY (scan.wy)
|
||||
#define WT (scan.wt)
|
||||
#define WV (scan.wv)
|
||||
|
||||
byte patpix[4096][8][8];
|
||||
byte patdirty[1024];
|
||||
byte anydirty;
|
||||
|
||||
// static int scale = 1;
|
||||
|
||||
static int rgb332;
|
||||
|
||||
static int sprsort = 1;
|
||||
static int sprdebug;
|
||||
static int scanline_ind=0;
|
||||
|
||||
#define DEF_PAL { 0x98d0e0, 0x68a0b0, 0x60707C, 0x2C3C3C }
|
||||
|
||||
static int dmg_pal[4][4] = { DEF_PAL, DEF_PAL, DEF_PAL, DEF_PAL };
|
||||
|
||||
static int usefilter, filterdmg;
|
||||
static int filter[3][4] = {
|
||||
{ 195, 25, 0, 35 },
|
||||
{ 25, 170, 25, 35 },
|
||||
{ 25, 60, 125, 40 }
|
||||
};
|
||||
|
||||
rcvar_t lcd_exports[] =
|
||||
{
|
||||
RCV_BOOL("rgb332", &rgb332),
|
||||
RCV_VECTOR("dmg_bgp", dmg_pal[0], 4),
|
||||
RCV_VECTOR("dmg_wndp", dmg_pal[1], 4),
|
||||
RCV_VECTOR("dmg_obp0", dmg_pal[2], 4),
|
||||
RCV_VECTOR("dmg_obp1", dmg_pal[3], 4),
|
||||
RCV_BOOL("sprsort", &sprsort),
|
||||
RCV_BOOL("sprdebug", &sprdebug),
|
||||
RCV_BOOL("colorfilter", &usefilter),
|
||||
RCV_BOOL("filterdmg", &filterdmg),
|
||||
RCV_VECTOR("red", filter[0], 4),
|
||||
RCV_VECTOR("green", filter[1], 4),
|
||||
RCV_VECTOR("blue", filter[2], 4),
|
||||
RCV_END
|
||||
};
|
||||
|
||||
static byte *vdest;
|
||||
|
||||
#ifdef ALLOW_UNALIGNED_IO /* long long is ok since this is i386-only anyway? */
|
||||
#define MEMCPY8(d, s) ((*(long long *)(d)) = (*(long long *)(s)))
|
||||
#else
|
||||
#define MEMCPY8(d, s) memcpy((d), (s), 8)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef ASM_UPDATEPATPIX
|
||||
void updatepatpix(void)
|
||||
{
|
||||
int i, j;
|
||||
#if CONFIG_CPU != SH7034 || defined(SIMULATOR)
|
||||
int k, a, c;
|
||||
#endif
|
||||
byte *vram = lcd.vbank[0];
|
||||
|
||||
if (!anydirty) return;
|
||||
for (i = 0; i < 1024; i++)
|
||||
{
|
||||
if (i == 384) i = 512;
|
||||
if (i == 896) break;
|
||||
if (!patdirty[i]) continue;
|
||||
patdirty[i] = 0;
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
#if CONFIG_CPU == SH7034 && !defined(SIMULATOR)
|
||||
asm volatile (
|
||||
"mov.w @%2,r1 \n"
|
||||
"swap.b r1,r2 \n"
|
||||
|
||||
"mov #0,r0 \n"
|
||||
"shlr r1 \n"
|
||||
"rotcl r0 \n"
|
||||
"shlr r2 \n"
|
||||
"rotcl r0 \n"
|
||||
"mov.b r0,@%0 \n"
|
||||
"mov.b r0,@(7,%1) \n"
|
||||
"mov #0,r0 \n"
|
||||
"shlr r1 \n"
|
||||
"rotcl r0 \n"
|
||||
"shlr r2 \n"
|
||||
"rotcl r0 \n"
|
||||
"mov.b r0,@(1,%0) \n"
|
||||
"mov.b r0,@(6,%1) \n"
|
||||
"mov #0,r0 \n"
|
||||
"shlr r1 \n"
|
||||
"rotcl r0 \n"
|
||||
"shlr r2 \n"
|
||||
"rotcl r0 \n"
|
||||
"mov.b r0,@(2,%0) \n"
|
||||
"mov.b r0,@(5,%1) \n"
|
||||
"mov #0,r0 \n"
|
||||
"shlr r1 \n"
|
||||
"rotcl r0 \n"
|
||||
"shlr r2 \n"
|
||||
"rotcl r0 \n"
|
||||
"mov.b r0,@(3,%0) \n"
|
||||
"mov.b r0,@(4,%1) \n"
|
||||
"mov #0,r0 \n"
|
||||
"shlr r1 \n"
|
||||
"rotcl r0 \n"
|
||||
"shlr r2 \n"
|
||||
"rotcl r0 \n"
|
||||
"mov.b r0,@(4,%0) \n"
|
||||
"mov.b r0,@(3,%1) \n"
|
||||
"mov #0,r0 \n"
|
||||
"shlr r1 \n"
|
||||
"rotcl r0 \n"
|
||||
"shlr r2 \n"
|
||||
"rotcl r0 \n"
|
||||
"mov.b r0,@(5,%0) \n"
|
||||
"mov.b r0,@(2,%1) \n"
|
||||
"mov #0,r0 \n"
|
||||
"shlr r1 \n"
|
||||
"rotcl r0 \n"
|
||||
"shlr r2 \n"
|
||||
"rotcl r0 \n"
|
||||
"mov.b r0,@(6,%0) \n"
|
||||
"mov.b r0,@(1,%1) \n"
|
||||
"mov #0,r0 \n"
|
||||
"shlr r1 \n"
|
||||
"rotcl r0 \n"
|
||||
"shlr r2 \n"
|
||||
"rotcl r0 \n"
|
||||
"mov.b r0,@(7,%0) \n"
|
||||
"mov.b r0,@%1 \n"
|
||||
: /* outputs */
|
||||
: /* inputs */
|
||||
/* %0 */ "r"(patpix[i+1024][j]),
|
||||
/* %1 */ "r"(patpix[i][j]),
|
||||
/* %2 */ "r"(&vram[(i<<4)|(j<<1)])
|
||||
: /* clobbers */
|
||||
"r0", "r1", "r2"
|
||||
);
|
||||
#else
|
||||
a = ((i<<4) | (j<<1));
|
||||
for (k = 0; k < 8; k++)
|
||||
{
|
||||
c = vram[a] & (1<<k) ? 1 : 0;
|
||||
c |= vram[a+1] & (1<<k) ? 2 : 0;
|
||||
patpix[i+1024][j][k] = c;
|
||||
}
|
||||
for (k = 0; k < 8; k++)
|
||||
patpix[i][j][k] =
|
||||
patpix[i+1024][j][7-k];
|
||||
#endif
|
||||
}
|
||||
#if CONFIG_CPU == SH7034 && !defined(SIMULATOR)
|
||||
asm volatile (
|
||||
"mov.l @%0,r0 \n"
|
||||
"mov.l @(4,%0),r1 \n"
|
||||
"mov.l r0,@(56,%1) \n"
|
||||
"mov.l r1,@(60,%1) \n"
|
||||
"mov.l @(8,%0),r0 \n"
|
||||
"mov.l @(12,%0),r1 \n"
|
||||
"mov.l r0,@(48,%1) \n"
|
||||
"mov.l r1,@(52,%1) \n"
|
||||
"mov.l @(16,%0),r0 \n"
|
||||
"mov.l @(20,%0),r1 \n"
|
||||
"mov.l r0,@(40,%1) \n"
|
||||
"mov.l r1,@(44,%1) \n"
|
||||
"mov.l @(24,%0),r0 \n"
|
||||
"mov.l @(28,%0),r1 \n"
|
||||
"mov.l r0,@(32,%1) \n"
|
||||
"mov.l r1,@(36,%1) \n"
|
||||
"mov.l @(32,%0),r0 \n"
|
||||
"mov.l @(36,%0),r1 \n"
|
||||
"mov.l r0,@(24,%1) \n"
|
||||
"mov.l r1,@(28,%1) \n"
|
||||
"mov.l @(40,%0),r0 \n"
|
||||
"mov.l @(44,%0),r1 \n"
|
||||
"mov.l r0,@(16,%1) \n"
|
||||
"mov.l r1,@(20,%1) \n"
|
||||
"mov.l @(48,%0),r0 \n"
|
||||
"mov.l @(52,%0),r1 \n"
|
||||
"mov.l r0,@(8,%1) \n"
|
||||
"mov.l r1,@(12,%1) \n"
|
||||
"mov.l @(56,%0),r0 \n"
|
||||
"mov.l @(60,%0),r1 \n"
|
||||
"mov.l r0,@%1 \n"
|
||||
"mov.l r1,@(4,%1) \n"
|
||||
|
||||
"add %2,%0 \n"
|
||||
"add %2,%1 \n"
|
||||
|
||||
"mov.l @%0,r0 \n"
|
||||
"mov.l @(4,%0),r1 \n"
|
||||
"mov.l r0,@(56,%1) \n"
|
||||
"mov.l r1,@(60,%1) \n"
|
||||
"mov.l @(8,%0),r0 \n"
|
||||
"mov.l @(12,%0),r1 \n"
|
||||
"mov.l r0,@(48,%1) \n"
|
||||
"mov.l r1,@(52,%1) \n"
|
||||
"mov.l @(16,%0),r0 \n"
|
||||
"mov.l @(20,%0),r1 \n"
|
||||
"mov.l r0,@(40,%1) \n"
|
||||
"mov.l r1,@(44,%1) \n"
|
||||
"mov.l @(24,%0),r0 \n"
|
||||
"mov.l @(28,%0),r1 \n"
|
||||
"mov.l r0,@(32,%1) \n"
|
||||
"mov.l r1,@(36,%1) \n"
|
||||
"mov.l @(32,%0),r0 \n"
|
||||
"mov.l @(36,%0),r1 \n"
|
||||
"mov.l r0,@(24,%1) \n"
|
||||
"mov.l r1,@(28,%1) \n"
|
||||
"mov.l @(40,%0),r0 \n"
|
||||
"mov.l @(44,%0),r1 \n"
|
||||
"mov.l r0,@(16,%1) \n"
|
||||
"mov.l r1,@(20,%1) \n"
|
||||
"mov.l @(48,%0),r0 \n"
|
||||
"mov.l @(52,%0),r1 \n"
|
||||
"mov.l r0,@(8,%1) \n"
|
||||
"mov.l r1,@(12,%1) \n"
|
||||
"mov.l @(56,%0),r0 \n"
|
||||
"mov.l @(60,%0),r1 \n"
|
||||
"mov.l r0,@%1 \n"
|
||||
"mov.l r1,@(4,%1) \n"
|
||||
: /* outputs */
|
||||
: /* inputs */
|
||||
/* %0 */ "r"(patpix[i][0]),
|
||||
/* %1 */ "r"(patpix[i+2048][0]),
|
||||
/* %2 */ "r"(1024*64)
|
||||
: /* clobbers */
|
||||
"r0", "r1"
|
||||
);
|
||||
#else
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
for (k = 0; k < 8; k++)
|
||||
{
|
||||
patpix[i+2048][j][k] =
|
||||
patpix[i][7-j][k];
|
||||
patpix[i+3072][j][k] =
|
||||
patpix[i+1024][7-j][k];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
anydirty = 0;
|
||||
}
|
||||
#endif /* ASM_UPDATEPATPIX */
|
||||
|
||||
|
||||
|
||||
void tilebuf(void)
|
||||
{
|
||||
int i, cnt;
|
||||
int base;
|
||||
byte *tilemap, *attrmap;
|
||||
int *tilebuf;
|
||||
int *wrap;
|
||||
static int wraptable[64] =
|
||||
{
|
||||
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,-32
|
||||
};
|
||||
|
||||
base = ((R_LCDC&0x08)?0x1C00:0x1800) + (T<<5) + S;
|
||||
tilemap = lcd.vbank[0] + base;
|
||||
attrmap = lcd.vbank[1] + base;
|
||||
tilebuf = BG;
|
||||
wrap = wraptable + S;
|
||||
cnt = ((WX + 7) >> 3) + 1;
|
||||
|
||||
if (hw.cgb) {
|
||||
if (R_LCDC & 0x10)
|
||||
for (i = cnt; i > 0; i--)
|
||||
{
|
||||
*(tilebuf++) = *tilemap
|
||||
| (((int)*attrmap & 0x08) << 6)
|
||||
| (((int)*attrmap & 0x60) << 5);
|
||||
*(tilebuf++) = (((int)*attrmap & 0x07) << 2);
|
||||
attrmap += *wrap + 1;
|
||||
tilemap += *(wrap++) + 1;
|
||||
}
|
||||
else
|
||||
for (i = cnt; i > 0; i--)
|
||||
{
|
||||
*(tilebuf++) = (256 + ((n8)*tilemap))
|
||||
| (((int)*attrmap & 0x08) << 6)
|
||||
| (((int)*attrmap & 0x60) << 5);
|
||||
*(tilebuf++) = (((int)*attrmap & 0x07) << 2);
|
||||
attrmap += *wrap + 1;
|
||||
tilemap += *(wrap++) + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (R_LCDC & 0x10)
|
||||
for (i = cnt; i > 0; i--)
|
||||
{
|
||||
*(tilebuf++) = *(tilemap++);
|
||||
tilemap += *(wrap++);
|
||||
}
|
||||
else
|
||||
for (i = cnt; i > 0; i--)
|
||||
{
|
||||
*(tilebuf++) = (256 + ((n8)*(tilemap++)));
|
||||
tilemap += *(wrap++);
|
||||
}
|
||||
}
|
||||
|
||||
if (WX >= 160) return;
|
||||
|
||||
base = ((R_LCDC&0x40)?0x1C00:0x1800) + (WT<<5);
|
||||
tilemap = lcd.vbank[0] + base;
|
||||
attrmap = lcd.vbank[1] + base;
|
||||
tilebuf = WND;
|
||||
cnt = ((160 - WX) >> 3) + 1;
|
||||
|
||||
if (hw.cgb)
|
||||
{
|
||||
if (R_LCDC & 0x10)
|
||||
for (i = cnt; i > 0; i--)
|
||||
{
|
||||
*(tilebuf++) = *(tilemap++)
|
||||
| (((int)*attrmap & 0x08) << 6)
|
||||
| (((int)*attrmap & 0x60) << 5);
|
||||
*(tilebuf++) = (((int)*(attrmap++)&7) << 2);
|
||||
}
|
||||
else
|
||||
for (i = cnt; i > 0; i--)
|
||||
{
|
||||
*(tilebuf++) = (256 + ((n8)*(tilemap++)))
|
||||
| (((int)*attrmap & 0x08) << 6)
|
||||
| (((int)*attrmap & 0x60) << 5);
|
||||
*(tilebuf++) = (((int)*(attrmap++)&7) << 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
{
|
||||
if (R_LCDC & 0x10)
|
||||
for (i = cnt; i > 0; i--)
|
||||
*(tilebuf++) = *(tilemap++);
|
||||
else
|
||||
for (i = cnt; i > 0; i--)
|
||||
*(tilebuf++) = (256 + ((n8)*(tilemap++)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// V = vertical line
|
||||
// WX = WND start (if 0, no need to do anything) -> WY
|
||||
// U = start...something...thingy... 7 at most
|
||||
void bg_scan(void)
|
||||
{
|
||||
int cnt;
|
||||
byte *src, *dest;
|
||||
int *tile;
|
||||
|
||||
if (WX <= 0) return;
|
||||
cnt = WX;
|
||||
tile = BG;
|
||||
dest = BUF;
|
||||
|
||||
src = patpix[*(tile++)][V] + U;
|
||||
memcpy(dest, src, 8-U);
|
||||
dest += 8-U;
|
||||
cnt -= 8-U;
|
||||
if (cnt <= 0) return;
|
||||
while (cnt >= 8)
|
||||
{
|
||||
src = patpix[*(tile++)][V];
|
||||
MEMCPY8(dest, src);
|
||||
dest += 8;
|
||||
cnt -= 8;
|
||||
}
|
||||
src = patpix[*tile][V];
|
||||
while (cnt--)
|
||||
*(dest++) = *(src++);
|
||||
}
|
||||
|
||||
void wnd_scan(void)
|
||||
{
|
||||
int cnt;
|
||||
byte *src, *dest;
|
||||
int *tile;
|
||||
|
||||
if (WX >= 160) return;
|
||||
cnt = 160 - WX;
|
||||
tile = WND;
|
||||
dest = BUF + WX;
|
||||
|
||||
while (cnt >= 8)
|
||||
{
|
||||
src = patpix[*(tile++)][WV];
|
||||
MEMCPY8(dest, src);
|
||||
dest += 8;
|
||||
cnt -= 8;
|
||||
}
|
||||
src = patpix[*tile][WV];
|
||||
while (cnt--)
|
||||
*(dest++) = *(src++);
|
||||
}
|
||||
|
||||
static void blendcpy(byte *dest, byte *src, byte b, int cnt)
|
||||
{
|
||||
while (cnt--) *(dest++) = *(src++) | b;
|
||||
}
|
||||
|
||||
static int priused(void *attr)
|
||||
{
|
||||
un32 *a = attr;
|
||||
return (int)((a[0]|a[1]|a[2]|a[3]|a[4]|a[5]|a[6]|a[7])&0x80808080);
|
||||
}
|
||||
|
||||
void bg_scan_pri(void)
|
||||
{
|
||||
int cnt, i;
|
||||
byte *src, *dest;
|
||||
|
||||
if (WX <= 0) return;
|
||||
i = S;
|
||||
cnt = WX;
|
||||
dest = PRI;
|
||||
src = lcd.vbank[1] + ((R_LCDC&0x08)?0x1C00:0x1800) + (T<<5);
|
||||
|
||||
if (!priused(src))
|
||||
{
|
||||
memset(dest, 0, cnt);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(dest, src[i++&31]&128, 8-U);
|
||||
dest += 8-U;
|
||||
cnt -= 8-U;
|
||||
if (cnt <= 0) return;
|
||||
while (cnt >= 8)
|
||||
{
|
||||
memset(dest, src[i++&31]&128, 8);
|
||||
dest += 8;
|
||||
cnt -= 8;
|
||||
}
|
||||
memset(dest, src[i&31]&128, cnt);
|
||||
}
|
||||
|
||||
void wnd_scan_pri(void)
|
||||
{
|
||||
int cnt, i;
|
||||
byte *src, *dest;
|
||||
|
||||
if (WX >= 160) return;
|
||||
i = 0;
|
||||
cnt = 160 - WX;
|
||||
dest = PRI + WX;
|
||||
src = lcd.vbank[1] + ((R_LCDC&0x40)?0x1C00:0x1800) + (WT<<5);
|
||||
|
||||
if (!priused(src))
|
||||
{
|
||||
memset(dest, 0, cnt);
|
||||
return;
|
||||
}
|
||||
|
||||
while (cnt >= 8)
|
||||
{
|
||||
memset(dest, src[i++]&128, 8);
|
||||
dest += 8;
|
||||
cnt -= 8;
|
||||
}
|
||||
memset(dest, src[i]&128, cnt);
|
||||
}
|
||||
|
||||
void bg_scan_color(void)
|
||||
{
|
||||
int cnt;
|
||||
byte *src, *dest;
|
||||
int *tile;
|
||||
|
||||
if (WX <= 0) return;
|
||||
cnt = WX;
|
||||
tile = BG;
|
||||
dest = BUF;
|
||||
|
||||
src = patpix[*(tile++)][V] + U;
|
||||
blendcpy(dest, src, *(tile++), 8-U);
|
||||
dest += 8-U;
|
||||
cnt -= 8-U;
|
||||
if (cnt <= 0) return;
|
||||
while (cnt >= 8)
|
||||
{
|
||||
src = patpix[*(tile++)][V];
|
||||
blendcpy(dest, src, *(tile++), 8);
|
||||
dest += 8;
|
||||
cnt -= 8;
|
||||
}
|
||||
src = patpix[*(tile++)][V];
|
||||
blendcpy(dest, src, *(tile++), cnt);
|
||||
}
|
||||
|
||||
// blend in window source WND target BUF
|
||||
// WX = starting X in buf where WND starts
|
||||
// WV = vertical line selected for this scanline
|
||||
// reverse:
|
||||
// WY = starting y in buf where WND starts ?
|
||||
// W?? = horizontal line selected for this scanline
|
||||
void wnd_scan_color(void)
|
||||
{
|
||||
int cnt;
|
||||
byte *src, *dest;
|
||||
int *tile;
|
||||
|
||||
if (WX >= 160) return;
|
||||
cnt = 160 - WX;
|
||||
tile = WND;
|
||||
dest = BUF + WX;
|
||||
|
||||
while (cnt >= 8)
|
||||
{
|
||||
src = patpix[*(tile++)][WV];
|
||||
blendcpy(dest, src, *(tile++), 8);
|
||||
dest += 8;
|
||||
cnt -= 8;
|
||||
}
|
||||
src = patpix[*(tile++)][WV];
|
||||
blendcpy(dest, src, *(tile++), cnt);
|
||||
}
|
||||
|
||||
static void recolor(byte *buf, byte fill, int cnt)
|
||||
{
|
||||
while (cnt--) *(buf++) |= fill;
|
||||
}
|
||||
|
||||
void spr_count(void)
|
||||
{
|
||||
int i;
|
||||
struct obj *o;
|
||||
|
||||
NS = 0;
|
||||
if (!(R_LCDC & 0x02)) return;
|
||||
|
||||
o = lcd.oam.obj;
|
||||
|
||||
for (i = 40; i; i--, o++)
|
||||
{
|
||||
if (L >= o->y || L + 16 < o->y)
|
||||
continue;
|
||||
if (L + 8 >= o->y && !(R_LCDC & 0x04))
|
||||
continue;
|
||||
if (++NS == 10) break;
|
||||
}
|
||||
}
|
||||
|
||||
void spr_enum(void)
|
||||
{
|
||||
int i, j;
|
||||
struct obj *o;
|
||||
struct vissprite ts[10];
|
||||
int v, pat;
|
||||
int l, x;
|
||||
|
||||
NS = 0;
|
||||
if (!(R_LCDC & 0x02)) return;
|
||||
|
||||
o = lcd.oam.obj;
|
||||
|
||||
for (i = 40; i; i--, o++)
|
||||
{
|
||||
if (L >= o->y || L + 16 < o->y)
|
||||
continue;
|
||||
if (L + 8 >= o->y && !(R_LCDC & 0x04))
|
||||
continue;
|
||||
VS[NS].x = (int)o->x - 8;
|
||||
v = L - (int)o->y + 16;
|
||||
if (hw.cgb)
|
||||
{
|
||||
pat = o->pat | (((int)o->flags & 0x60) << 5)
|
||||
| (((int)o->flags & 0x08) << 6);
|
||||
VS[NS].pal = 32 + ((o->flags & 0x07) << 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
pat = o->pat | (((int)o->flags & 0x60) << 5);
|
||||
VS[NS].pal = 32 + ((o->flags & 0x10) >> 2);
|
||||
}
|
||||
VS[NS].pri = (o->flags & 0x80) >> 7;
|
||||
if ((R_LCDC & 0x04))
|
||||
{
|
||||
pat &= ~1;
|
||||
if (v >= 8)
|
||||
{
|
||||
v -= 8;
|
||||
pat++;
|
||||
}
|
||||
if (o->flags & 0x40) pat ^= 1;
|
||||
}
|
||||
VS[NS].buf = patpix[pat][v];
|
||||
if (++NS == 10) break;
|
||||
}
|
||||
if (!sprsort||hw.cgb) return;
|
||||
/* not quite optimal but it finally works! */
|
||||
for (i = 0; i < NS; i++)
|
||||
{
|
||||
l = 0;
|
||||
x = VS[0].x;
|
||||
for (j = 1; j < NS; j++)
|
||||
{
|
||||
if (VS[j].x < x)
|
||||
{
|
||||
l = j;
|
||||
x = VS[j].x;
|
||||
}
|
||||
}
|
||||
ts[i] = VS[l];
|
||||
VS[l].x = 160;
|
||||
}
|
||||
memcpy(VS, ts, sizeof VS);
|
||||
}
|
||||
|
||||
void spr_scan(void)
|
||||
{
|
||||
int i, x;
|
||||
byte pal, b, ns = NS;
|
||||
byte *src, *dest, *bg, *pri;
|
||||
struct vissprite *vs;
|
||||
static byte bgdup[256];
|
||||
|
||||
if (!ns) return;
|
||||
|
||||
memcpy(bgdup, BUF, 256);
|
||||
vs = &VS[ns-1];
|
||||
|
||||
for (; ns; ns--, vs--)
|
||||
{
|
||||
x = vs->x;
|
||||
if (x >= 160) continue;
|
||||
if (x <= -8) continue;
|
||||
if (x < 0)
|
||||
{
|
||||
src = vs->buf - x;
|
||||
dest = BUF;
|
||||
i = 8 + x;
|
||||
}
|
||||
else
|
||||
{
|
||||
src = vs->buf;
|
||||
dest = BUF + x;
|
||||
if (x > 152) i = 160 - x;
|
||||
else i = 8;
|
||||
}
|
||||
pal = vs->pal;
|
||||
if (vs->pri)
|
||||
{
|
||||
bg = bgdup + (dest - BUF);
|
||||
while (i--)
|
||||
{
|
||||
b = src[i];
|
||||
if (b && !(bg[i]&3)) dest[i] = pal|b;
|
||||
}
|
||||
}
|
||||
else if (hw.cgb)
|
||||
{
|
||||
bg = bgdup + (dest - BUF);
|
||||
pri = PRI + (dest - BUF);
|
||||
while (i--)
|
||||
{
|
||||
b = src[i];
|
||||
if (b && (!pri[i] || !(bg[i]&3)))
|
||||
dest[i] = pal|b;
|
||||
}
|
||||
}
|
||||
else while (i--) if (src[i]) dest[i] = pal|src[i];
|
||||
/* else while (i--) if (src[i]) dest[i] = 31 + ns; */
|
||||
}
|
||||
// if (sprdebug) for (i = 0; i < NS; i++) BUF[i<<1] = 36;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void lcd_begin(void)
|
||||
{
|
||||
/* if (fb.indexed)
|
||||
{
|
||||
if (rgb332) pal_set332();
|
||||
else pal_expire();
|
||||
}
|
||||
while (scale * 160 > fb.w || scale * 144 > fb.h) scale--; */
|
||||
vdest = fb.ptr + ((fb.w*fb.pelsize)>>1)
|
||||
- (80*fb.pelsize)
|
||||
+ ((fb.h>>1) - 72) * fb.pitch;
|
||||
WY = R_WY;
|
||||
}
|
||||
|
||||
void lcd_refreshline(void)
|
||||
{
|
||||
if (!fb.enabled) return;
|
||||
|
||||
if (!(R_LCDC & 0x80))
|
||||
return; /* should not happen... */
|
||||
|
||||
#if LCD_HEIGHT == 64
|
||||
if (R_LY >= 128 || R_LY & 1) /* calculate only even lines */
|
||||
#else
|
||||
if (R_LY >= 128)
|
||||
#endif
|
||||
return;
|
||||
|
||||
updatepatpix();
|
||||
|
||||
L = R_LY;
|
||||
#if LCD_HEIGHT == 64
|
||||
scanline_ind = (L/2) % 8;
|
||||
#else
|
||||
scanline_ind = L % 8;
|
||||
#endif
|
||||
X = R_SCX;
|
||||
Y = (R_SCY + L) & 0xff;
|
||||
S = X >> 3;
|
||||
T = Y >> 3;
|
||||
U = X & 7;
|
||||
V = Y & 7;
|
||||
|
||||
WX = R_WX - 7;
|
||||
if (WY>L || WY<0 || WY>143 || WX<-7 || WX>159 || !(R_LCDC&0x20))
|
||||
WX = 160;
|
||||
WT = (L - WY) >> 3;
|
||||
WV = (L - WY) & 7;
|
||||
|
||||
spr_enum();
|
||||
|
||||
tilebuf();
|
||||
if (hw.cgb)
|
||||
{
|
||||
bg_scan_color();
|
||||
wnd_scan_color();
|
||||
if (NS)
|
||||
{
|
||||
bg_scan_pri();
|
||||
wnd_scan_pri();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
bg_scan();
|
||||
wnd_scan();
|
||||
recolor(BUF+WX, 0x04, 160-WX);
|
||||
}
|
||||
spr_scan();
|
||||
/*
|
||||
if (fb.dirty) memset(fb.ptr, 0, fb.pitch * fb.h);
|
||||
fb.dirty = 0;
|
||||
if (density > scale) density = scale;
|
||||
if (scale == 1) density = 1;
|
||||
dest = vdest;
|
||||
*/
|
||||
if (scanline_ind == 7)
|
||||
vid_update(L);
|
||||
// vdest += fb.pitch * scale;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
static void updatepalette(int i)
|
||||
{
|
||||
int c, r, g, b, y, u, v, rr, gg;
|
||||
|
||||
c = (lcd.pal[i<<1] | ((int)lcd.pal[(i<<1)|1] << 8)) & 0x7FFF;
|
||||
r = (c & 0x001F) << 3;
|
||||
g = (c & 0x03E0) >> 2;
|
||||
b = (c & 0x7C00) >> 7;
|
||||
r |= (r >> 5);
|
||||
g |= (g >> 5);
|
||||
b |= (b >> 5);
|
||||
|
||||
if (usefilter && (filterdmg||hw.cgb))
|
||||
{
|
||||
rr = ((r * filter[0][0] + g * filter[0][1] + b * filter[0][2]) >> 8) + filter[0][3];
|
||||
gg = ((r * filter[1][0] + g * filter[1][1] + b * filter[1][2]) >> 8) + filter[1][3];
|
||||
b = ((r * filter[2][0] + g * filter[2][1] + b * filter[2][2]) >> 8) + filter[2][3];
|
||||
r = rr;
|
||||
g = gg;
|
||||
}
|
||||
|
||||
if (fb.yuv)
|
||||
{
|
||||
y = (((r * 263) + (g * 516) + (b * 100)) >> 10) + 16;
|
||||
u = (((r * 450) - (g * 377) - (b * 73)) >> 10) + 128;
|
||||
v = (((r * -152) - (g * 298) + (b * 450)) >> 10) + 128;
|
||||
if (y < 0) y = 0; if (y > 255) y = 255;
|
||||
if (u < 0) u = 0; if (u > 255) u = 255;
|
||||
if (v < 0) v = 0; if (v > 255) v = 255;
|
||||
PAL4[i] = (y<<fb.cc[0].l) | (y<<fb.cc[3].l)
|
||||
| (u<<fb.cc[1].l) | (v<<fb.cc[2].l);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fb.indexed)
|
||||
{
|
||||
pal_release(PAL1[i]);
|
||||
c = pal_getcolor(c, r, g, b);
|
||||
PAL1[i] = c;
|
||||
PAL2[i] = (c<<8) | c;
|
||||
PAL4[i] = (c<<24) | (c<<16) | (c<<8) | c;
|
||||
return;
|
||||
}
|
||||
|
||||
r = (r >> fb.cc[0].r) << fb.cc[0].l;
|
||||
g = (g >> fb.cc[1].r) << fb.cc[1].l;
|
||||
b = (b >> fb.cc[2].r) << fb.cc[2].l;
|
||||
c = r|g|b;
|
||||
|
||||
switch (fb.pelsize)
|
||||
{
|
||||
case 1:
|
||||
PAL1[i] = c;
|
||||
PAL2[i] = (c<<8) | c;
|
||||
PAL4[i] = (c<<24) | (c<<16) | (c<<8) | c;
|
||||
break;
|
||||
case 2:
|
||||
PAL2[i] = c;
|
||||
PAL4[i] = (c<<16) | c;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
PAL4[i] = c;
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
void pal_write(int i, byte b)
|
||||
{
|
||||
if (lcd.pal[i] == b) return;
|
||||
lcd.pal[i] = b;
|
||||
// updatepalette(i>>1);
|
||||
}
|
||||
|
||||
void pal_write_dmg(int i, int mapnum, byte d)
|
||||
{
|
||||
int j;
|
||||
int *cmap = dmg_pal[mapnum];
|
||||
int c, r, g, b;
|
||||
|
||||
if (hw.cgb) return;
|
||||
|
||||
/* if (mapnum >= 2) d = 0xe4; */
|
||||
for (j = 0; j < 8; j += 2)
|
||||
{
|
||||
c = cmap[(d >> j) & 3];
|
||||
r = (c & 0xf8) >> 3;
|
||||
g = (c & 0xf800) >> 6;
|
||||
b = (c & 0xf80000) >> 9;
|
||||
c = r|g|b;
|
||||
/* FIXME - handle directly without faking cgb */
|
||||
pal_write(i+j, c & 0xff);
|
||||
pal_write(i+j+1, c >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
void vram_write(int a, byte b)
|
||||
{
|
||||
lcd.vbank[R_VBK&1][a] = b;
|
||||
if (a >= 0x1800) return;
|
||||
patdirty[((R_VBK&1)<<9)+(a>>4)] = 1;
|
||||
anydirty = 1;
|
||||
}
|
||||
|
||||
void vram_dirty(void)
|
||||
{
|
||||
anydirty = 1;
|
||||
memset(patdirty, 1, sizeof patdirty);
|
||||
}
|
||||
|
||||
void pal_dirty(void)
|
||||
{
|
||||
// int i;
|
||||
if (!hw.cgb)
|
||||
{
|
||||
|
||||
pal_write_dmg(0, 0, R_BGP);
|
||||
pal_write_dmg(8, 1, R_BGP);
|
||||
pal_write_dmg(64, 2, R_OBP0);
|
||||
pal_write_dmg(72, 3, R_OBP1);
|
||||
}
|
||||
// for (i = 0; i < 64; i++)
|
||||
// updatepalette(i);
|
||||
}
|
||||
|
||||
void lcd_reset(void)
|
||||
{
|
||||
memset(&lcd, 0, sizeof lcd);
|
||||
lcd_begin();
|
||||
vram_dirty();
|
||||
pal_dirty();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
74
apps/plugins/rockboy/lcd.h
Normal file
74
apps/plugins/rockboy/lcd.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
|
||||
|
||||
#ifndef __LCD_H__
|
||||
#define __LCD_H__
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
struct vissprite
|
||||
{
|
||||
byte *buf;
|
||||
int x;
|
||||
byte pal, pri, pad[6];
|
||||
};
|
||||
|
||||
struct scan
|
||||
{
|
||||
int bg[64];
|
||||
int wnd[64];
|
||||
byte buf[8][256];
|
||||
byte pal1[128];
|
||||
un16 pal2[64];
|
||||
un32 pal4[64];
|
||||
byte pri[256];
|
||||
struct vissprite vs[16];
|
||||
int ns, l, x, y, s, t, u, v, wx, wy, wt, wv;
|
||||
};
|
||||
|
||||
struct obj
|
||||
{
|
||||
byte y;
|
||||
byte x;
|
||||
byte pat;
|
||||
byte flags;
|
||||
};
|
||||
|
||||
struct lcd
|
||||
{
|
||||
byte vbank[2][8192];
|
||||
union
|
||||
{
|
||||
byte mem[256];
|
||||
struct obj obj[40];
|
||||
} oam;
|
||||
byte pal[128];
|
||||
};
|
||||
|
||||
extern struct lcd lcd;
|
||||
extern struct scan scan;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void updatepatpix(void);
|
||||
void tilebuf(void);
|
||||
void bg_scan(void);
|
||||
void wnd_scan(void);
|
||||
void bg_scan_pri(void);
|
||||
void wnd_scan_pri(void);
|
||||
void spr_count(void);
|
||||
void spr_enum(void);
|
||||
void spr_scan(void);
|
||||
void lcd_begin(void);
|
||||
void lcd_refreshline(void);
|
||||
void pal_write(int i, byte b);
|
||||
void pal_write_dmg(int i, int mapnum, byte d);
|
||||
void vram_write(int a, byte b);
|
||||
void vram_dirty(void);
|
||||
void pal_dirty(void);
|
||||
void lcd_reset(void);
|
180
apps/plugins/rockboy/lcdc.c
Normal file
180
apps/plugins/rockboy/lcdc.c
Normal file
|
@ -0,0 +1,180 @@
|
|||
|
||||
|
||||
#include "rockmacros.h"
|
||||
|
||||
#include "defs.h"
|
||||
#include "hw.h"
|
||||
#include "cpu.h"
|
||||
#include "regs.h"
|
||||
#include "lcd.h"
|
||||
|
||||
|
||||
#define C (cpu.lcdc)
|
||||
|
||||
|
||||
/*
|
||||
* stat_trigger updates the STAT interrupt line to reflect whether any
|
||||
* of the conditions set to be tested (by bits 3-6 of R_STAT) are met.
|
||||
* This function should be called whenever any of the following occur:
|
||||
* 1) LY or LYC changes.
|
||||
* 2) A state transition affects the low 2 bits of R_STAT (see below).
|
||||
* 3) The program writes to the upper bits of R_STAT.
|
||||
* stat_trigger also updates bit 2 of R_STAT to reflect whether LY=LYC.
|
||||
*/
|
||||
|
||||
void stat_trigger(void)
|
||||
{
|
||||
static const int condbits[4] = { 0x08, 0x30, 0x20, 0x00 };
|
||||
int flag = 0;
|
||||
|
||||
if ((R_LY < 0x91) && (R_LY == R_LYC))
|
||||
{
|
||||
R_STAT |= 0x04;
|
||||
if (R_STAT & 0x40) flag = IF_STAT;
|
||||
}
|
||||
else R_STAT &= ~0x04;
|
||||
|
||||
if (R_STAT & condbits[R_STAT&3]) flag = IF_STAT;
|
||||
|
||||
if (!(R_LCDC & 0x80)) flag = 0;
|
||||
|
||||
hw_interrupt(flag, IF_STAT);
|
||||
}
|
||||
|
||||
void stat_write(byte b)
|
||||
{
|
||||
R_STAT = (R_STAT & 0x07) | (b & 0x78);
|
||||
if (!hw.cgb &&!(R_STAT & 2)) /* DMG STAT write bug => interrupt */
|
||||
hw_interrupt(IF_STAT, IF_STAT);
|
||||
stat_trigger();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* stat_change is called when a transition results in a change to the
|
||||
* LCD STAT condition (the low 2 bits of R_STAT). It raises or lowers
|
||||
* the VBLANK interrupt line appropriately and calls stat_trigger to
|
||||
* update the STAT interrupt line.
|
||||
*/
|
||||
|
||||
static void stat_change(int stat)
|
||||
{
|
||||
stat &= 3;
|
||||
R_STAT = (R_STAT & 0x7C) | stat;
|
||||
|
||||
if (stat != 1) hw_interrupt(0, IF_VBLANK);
|
||||
/* hw_interrupt((stat == 1) ? IF_VBLANK : 0, IF_VBLANK); */
|
||||
stat_trigger();
|
||||
}
|
||||
|
||||
|
||||
void lcdc_change(byte b)
|
||||
{
|
||||
byte old = R_LCDC;
|
||||
R_LCDC = b;
|
||||
if ((R_LCDC ^ old) & 0x80) /* lcd on/off change */
|
||||
{
|
||||
R_LY = 0;
|
||||
stat_change(2);
|
||||
C = 40;
|
||||
lcd_begin();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void lcdc_trans(void)
|
||||
{
|
||||
if (!(R_LCDC & 0x80))
|
||||
{
|
||||
while (C <= 0)
|
||||
{
|
||||
switch ((byte)(R_STAT & 3))
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
stat_change(2);
|
||||
C += 40;
|
||||
break;
|
||||
case 2:
|
||||
stat_change(3);
|
||||
C += 86;
|
||||
break;
|
||||
case 3:
|
||||
stat_change(0);
|
||||
if (hw.hdma & 0x80)
|
||||
hw_hdma();
|
||||
else
|
||||
C += 102;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (C <= 0)
|
||||
{
|
||||
switch ((byte)(R_STAT & 3))
|
||||
{
|
||||
case 1:
|
||||
if (!(hw.ilines & IF_VBLANK))
|
||||
{
|
||||
C += 218;
|
||||
hw_interrupt(IF_VBLANK, IF_VBLANK);
|
||||
break;
|
||||
}
|
||||
if (R_LY == 0)
|
||||
{
|
||||
lcd_begin();
|
||||
stat_change(2);
|
||||
C += 40;
|
||||
break;
|
||||
}
|
||||
else if (R_LY < 152)
|
||||
C += 228;
|
||||
else if (R_LY == 152)
|
||||
C += 28;
|
||||
else
|
||||
{
|
||||
R_LY = -1;
|
||||
C += 200;
|
||||
}
|
||||
R_LY++;
|
||||
stat_trigger();
|
||||
break;
|
||||
case 2:
|
||||
lcd_refreshline();
|
||||
stat_change(3);
|
||||
C += 86;
|
||||
break;
|
||||
case 3:
|
||||
stat_change(0);
|
||||
if (hw.hdma & 0x80)
|
||||
hw_hdma();
|
||||
/* FIXME -- how much of the hblank does hdma use?? */
|
||||
/* else */
|
||||
C += 102;
|
||||
break;
|
||||
case 0:
|
||||
if (++R_LY >= 144)
|
||||
{
|
||||
if (cpu.halt)
|
||||
{
|
||||
hw_interrupt(IF_VBLANK, IF_VBLANK);
|
||||
C += 228;
|
||||
}
|
||||
else C += 10;
|
||||
stat_change(1);
|
||||
break;
|
||||
}
|
||||
stat_change(2);
|
||||
C += 40;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
4
apps/plugins/rockboy/lcdc.h
Normal file
4
apps/plugins/rockboy/lcdc.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
void stat_trigger(void);
|
||||
void stat_write(byte b);
|
||||
void lcdc_change(byte b);
|
||||
void lcdc_trans(void);
|
383
apps/plugins/rockboy/loader.c
Normal file
383
apps/plugins/rockboy/loader.c
Normal file
|
@ -0,0 +1,383 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "rockmacros.h"
|
||||
#include "defs.h"
|
||||
#include "regs.h"
|
||||
#include "mem.h"
|
||||
#include "hw.h"
|
||||
#include "rtc.h"
|
||||
#include "rc.h"
|
||||
#include "save.h"
|
||||
#include "sound.h"
|
||||
|
||||
|
||||
static int mbc_table[256] =
|
||||
{
|
||||
0, 1, 1, 1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3,
|
||||
3, 3, 3, 3, 0, 0, 0, 0, 0, 5, 5, 5, MBC_RUMBLE, MBC_RUMBLE, MBC_RUMBLE, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MBC_HUC3, MBC_HUC1
|
||||
};
|
||||
|
||||
static int rtc_table[256] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0
|
||||
};
|
||||
|
||||
static int batt_table[256] =
|
||||
{
|
||||
0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0,
|
||||
1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
|
||||
0
|
||||
};
|
||||
|
||||
static int romsize_table[256] =
|
||||
{
|
||||
2, 4, 8, 16, 32, 64, 128, 256, 512,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 128, 128, 128
|
||||
/* 0, 0, 72, 80, 96 -- actual values but bad to use these! */
|
||||
};
|
||||
|
||||
static int ramsize_table[256] =
|
||||
{
|
||||
1, 1, 1, 4, 16,
|
||||
4 /* FIXME - what value should this be?! */
|
||||
};
|
||||
|
||||
|
||||
static char *romfile;
|
||||
static char sramfile[500];
|
||||
static char rtcfile[500];
|
||||
static char saveprefix[500];
|
||||
|
||||
static char *savename;
|
||||
static char *savedir = "/.rockbox/rockboy";
|
||||
|
||||
static int saveslot;
|
||||
|
||||
static int forcebatt, nobatt;
|
||||
static int forcedmg;
|
||||
|
||||
static int memfill = -1, memrand = -1;
|
||||
|
||||
//static byte romMemory[4*1025*1024];
|
||||
int mp3_buffer_size;
|
||||
void *bufferpos;
|
||||
|
||||
static void initmem(void *mem, int size)
|
||||
{
|
||||
char *p = mem;
|
||||
if (memrand >= 0)
|
||||
{
|
||||
srand(memrand ? memrand : -6 ); //time(0));
|
||||
while(size--) *(p++) = rand();
|
||||
}
|
||||
else if (memfill >= 0)
|
||||
memset(p, memfill, size);
|
||||
}
|
||||
|
||||
static byte *loadfile(int fd, int *len)
|
||||
{
|
||||
int c, l = 0, p = 0;
|
||||
|
||||
byte *d, buf[512];
|
||||
d=malloc(32768);
|
||||
for(;;)
|
||||
{
|
||||
c = read(fd, buf, sizeof buf);
|
||||
if (c <= 0) break;
|
||||
l += c;
|
||||
memcpy(d+p, buf, c);
|
||||
p += c;
|
||||
}
|
||||
setmallocpos(d+p+64);
|
||||
*len = l;
|
||||
return d;
|
||||
}
|
||||
|
||||
//static byte sram[65536];
|
||||
|
||||
int rom_load(void)
|
||||
{
|
||||
int fd;
|
||||
byte c, *data, *header;
|
||||
int len = 0, rlen;
|
||||
|
||||
fd = open(romfile, O_RDONLY);
|
||||
|
||||
if (fd<0) {
|
||||
die("cannot open rom file");
|
||||
die(romfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
data = loadfile(fd, &len);
|
||||
header = data; // no zip. = decompress(data, &len);
|
||||
|
||||
memcpy(rom.name, header+0x0134, 16);
|
||||
if (rom.name[14] & 0x80) rom.name[14] = 0;
|
||||
if (rom.name[15] & 0x80) rom.name[15] = 0;
|
||||
rom.name[16] = 0;
|
||||
|
||||
c = header[0x0147];
|
||||
mbc.type = mbc_table[c];
|
||||
mbc.batt = (batt_table[c] && !nobatt) || forcebatt;
|
||||
// mbc.batt = 1; // always store savegame mem.
|
||||
rtc.batt = rtc_table[c];
|
||||
mbc.romsize = romsize_table[header[0x0148]];
|
||||
mbc.ramsize = ramsize_table[header[0x0149]];
|
||||
|
||||
if (!mbc.romsize) {
|
||||
die("unknown ROM size %02X\n", header[0x0148]);
|
||||
return 1;
|
||||
}
|
||||
if (!mbc.ramsize) {
|
||||
die("unknown SRAM size %02X\n", header[0x0149]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rlen = 16384 * mbc.romsize;
|
||||
rom.bank = (void *) data; //realloc(data, rlen);
|
||||
if (rlen > len) memset(rom.bank[0]+len, 0xff, rlen - len);
|
||||
|
||||
ram.sbank = malloc(8192 * mbc.ramsize);
|
||||
//ram.ibank = malloc(4096*8);
|
||||
|
||||
initmem(ram.sbank, 8192 * mbc.ramsize);
|
||||
initmem(ram.ibank, 4096 * 8);
|
||||
|
||||
mbc.rombank = 1;
|
||||
mbc.rambank = 0;
|
||||
|
||||
c = header[0x0143];
|
||||
hw.cgb = ((c == 0x80) || (c == 0xc0)) && !forcedmg;
|
||||
hw.gba = 0; //(hw.cgb && gbamode);
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sram_load(void)
|
||||
{
|
||||
int fd;
|
||||
char meow[500];
|
||||
|
||||
if (!mbc.batt || !sramfile || !*sramfile) return -1;
|
||||
|
||||
/* Consider sram loaded at this point, even if file doesn't exist */
|
||||
ram.loaded = 1;
|
||||
|
||||
fd = open(sramfile, O_RDONLY);
|
||||
snprintf(meow,499,"Opening %s %d",sramfile,fd);
|
||||
rb->splash(HZ*2, true, meow);
|
||||
if (fd<0) return -1;
|
||||
snprintf(meow,499,"Loading savedata from %s",sramfile);
|
||||
rb->splash(HZ*2, true, meow);
|
||||
read(fd,ram.sbank, 8192*mbc.ramsize);
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sram_save(void)
|
||||
{
|
||||
int fd;
|
||||
char meow[500];
|
||||
|
||||
/* If we crash before we ever loaded sram, DO NOT SAVE! */
|
||||
if (!mbc.batt || !sramfile || !ram.loaded || !mbc.ramsize)
|
||||
return -1;
|
||||
fd = open(sramfile, O_WRONLY|O_CREAT);
|
||||
// snprintf(meow,499,"Opening %s %d",sramfile,fd);
|
||||
// rb->splash(HZ*2, true, meow);
|
||||
if (fd<0) return -1;
|
||||
snprintf(meow,499,"Saving savedata to %s",sramfile);
|
||||
rb->splash(HZ*2, true, meow);
|
||||
write(fd,ram.sbank, 8192*mbc.ramsize);
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void state_save(int n)
|
||||
{
|
||||
int fd;
|
||||
char name[500];
|
||||
|
||||
if (n < 0) n = saveslot;
|
||||
if (n < 0) n = 0;
|
||||
snprintf(name, 499,"%s.%03d", saveprefix, n);
|
||||
|
||||
if ((fd = open(name, O_WRONLY|O_CREAT)>=0))
|
||||
{
|
||||
savestate(fd);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void state_load(int n)
|
||||
{
|
||||
int fd;
|
||||
char name[500];
|
||||
|
||||
if (n < 0) n = saveslot;
|
||||
if (n < 0) n = 0;
|
||||
snprintf(name, 499, "%s.%03d", saveprefix, n);
|
||||
|
||||
if ((fd = open(name, O_RDONLY)>=0))
|
||||
{
|
||||
loadstate(fd);
|
||||
close(fd);
|
||||
vram_dirty();
|
||||
pal_dirty();
|
||||
sound_dirty();
|
||||
mem_updatemap();
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_save(void)
|
||||
{
|
||||
int fd;
|
||||
if (!rtc.batt) return;
|
||||
if ((fd = open(rtcfile, O_WRONLY|O_CREAT))<0) return;
|
||||
rtc_save_internal(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void rtc_load(void)
|
||||
{
|
||||
int fd;
|
||||
if (!rtc.batt) return;
|
||||
if ((fd = open(rtcfile, O_RDONLY))<0) return;
|
||||
rtc_load_internal(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
void loader_unload(void)
|
||||
{
|
||||
sram_save();
|
||||
// if (romfile) free(romfile);
|
||||
// if (sramfile) free(sramfile);
|
||||
// if (saveprefix) free(saveprefix);
|
||||
// if (rom.bank) free(rom.bank);
|
||||
// if (ram.sbank) free(ram.sbank);
|
||||
romfile = 0;
|
||||
rom.bank = 0;
|
||||
ram.sbank = 0;
|
||||
mbc.type = mbc.romsize = mbc.ramsize = mbc.batt = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
static char *base(char *s)
|
||||
{
|
||||
char *p;
|
||||
p = strrchr(s, '/');
|
||||
if (p) return p+1;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
static char *ldup(char *s)
|
||||
{
|
||||
int i;
|
||||
char *n, *p;
|
||||
p = n = malloc(strlen(s));
|
||||
for (i = 0; s[i]; i++) if (isalnum(s[i])) *(p++) = tolower(s[i]);
|
||||
*p = 0;
|
||||
return n;
|
||||
}*/
|
||||
|
||||
void cleanup(void)
|
||||
{
|
||||
sram_save();
|
||||
rtc_save();
|
||||
// IDEA - if error, write emergency savestate..?
|
||||
}
|
||||
|
||||
void loader_init(char *s)
|
||||
{
|
||||
char *name;
|
||||
DIR* dir;
|
||||
|
||||
// sys_checkdir(savedir, 1); /* needs to be writable */
|
||||
dir=opendir(savedir);
|
||||
if(!dir)
|
||||
mkdir(savedir,0);
|
||||
else
|
||||
closedir(dir);
|
||||
|
||||
romfile = s;
|
||||
if(rom_load())
|
||||
return;
|
||||
vid_settitle(rom.name);
|
||||
name = rom.name;
|
||||
|
||||
snprintf(saveprefix, 499, "%s/%s", savedir, name);
|
||||
|
||||
strcpy(sramfile, saveprefix);
|
||||
strcat(sramfile, ".sav");
|
||||
|
||||
strcpy(rtcfile, saveprefix);
|
||||
strcat(rtcfile, ".rtc");
|
||||
|
||||
sram_load();
|
||||
rtc_load();
|
||||
|
||||
//atexit(cleanup);
|
||||
}
|
||||
|
||||
rcvar_t loader_exports[] =
|
||||
{
|
||||
RCV_STRING("savedir", &savedir),
|
||||
RCV_STRING("savename", &savename),
|
||||
RCV_INT("saveslot", &saveslot),
|
||||
RCV_BOOL("forcebatt", &forcebatt),
|
||||
RCV_BOOL("nobatt", &nobatt),
|
||||
RCV_BOOL("forcedmg", &forcedmg),
|
||||
RCV_INT("memfill", &memfill),
|
||||
RCV_INT("memrand", &memrand),
|
||||
RCV_END
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
28
apps/plugins/rockboy/loader.h
Normal file
28
apps/plugins/rockboy/loader.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
|
||||
|
||||
#ifndef __LOADER_H__
|
||||
#define __LOADER_H__
|
||||
|
||||
|
||||
typedef struct loader_s
|
||||
{
|
||||
char *rom;
|
||||
char *base;
|
||||
char *sram;
|
||||
char *state;
|
||||
int ramloaded;
|
||||
} loader_t;
|
||||
|
||||
|
||||
extern loader_t loader;
|
||||
|
||||
|
||||
int rom_load(void);
|
||||
int sram_load(void);
|
||||
int sram_save(void);
|
||||
void loader_init(char *s);
|
||||
void cleanup(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
83
apps/plugins/rockboy/main.c
Normal file
83
apps/plugins/rockboy/main.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rockmacros.h"
|
||||
#include "input.h"
|
||||
#include "rc.h"
|
||||
#include "exports.h"
|
||||
#include "emu.h"
|
||||
#include "loader.h"
|
||||
#include "hw.h"
|
||||
|
||||
//#include "Version"
|
||||
|
||||
|
||||
static char *defaultconfig[] =
|
||||
{
|
||||
"bind up +up",
|
||||
"bind down +down",
|
||||
"bind left +left",
|
||||
"bind right +right",
|
||||
"bind joy0 +b",
|
||||
"bind joy1 +a",
|
||||
"bind joy2 +select",
|
||||
"bind joy3 +start",
|
||||
"bind ins savestate",
|
||||
"bind del loadstate",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
void doevents()
|
||||
{
|
||||
event_t ev;
|
||||
int st;
|
||||
|
||||
ev_poll();
|
||||
while (ev_getevent(&ev))
|
||||
{
|
||||
if (ev.type != EV_PRESS && ev.type != EV_RELEASE)
|
||||
continue;
|
||||
st = (ev.type != EV_RELEASE);
|
||||
pad_set(ev.code, st);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int gnuboy_main(char *rom)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Avoid initializing video if we don't have to
|
||||
// If we have special perms, drop them ASAP!
|
||||
rb->splash(HZ*1, true, "Init exports");
|
||||
init_exports();
|
||||
|
||||
rb->splash(HZ*1, true, "Loading default config");
|
||||
for (i = 0; defaultconfig[i]; i++)
|
||||
rc_command(defaultconfig[i]);
|
||||
|
||||
// sprintf(cmd, "source %s", rom);
|
||||
// s = strchr(cmd, '.');
|
||||
// if (s) *s = 0;
|
||||
// strcat(cmd, ".rc");
|
||||
// rc_command(cmd);
|
||||
|
||||
// FIXME - make interface modules responsible for atexit()
|
||||
rb->splash(HZ*1, true, "Init video");
|
||||
vid_init();
|
||||
rb->splash(HZ*1, true, "Init sound (nosound)");
|
||||
pcm_init();
|
||||
rb->splash(HZ*1, true, "Loading rom");
|
||||
loader_init(rom);
|
||||
if(shut)
|
||||
return PLUGIN_ERROR;
|
||||
rb->splash(HZ*1, true, "Emu reset");
|
||||
emu_reset();
|
||||
rb->splash(HZ*1, true, "Emu run");
|
||||
emu_run();
|
||||
|
||||
// never reached
|
||||
return PLUGIN_OK;
|
||||
}
|
578
apps/plugins/rockboy/mem.c
Normal file
578
apps/plugins/rockboy/mem.c
Normal file
|
@ -0,0 +1,578 @@
|
|||
|
||||
|
||||
#include "rockmacros.h"
|
||||
|
||||
#include "defs.h"
|
||||
#include "hw.h"
|
||||
#include "regs.h"
|
||||
#include "mem.h"
|
||||
#include "rtc.h"
|
||||
#include "lcd.h"
|
||||
#include "lcdc.h"
|
||||
#include "sound.h"
|
||||
|
||||
struct mbc mbc;
|
||||
struct rom rom;
|
||||
struct ram ram;
|
||||
|
||||
|
||||
/*
|
||||
* In order to make reads and writes efficient, we keep tables
|
||||
* (indexed by the high nibble of the address) specifying which
|
||||
* regions can be read/written without a function call. For such
|
||||
* ranges, the pointer in the map table points to the base of the
|
||||
* region in host system memory. For ranges that require special
|
||||
* processing, the pointer is NULL.
|
||||
*
|
||||
* mem_updatemap is called whenever bank changes or other operations
|
||||
* make the old maps potentially invalid.
|
||||
*/
|
||||
|
||||
void mem_updatemap()
|
||||
{
|
||||
int n;
|
||||
byte **map;
|
||||
|
||||
map = mbc.rmap;
|
||||
map[0x0] = rom.bank[0];
|
||||
map[0x1] = rom.bank[0];
|
||||
map[0x2] = rom.bank[0];
|
||||
map[0x3] = rom.bank[0];
|
||||
if (mbc.rombank < mbc.romsize)
|
||||
{
|
||||
map[0x4] = rom.bank[mbc.rombank] - 0x4000;
|
||||
map[0x5] = rom.bank[mbc.rombank] - 0x4000;
|
||||
map[0x6] = rom.bank[mbc.rombank] - 0x4000;
|
||||
map[0x7] = rom.bank[mbc.rombank] - 0x4000;
|
||||
}
|
||||
else map[0x4] = map[0x5] = map[0x6] = map[0x7] = NULL;
|
||||
if (0 && (R_STAT & 0x03) == 0x03)
|
||||
{
|
||||
map[0x8] = NULL;
|
||||
map[0x9] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
map[0x8] = lcd.vbank[R_VBK & 1] - 0x8000;
|
||||
map[0x9] = lcd.vbank[R_VBK & 1] - 0x8000;
|
||||
}
|
||||
if (mbc.enableram && !(rtc.sel&8))
|
||||
{
|
||||
map[0xA] = ram.sbank[mbc.rambank] - 0xA000;
|
||||
map[0xB] = ram.sbank[mbc.rambank] - 0xA000;
|
||||
}
|
||||
else map[0xA] = map[0xB] = NULL;
|
||||
map[0xC] = ram.ibank[0] - 0xC000;
|
||||
n = R_SVBK & 0x07;
|
||||
map[0xD] = ram.ibank[n?n:1] - 0xD000;
|
||||
map[0xE] = ram.ibank[0] - 0xE000;
|
||||
map[0xF] = NULL;
|
||||
|
||||
map = mbc.wmap;
|
||||
map[0x0] = map[0x1] = map[0x2] = map[0x3] = NULL;
|
||||
map[0x4] = map[0x5] = map[0x6] = map[0x7] = NULL;
|
||||
map[0x8] = map[0x9] = NULL;
|
||||
if (mbc.enableram && !(rtc.sel&8))
|
||||
{
|
||||
map[0xA] = ram.sbank[mbc.rambank] - 0xA000;
|
||||
map[0xB] = ram.sbank[mbc.rambank] - 0xA000;
|
||||
}
|
||||
else map[0xA] = map[0xB] = NULL;
|
||||
map[0xC] = ram.ibank[0] - 0xC000;
|
||||
n = R_SVBK & 0x07;
|
||||
map[0xD] = ram.ibank[n?n:1] - 0xD000;
|
||||
map[0xE] = ram.ibank[0] - 0xE000;
|
||||
map[0xF] = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ioreg_write handles output to io registers in the FF00-FF7F,FFFF
|
||||
* range. It takes the register number (low byte of the address) and a
|
||||
* byte value to be written.
|
||||
*/
|
||||
|
||||
void ioreg_write(byte r, byte b)
|
||||
{
|
||||
if (!hw.cgb)
|
||||
{
|
||||
|
||||
switch (r)
|
||||
{
|
||||
case RI_VBK:
|
||||
case RI_BCPS:
|
||||
case RI_OCPS:
|
||||
case RI_BCPD:
|
||||
case RI_OCPD:
|
||||
case RI_SVBK:
|
||||
case RI_KEY1:
|
||||
case RI_HDMA1:
|
||||
case RI_HDMA2:
|
||||
case RI_HDMA3:
|
||||
case RI_HDMA4:
|
||||
case RI_HDMA5:
|
||||
return;
|
||||
}
|
||||
}
|
||||
switch(r)
|
||||
{
|
||||
case RI_TIMA:
|
||||
case RI_TMA:
|
||||
case RI_TAC:
|
||||
case RI_SCY:
|
||||
case RI_SCX:
|
||||
case RI_WY:
|
||||
case RI_WX:
|
||||
REG(r) = b;
|
||||
break;
|
||||
case RI_BGP:
|
||||
if (R_BGP == b) break;
|
||||
pal_write_dmg(0, 0, b);
|
||||
pal_write_dmg(8, 1, b);
|
||||
R_BGP = b;
|
||||
break;
|
||||
case RI_OBP0:
|
||||
if (R_OBP0 == b) break;
|
||||
pal_write_dmg(64, 2, b);
|
||||
R_OBP0 = b;
|
||||
break;
|
||||
case RI_OBP1:
|
||||
if (R_OBP1 == b) break;
|
||||
pal_write_dmg(72, 3, b);
|
||||
R_OBP1 = b;
|
||||
break;
|
||||
case RI_IF:
|
||||
case RI_IE:
|
||||
REG(r) = b & 0x1F;
|
||||
break;
|
||||
case RI_P1:
|
||||
REG(r) = b;
|
||||
pad_refresh();
|
||||
break;
|
||||
case RI_SC:
|
||||
/* FIXME - this is a hack for stupid roms that probe serial */
|
||||
if ((b & 0x81) == 0x81)
|
||||
{
|
||||
R_SB = 0xff;
|
||||
hw_interrupt(IF_SERIAL, IF_SERIAL);
|
||||
hw_interrupt(0, IF_SERIAL);
|
||||
}
|
||||
R_SC = b; /* & 0x7f; */
|
||||
break;
|
||||
case RI_DIV:
|
||||
REG(r) = 0;
|
||||
break;
|
||||
case RI_LCDC:
|
||||
lcdc_change(b);
|
||||
break;
|
||||
case RI_STAT:
|
||||
stat_write(b);
|
||||
break;
|
||||
case RI_LYC:
|
||||
REG(r) = b;
|
||||
stat_trigger();
|
||||
break;
|
||||
case RI_VBK:
|
||||
REG(r) = b | 0xFE;
|
||||
mem_updatemap();
|
||||
break;
|
||||
case RI_BCPS:
|
||||
R_BCPS = b & 0xBF;
|
||||
R_BCPD = lcd.pal[b & 0x3F];
|
||||
break;
|
||||
case RI_OCPS:
|
||||
R_OCPS = b & 0xBF;
|
||||
R_OCPD = lcd.pal[64 + (b & 0x3F)];
|
||||
break;
|
||||
case RI_BCPD:
|
||||
R_BCPD = b;
|
||||
pal_write(R_BCPS & 0x3F, b);
|
||||
if (R_BCPS & 0x80) R_BCPS = (R_BCPS+1) & 0xBF;
|
||||
break;
|
||||
case RI_OCPD:
|
||||
R_OCPD = b;
|
||||
pal_write(64 + (R_OCPS & 0x3F), b);
|
||||
if (R_OCPS & 0x80) R_OCPS = (R_OCPS+1) & 0xBF;
|
||||
break;
|
||||
case RI_SVBK:
|
||||
REG(r) = b & 0x07;
|
||||
mem_updatemap();
|
||||
break;
|
||||
case RI_DMA:
|
||||
hw_dma(b);
|
||||
break;
|
||||
case RI_KEY1:
|
||||
REG(r) = (REG(r) & 0x80) | (b & 0x01);
|
||||
break;
|
||||
case RI_HDMA1:
|
||||
REG(r) = b;
|
||||
break;
|
||||
case RI_HDMA2:
|
||||
REG(r) = b & 0xF0;
|
||||
break;
|
||||
case RI_HDMA3:
|
||||
REG(r) = b & 0x1F;
|
||||
break;
|
||||
case RI_HDMA4:
|
||||
REG(r) = b & 0xF0;
|
||||
break;
|
||||
case RI_HDMA5:
|
||||
hw_hdma_cmd(b);
|
||||
break;
|
||||
}
|
||||
switch (r)
|
||||
{
|
||||
case RI_BGP:
|
||||
case RI_OBP0:
|
||||
case RI_OBP1:
|
||||
/* printf("palette reg %02X write %02X at LY=%02X\n", r, b, R_LY); */
|
||||
case RI_HDMA1:
|
||||
case RI_HDMA2:
|
||||
case RI_HDMA3:
|
||||
case RI_HDMA4:
|
||||
case RI_HDMA5:
|
||||
/* printf("HDMA %d: %02X\n", r - RI_HDMA1 + 1, b); */
|
||||
break;
|
||||
}
|
||||
/* printf("reg %02X => %02X (%02X)\n", r, REG(r), b); */
|
||||
}
|
||||
|
||||
|
||||
byte ioreg_read(byte r)
|
||||
{
|
||||
switch(r)
|
||||
{
|
||||
case RI_SC:
|
||||
r = R_SC;
|
||||
R_SC &= 0x7f;
|
||||
return r;
|
||||
case RI_P1:
|
||||
case RI_SB:
|
||||
case RI_DIV:
|
||||
case RI_TIMA:
|
||||
case RI_TMA:
|
||||
case RI_TAC:
|
||||
case RI_LCDC:
|
||||
case RI_STAT:
|
||||
case RI_SCY:
|
||||
case RI_SCX:
|
||||
case RI_LY:
|
||||
case RI_LYC:
|
||||
case RI_BGP:
|
||||
case RI_OBP0:
|
||||
case RI_OBP1:
|
||||
case RI_WY:
|
||||
case RI_WX:
|
||||
case RI_IE:
|
||||
case RI_IF:
|
||||
return REG(r);
|
||||
case RI_VBK:
|
||||
case RI_BCPS:
|
||||
case RI_OCPS:
|
||||
case RI_BCPD:
|
||||
case RI_OCPD:
|
||||
case RI_SVBK:
|
||||
case RI_KEY1:
|
||||
case RI_HDMA1:
|
||||
case RI_HDMA2:
|
||||
case RI_HDMA3:
|
||||
case RI_HDMA4:
|
||||
case RI_HDMA5:
|
||||
if (hw.cgb) return REG(r);
|
||||
default:
|
||||
return 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Memory bank controllers typically intercept write attempts to
|
||||
* 0000-7FFF, using the address and byte written as instructions to
|
||||
* change rom or sram banks, control special hardware, etc.
|
||||
*
|
||||
* mbc_write takes an address (which should be in the proper range)
|
||||
* and a byte value written to the address.
|
||||
*/
|
||||
|
||||
void mbc_write(int a, byte b)
|
||||
{
|
||||
byte ha = (a>>12);
|
||||
|
||||
/* printf("mbc %d: rom bank %02X -[%04X:%02X]-> ", mbc.type, mbc.rombank, a, b); */
|
||||
switch (mbc.type)
|
||||
{
|
||||
case MBC_MBC1:
|
||||
switch (ha & 0xE)
|
||||
{
|
||||
case 0x0:
|
||||
mbc.enableram = ((b & 0x0F) == 0x0A);
|
||||
break;
|
||||
case 0x2:
|
||||
if ((b & 0x1F) == 0) b = 0x01;
|
||||
mbc.rombank = (mbc.rombank & 0x60) | (b & 0x1F);
|
||||
break;
|
||||
case 0x4:
|
||||
if (mbc.model)
|
||||
{
|
||||
mbc.rambank = b & 0x03;
|
||||
break;
|
||||
}
|
||||
mbc.rombank = (mbc.rombank & 0x1F) | ((int)(b&3)<<5);
|
||||
break;
|
||||
case 0x6:
|
||||
mbc.model = b & 0x1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MBC_MBC2: /* is this at all right? */
|
||||
if ((a & 0x0100) == 0x0000)
|
||||
{
|
||||
mbc.enableram = ((b & 0x0F) == 0x0A);
|
||||
break;
|
||||
}
|
||||
if ((a & 0xE100) == 0x2100)
|
||||
{
|
||||
mbc.rombank = b & 0x0F;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MBC_MBC3:
|
||||
switch (ha & 0xE)
|
||||
{
|
||||
case 0x0:
|
||||
mbc.enableram = ((b & 0x0F) == 0x0A);
|
||||
break;
|
||||
case 0x2:
|
||||
if ((b & 0x7F) == 0) b = 0x01;
|
||||
mbc.rombank = b & 0x7F;
|
||||
break;
|
||||
case 0x4:
|
||||
rtc.sel = b & 0x0f;
|
||||
mbc.rambank = b & 0x03;
|
||||
break;
|
||||
case 0x6:
|
||||
rtc_latch(b);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MBC_RUMBLE:
|
||||
switch (ha & 0xF)
|
||||
{
|
||||
case 0x4:
|
||||
case 0x5:
|
||||
/* FIXME - save high bit as rumble state */
|
||||
/* mask off high bit */
|
||||
b &= 0x7;
|
||||
break;
|
||||
}
|
||||
/* fall thru */
|
||||
case MBC_MBC5:
|
||||
switch (ha & 0xF)
|
||||
{
|
||||
case 0x0:
|
||||
case 0x1:
|
||||
mbc.enableram = ((b & 0x0F) == 0x0A);
|
||||
break;
|
||||
case 0x2:
|
||||
if ((b & 0xFF) == 0) b = 0x01;
|
||||
mbc.rombank = (mbc.rombank & 0x100) | (b & 0xFF);
|
||||
break;
|
||||
case 0x3:
|
||||
mbc.rombank = (mbc.rombank & 0xFF) | ((int)(b&1)<<8);
|
||||
break;
|
||||
case 0x4:
|
||||
case 0x5:
|
||||
mbc.rambank = b & 0x0f;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MBC_HUC1: /* FIXME - this is all guesswork -- is it right??? */
|
||||
switch (ha & 0xE)
|
||||
{
|
||||
case 0x0:
|
||||
mbc.enableram = ((b & 0x0F) == 0x0A);
|
||||
break;
|
||||
case 0x2:
|
||||
if ((b & 0x1F) == 0) b = 0x01;
|
||||
mbc.rombank = (mbc.rombank & 0x60) | (b & 0x1F);
|
||||
break;
|
||||
case 0x4:
|
||||
if (mbc.model)
|
||||
{
|
||||
mbc.rambank = b & 0x03;
|
||||
break;
|
||||
}
|
||||
mbc.rombank = (mbc.rombank & 0x1F) | ((int)(b&3)<<5);
|
||||
break;
|
||||
case 0x6:
|
||||
mbc.model = b & 0x1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MBC_HUC3:
|
||||
switch (ha & 0xE)
|
||||
{
|
||||
case 0x0:
|
||||
mbc.enableram = ((b & 0x0F) == 0x0A);
|
||||
break;
|
||||
case 0x2:
|
||||
b &= 0x7F;
|
||||
mbc.rombank = b ? b : 1;
|
||||
break;
|
||||
case 0x4:
|
||||
rtc.sel = b & 0x0f;
|
||||
mbc.rambank = b & 0x03;
|
||||
break;
|
||||
case 0x6:
|
||||
rtc_latch(b);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
mbc.rombank &= (mbc.romsize - 1);
|
||||
mbc.rambank &= (mbc.ramsize - 1);
|
||||
/* printf("%02X\n", mbc.rombank); */
|
||||
mem_updatemap();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mem_write is the basic write function. Although it should only be
|
||||
* called when the write map contains a NULL for the requested address
|
||||
* region, it accepts writes to any address.
|
||||
*/
|
||||
|
||||
void mem_write(int a, byte b)
|
||||
{
|
||||
int n;
|
||||
byte ha = (a>>12) & 0xE;
|
||||
|
||||
/* printf("write to 0x%04X: 0x%02X\n", a, b); */
|
||||
switch (ha)
|
||||
{
|
||||
case 0x0:
|
||||
case 0x2:
|
||||
case 0x4:
|
||||
case 0x6:
|
||||
mbc_write(a, b);
|
||||
break;
|
||||
case 0x8:
|
||||
/* if ((R_STAT & 0x03) == 0x03) break; */
|
||||
vram_write(a & 0x1FFF, b);
|
||||
break;
|
||||
case 0xA:
|
||||
if (!mbc.enableram) break;
|
||||
if (rtc.sel&8)
|
||||
{
|
||||
rtc_write(b);
|
||||
break;
|
||||
}
|
||||
ram.sbank[mbc.rambank][a & 0x1FFF] = b;
|
||||
break;
|
||||
case 0xC:
|
||||
if ((a & 0xF000) == 0xC000)
|
||||
{
|
||||
ram.ibank[0][a & 0x0FFF] = b;
|
||||
break;
|
||||
}
|
||||
n = R_SVBK & 0x07;
|
||||
ram.ibank[n?n:1][a & 0x0FFF] = b;
|
||||
break;
|
||||
case 0xE:
|
||||
if (a < 0xFE00)
|
||||
{
|
||||
mem_write(a & 0xDFFF, b);
|
||||
break;
|
||||
}
|
||||
if ((a & 0xFF00) == 0xFE00)
|
||||
{
|
||||
/* if (R_STAT & 0x02) break; */
|
||||
if (a < 0xFEA0) lcd.oam.mem[a & 0xFF] = b;
|
||||
break;
|
||||
}
|
||||
/* return writehi(a & 0xFF, b); */
|
||||
if (a >= 0xFF10 && a <= 0xFF3F)
|
||||
{
|
||||
sound_write(a & 0xFF, b);
|
||||
break;
|
||||
}
|
||||
if ((a & 0xFF80) == 0xFF80 && a != 0xFFFF)
|
||||
{
|
||||
ram.hi[a & 0xFF] = b;
|
||||
break;
|
||||
}
|
||||
ioreg_write(a & 0xFF, b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mem_read is the basic read function...not useful for much anymore
|
||||
* with the read map, but it's still necessary for the final messy
|
||||
* region.
|
||||
*/
|
||||
|
||||
byte mem_read(int a)
|
||||
{
|
||||
int n;
|
||||
byte ha = (a>>12) & 0xE;
|
||||
|
||||
/* printf("read %04x\n", a); */
|
||||
switch (ha)
|
||||
{
|
||||
case 0x0:
|
||||
case 0x2:
|
||||
return rom.bank[0][a];
|
||||
case 0x4:
|
||||
case 0x6:
|
||||
return rom.bank[mbc.rombank][a & 0x3FFF];
|
||||
case 0x8:
|
||||
/* if ((R_STAT & 0x03) == 0x03) return 0xFF; */
|
||||
return lcd.vbank[R_VBK&1][a & 0x1FFF];
|
||||
case 0xA:
|
||||
if (!mbc.enableram && mbc.type == MBC_HUC3)
|
||||
return 0x01;
|
||||
if (!mbc.enableram)
|
||||
return 0xFF;
|
||||
if (rtc.sel&8)
|
||||
return rtc.regs[rtc.sel&7];
|
||||
return ram.sbank[mbc.rambank][a & 0x1FFF];
|
||||
case 0xC:
|
||||
if ((a & 0xF000) == 0xC000)
|
||||
return ram.ibank[0][a & 0x0FFF];
|
||||
n = R_SVBK & 0x07;
|
||||
return ram.ibank[n?n:1][a & 0x0FFF];
|
||||
case 0xE:
|
||||
if (a < 0xFE00) return mem_read(a & 0xDFFF);
|
||||
if ((a & 0xFF00) == 0xFE00)
|
||||
{
|
||||
/* if (R_STAT & 0x02) return 0xFF; */
|
||||
if (a < 0xFEA0) return lcd.oam.mem[a & 0xFF];
|
||||
return 0xFF;
|
||||
}
|
||||
/* return readhi(a & 0xFF); */
|
||||
if (a == 0xFFFF) return REG(0xFF);
|
||||
if (a >= 0xFF10 && a <= 0xFF3F)
|
||||
return sound_read(a & 0xFF);
|
||||
if ((a & 0xFF80) == 0xFF80)
|
||||
return ram.hi[a & 0xFF];
|
||||
return ioreg_read(a & 0xFF);
|
||||
}
|
||||
return 0xff; /* not reached */
|
||||
}
|
||||
|
||||
void mbc_reset(void)
|
||||
{
|
||||
mbc.rombank = 1;
|
||||
mbc.rambank = 0;
|
||||
mbc.enableram = 0;
|
||||
mem_updatemap();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
80
apps/plugins/rockboy/mem.h
Normal file
80
apps/plugins/rockboy/mem.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
|
||||
#ifndef __MEM_H__
|
||||
#define __MEM_H__
|
||||
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
|
||||
|
||||
#define MBC_NONE 0
|
||||
#define MBC_MBC1 1
|
||||
#define MBC_MBC2 2
|
||||
#define MBC_MBC3 3
|
||||
#define MBC_MBC5 5
|
||||
#define MBC_RUMBLE 15
|
||||
#define MBC_HUC1 0xC1
|
||||
#define MBC_HUC3 0xC3
|
||||
|
||||
struct mbc
|
||||
{
|
||||
int type;
|
||||
int model;
|
||||
int rombank;
|
||||
int rambank;
|
||||
int romsize;
|
||||
int ramsize;
|
||||
int enableram;
|
||||
int batt;
|
||||
byte *rmap[0x10], *wmap[0x10];
|
||||
};
|
||||
|
||||
struct rom
|
||||
{
|
||||
byte (*bank)[16384];
|
||||
char name[20];
|
||||
};
|
||||
|
||||
struct ram
|
||||
{
|
||||
byte hi[256];
|
||||
byte ibank[8][4096];
|
||||
byte (*sbank)[8192];
|
||||
int loaded;
|
||||
};
|
||||
|
||||
|
||||
extern struct mbc mbc;
|
||||
extern struct rom rom;
|
||||
extern struct ram ram;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void mem_updatemap(void);
|
||||
void ioreg_write(byte r, byte b);
|
||||
void mbc_write(int a, byte b);
|
||||
void mem_write(int a, byte b);
|
||||
byte mem_read(int a);
|
||||
void mbc_reset(void);
|
||||
|
||||
|
||||
|
||||
#define READB(a) ( mbc.rmap[(a)>>12] \
|
||||
? mbc.rmap[(a)>>12][(a)] \
|
||||
: mem_read((a)) )
|
||||
#define READW(a) ( READB((a)) | ((word)READB((a)+1)<<8) )
|
||||
|
||||
#define WRITEB(a, b) ( mbc.wmap[(a)>>12] \
|
||||
? ( mbc.wmap[(a)>>12][(a)] = (b) ) \
|
||||
: ( mem_write((a), (b)), (b) ) )
|
||||
#define WRITEW(a, w) ( WRITEB((a), (w)&0xFF), WRITEB((a)+1, (w)>>8) )
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
532
apps/plugins/rockboy/noise.h
Normal file
532
apps/plugins/rockboy/noise.h
Normal file
|
@ -0,0 +1,532 @@
|
|||
|
||||
#ifndef __NOISE_H__
|
||||
#define __NOISE_H__
|
||||
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
static byte noise7[] =
|
||||
{
|
||||
0xfd,0xf3,0xd7,0x0d,0xd3,0x15,0x82,0xf1,
|
||||
0xdb,0x25,0x21,0x39,0x68,0x8c,0xd5,0x00,
|
||||
};
|
||||
|
||||
static byte noise15[] =
|
||||
{
|
||||
0xff,0xfd,0xff,0xf3,0xff,0xd7,0xff,0x0f,
|
||||
0xfd,0xdf,0xf3,0x3f,0xd5,0x7f,0x00,0xfd,
|
||||
0xfd,0xf3,0xf3,0xd7,0xd7,0x0f,0x0d,0xdd,
|
||||
0xd3,0x33,0x15,0x55,0x80,0x02,0xff,0xf1,
|
||||
0xff,0xdb,0xff,0x27,0xfd,0x2f,0xf1,0x1f,
|
||||
0xd9,0xbf,0x2a,0x7d,0x02,0xf1,0xf1,0xdb,
|
||||
0xdb,0x27,0x25,0x2d,0x21,0x11,0x39,0x99,
|
||||
0x6a,0xa8,0x80,0x0c,0xff,0xd5,0xff,0x03,
|
||||
0xfd,0xf7,0xf3,0xcf,0xd7,0x5f,0x0c,0x3d,
|
||||
0xd7,0x73,0x0c,0xd5,0xd5,0x03,0x01,0xf5,
|
||||
0xfb,0xc3,0xe7,0x77,0xac,0xce,0x15,0x5b,
|
||||
0x80,0x26,0xff,0x29,0xfd,0x0b,0xf1,0xc7,
|
||||
0xdb,0x6f,0x24,0x9d,0x24,0xb1,0x24,0x59,
|
||||
0x26,0x29,0x2b,0x09,0x05,0xc9,0xe3,0x4b,
|
||||
0xb4,0x46,0x46,0x6a,0x6a,0x82,0x80,0xf0,
|
||||
0xfd,0xdd,0xf3,0x33,0xd5,0x57,0x00,0x0d,
|
||||
0xff,0xd3,0xff,0x17,0xfd,0x8f,0xf2,0xdf,
|
||||
0xd1,0x3f,0x19,0x7d,0xa8,0xf2,0x0d,0xd3,
|
||||
0xd3,0x17,0x15,0x8d,0x82,0xd2,0xf1,0x11,
|
||||
0xd9,0x9b,0x2a,0xa5,0x00,0x21,0xff,0x3b,
|
||||
0xfd,0x67,0xf0,0xaf,0xdc,0x1f,0x37,0xbd,
|
||||
0x4e,0x70,0x5a,0xde,0x21,0x3b,0x39,0x65,
|
||||
0x68,0xa0,0x8c,0x3c,0xd7,0x75,0x0c,0xc1,
|
||||
0xd5,0x7b,0x00,0xe5,0xfd,0xa3,0xf2,0x37,
|
||||
0xd3,0x4f,0x14,0x5d,0x86,0x32,0xeb,0x51,
|
||||
0x84,0x1a,0xe7,0xa1,0xae,0x3a,0x1b,0x63,
|
||||
0xa4,0xb6,0x24,0x4b,0x26,0x45,0x2a,0x61,
|
||||
0x02,0xb9,0xf0,0x6b,0xde,0x87,0x38,0xed,
|
||||
0x6d,0x90,0x92,0x9c,0x90,0xb4,0x9c,0x44,
|
||||
0xb6,0x64,0x4a,0xa6,0x40,0x2a,0x7f,0x02,
|
||||
0xfd,0xf1,0xf3,0xdb,0xd7,0x27,0x0d,0x2d,
|
||||
0xd1,0x13,0x19,0x95,0xaa,0x82,0x00,0xf3,
|
||||
0xfd,0xd7,0xf3,0x0f,0xd5,0xdf,0x03,0x3d,
|
||||
0xf5,0x73,0xc0,0xd7,0x7d,0x0c,0xf1,0xd5,
|
||||
0xdb,0x03,0x25,0xf5,0x23,0xc1,0x37,0x79,
|
||||
0x4c,0xe8,0x55,0x8e,0x02,0xdb,0xf1,0x27,
|
||||
0xd9,0x2f,0x29,0x1d,0x09,0xb1,0xca,0x5b,
|
||||
0x42,0x24,0x73,0x26,0xd5,0x29,0x01,0x09,
|
||||
0xf9,0xcb,0xeb,0x47,0x84,0x6e,0xe6,0x99,
|
||||
0xa8,0xaa,0x0c,0x03,0xd7,0xf7,0x0f,0xcd,
|
||||
0xdf,0x53,0x3c,0x15,0x77,0x80,0xce,0xfd,
|
||||
0x59,0xf0,0x2b,0xdf,0x07,0x3d,0xed,0x73,
|
||||
0x90,0xd6,0x9d,0x08,0xb1,0xcc,0x5b,0x56,
|
||||
0x24,0x0b,0x27,0xc5,0x2f,0x61,0x1c,0xb9,
|
||||
0xb4,0x6a,0x46,0x82,0x68,0xf2,0x8d,0xd0,
|
||||
0xd3,0x1d,0x15,0xb1,0x82,0x5a,0xf2,0x21,
|
||||
0xd3,0x3b,0x15,0x65,0x80,0xa2,0xfc,0x31,
|
||||
0xf7,0x5b,0xcc,0x27,0x57,0x2c,0x0d,0x17,
|
||||
0xd1,0x8f,0x1a,0xdd,0xa1,0x32,0x39,0x53,
|
||||
0x68,0x14,0x8f,0x84,0xde,0xe5,0x39,0xa1,
|
||||
0x6a,0x38,0x83,0x6c,0xf4,0x95,0xc4,0x83,
|
||||
0x64,0xf4,0xa5,0xc4,0x23,0x67,0x34,0xad,
|
||||
0x44,0x10,0x67,0x9e,0xae,0xb8,0x18,0x6f,
|
||||
0xae,0x9e,0x18,0xbb,0xac,0x66,0x16,0xab,
|
||||
0x88,0x06,0xcf,0xe9,0x5f,0x88,0x3e,0xcf,
|
||||
0x79,0x5c,0xe8,0x35,0x8f,0x42,0xdc,0x71,
|
||||
0x36,0xd9,0x49,0x28,0x49,0x0e,0x49,0xda,
|
||||
0x4b,0x22,0x45,0x32,0x61,0x52,0xb8,0x10,
|
||||
0x6f,0x9e,0x9e,0xb8,0xb8,0x6c,0x6e,0x96,
|
||||
0x98,0x88,0xac,0xcc,0x15,0x57,0x80,0x0e,
|
||||
0xff,0xd9,0xff,0x2b,0xfd,0x07,0xf1,0xef,
|
||||
0xdb,0x9f,0x26,0xbd,0x28,0x71,0x0e,0xd9,
|
||||
0xd9,0x2b,0x29,0x05,0x09,0xe1,0xcb,0xbb,
|
||||
0x46,0x64,0x6a,0xa6,0x80,0x28,0xff,0x0d,
|
||||
0xfd,0xd3,0xf3,0x17,0xd5,0x8f,0x02,0xdd,
|
||||
0xf1,0x33,0xd9,0x57,0x28,0x0d,0x0f,0xd1,
|
||||
0xdf,0x1b,0x3d,0xa5,0x72,0x20,0xd3,0x3d,
|
||||
0x15,0x71,0x80,0xda,0xfd,0x21,0xf1,0x3b,
|
||||
0xd9,0x67,0x28,0xad,0x0c,0x11,0xd7,0x9b,
|
||||
0x0e,0xa5,0xd8,0x23,0x2f,0x35,0x1d,0x41,
|
||||
0xb0,0x7a,0x5e,0xe2,0x39,0xb3,0x6a,0x54,
|
||||
0x82,0x04,0xf3,0xe5,0xd7,0xa3,0x0e,0x35,
|
||||
0xdb,0x43,0x24,0x75,0x26,0xc1,0x29,0x79,
|
||||
0x08,0xe9,0xcd,0x8b,0x52,0xc4,0x11,0x67,
|
||||
0x98,0xae,0xac,0x18,0x17,0xaf,0x8e,0x1e,
|
||||
0xdb,0xb9,0x26,0x69,0x2a,0x89,0x00,0xc9,
|
||||
0xfd,0x4b,0xf0,0x47,0xde,0x6f,0x3a,0x9d,
|
||||
0x60,0xb0,0xbc,0x5c,0x76,0x36,0xcb,0x49,
|
||||
0x44,0x48,0x66,0x4e,0xaa,0x58,0x02,0x2f,
|
||||
0xf3,0x1f,0xd5,0xbf,0x02,0x7d,0xf2,0xf3,
|
||||
0xd1,0xd7,0x1b,0x0d,0xa5,0xd2,0x23,0x13,
|
||||
0x35,0x95,0x42,0x80,0x70,0xfe,0xdd,0xf9,
|
||||
0x33,0xe9,0x57,0x88,0x0e,0xcf,0xd9,0x5f,
|
||||
0x28,0x3d,0x0f,0x71,0xdc,0xdb,0x35,0x25,
|
||||
0x41,0x20,0x79,0x3e,0xe9,0x79,0x88,0xea,
|
||||
0xcd,0x81,0x52,0xf8,0x11,0xef,0x9b,0x9e,
|
||||
0xa6,0xb8,0x28,0x6f,0x0e,0x9d,0xd8,0xb3,
|
||||
0x2c,0x55,0x16,0x01,0x8b,0xfa,0xc7,0xe1,
|
||||
0x6f,0xb8,0x9e,0x6c,0xba,0x94,0x60,0x86,
|
||||
0xbc,0xe8,0x75,0x8e,0xc2,0xd9,0x71,0x28,
|
||||
0xd9,0x0d,0x29,0xd1,0x0b,0x19,0xc5,0xab,
|
||||
0x62,0x04,0xb3,0xe4,0x57,0xa6,0x0e,0x2b,
|
||||
0xdb,0x07,0x25,0xed,0x23,0x91,0x36,0x99,
|
||||
0x48,0xa8,0x4c,0x0e,0x57,0xda,0x0f,0x23,
|
||||
0xdd,0x37,0x31,0x4d,0x58,0x50,0x2e,0x1f,
|
||||
0x1b,0xbd,0xa6,0x72,0x2a,0xd3,0x01,0x15,
|
||||
0xf9,0x83,0xea,0xf7,0x81,0xce,0xfb,0x59,
|
||||
0xe4,0x2b,0xa7,0x06,0x2d,0xeb,0x13,0x85,
|
||||
0x96,0xe2,0x89,0xb0,0xca,0x5d,0x42,0x30,
|
||||
0x73,0x5e,0xd4,0x39,0x07,0x69,0xec,0x8b,
|
||||
0x94,0xc6,0x85,0x68,0xe0,0x8d,0xbc,0xd2,
|
||||
0x75,0x12,0xc1,0x91,0x7a,0x98,0xe0,0xad,
|
||||
0xbc,0x12,0x77,0x92,0xce,0x91,0x58,0x98,
|
||||
0x2c,0xaf,0x14,0x1d,0x87,0xb2,0xee,0x51,
|
||||
0x9a,0x1a,0xa3,0xa0,0x36,0x3f,0x4b,0x7c,
|
||||
0x44,0xf6,0x65,0xca,0xa3,0x40,0x34,0x7f,
|
||||
0x46,0xfc,0x69,0xf6,0x8b,0xc8,0xc7,0x4d,
|
||||
0x6c,0x50,0x96,0x1c,0x8b,0xb4,0xc6,0x45,
|
||||
0x6a,0x60,0x82,0xbc,0xf0,0x75,0xde,0xc3,
|
||||
0x39,0x75,0x68,0xc0,0x8d,0x7c,0xd0,0xf5,
|
||||
0x1d,0xc1,0xb3,0x7a,0x54,0xe2,0x05,0xb3,
|
||||
0xe2,0x57,0xb2,0x0e,0x53,0xda,0x17,0x23,
|
||||
0x8d,0x36,0xd1,0x49,0x18,0x49,0xae,0x4a,
|
||||
0x1a,0x43,0xa2,0x76,0x32,0xcb,0x51,0x44,
|
||||
0x18,0x67,0xae,0xae,0x18,0x1b,0xaf,0xa6,
|
||||
0x1e,0x2b,0xbb,0x06,0x65,0xea,0xa3,0x80,
|
||||
0x36,0xff,0x49,0xfc,0x4b,0xf6,0x47,0xca,
|
||||
0x6f,0x42,0x9c,0x70,0xb6,0xdc,0x49,0x36,
|
||||
0x49,0x4a,0x48,0x42,0x4e,0x72,0x5a,0xd2,
|
||||
0x21,0x13,0x39,0x95,0x6a,0x80,0x80,0xfc,
|
||||
0xfd,0xf5,0xf3,0xc3,0xd7,0x77,0x0c,0xcd,
|
||||
0xd5,0x53,0x00,0x15,0xff,0x83,0xfe,0xf7,
|
||||
0xf9,0xcf,0xeb,0x5f,0x84,0x3e,0xe7,0x79,
|
||||
0xac,0xea,0x15,0x83,0x82,0xf6,0xf1,0xc9,
|
||||
0xdb,0x4b,0x24,0x45,0x26,0x61,0x2a,0xb9,
|
||||
0x00,0x69,0xfe,0x8b,0xf8,0xc7,0xed,0x6f,
|
||||
0x90,0x9e,0x9c,0xb8,0xb4,0x6c,0x46,0x96,
|
||||
0x68,0x8a,0x8c,0xc0,0xd5,0x7d,0x00,0xf1,
|
||||
0xfd,0xdb,0xf3,0x27,0xd5,0x2f,0x01,0x1d,
|
||||
0xf9,0xb3,0xea,0x57,0x82,0x0e,0xf3,0xd9,
|
||||
0xd7,0x2b,0x0d,0x05,0xd1,0xe3,0x1b,0xb5,
|
||||
0xa6,0x42,0x2a,0x73,0x02,0xd5,0xf1,0x03,
|
||||
0xd9,0xf7,0x2b,0xcd,0x07,0x51,0xec,0x1b,
|
||||
0x97,0xa6,0x8e,0x28,0xdb,0x0d,0x25,0xd1,
|
||||
0x23,0x19,0x35,0xa9,0x42,0x08,0x73,0xce,
|
||||
0xd7,0x59,0x0c,0x29,0xd7,0x0b,0x0d,0xc5,
|
||||
0xd3,0x63,0x14,0xb5,0x84,0x42,0xe6,0x71,
|
||||
0xaa,0xda,0x01,0x23,0xf9,0x37,0xe9,0x4f,
|
||||
0x88,0x5e,0xce,0x39,0x5b,0x68,0x24,0x8f,
|
||||
0x24,0xdd,0x25,0x31,0x21,0x59,0x38,0x29,
|
||||
0x6f,0x08,0x9d,0xcc,0xb3,0x54,0x54,0x06,
|
||||
0x07,0xeb,0xef,0x87,0x9e,0xee,0xb9,0x98,
|
||||
0x6a,0xae,0x80,0x18,0xff,0xad,0xfe,0x13,
|
||||
0xfb,0x97,0xe6,0x8f,0xa8,0xde,0x0d,0x3b,
|
||||
0xd1,0x67,0x18,0xad,0xac,0x12,0x17,0x93,
|
||||
0x8e,0x96,0xd8,0x89,0x2c,0xc9,0x15,0x49,
|
||||
0x80,0x4a,0xfe,0x41,0xfa,0x7b,0xe2,0xe7,
|
||||
0xb1,0xae,0x5a,0x1a,0x23,0xa3,0x36,0x35,
|
||||
0x4b,0x40,0x44,0x7e,0x66,0xfa,0xa9,0xe0,
|
||||
0x0b,0xbf,0xc6,0x7f,0x6a,0xfc,0x81,0xf4,
|
||||
0xfb,0xc5,0xe7,0x63,0xac,0xb6,0x14,0x4b,
|
||||
0x86,0x46,0xea,0x69,0x82,0x8a,0xf0,0xc1,
|
||||
0xdd,0x7b,0x30,0xe5,0x5d,0xa0,0x32,0x3f,
|
||||
0x53,0x7c,0x14,0xf7,0x85,0xce,0xe3,0x59,
|
||||
0xb4,0x2a,0x47,0x02,0x6d,0xf2,0x93,0xd0,
|
||||
0x97,0x1c,0x8d,0xb4,0xd2,0x45,0x12,0x61,
|
||||
0x92,0xba,0x90,0x60,0x9e,0xbc,0xb8,0x74,
|
||||
0x6e,0xc6,0x99,0x68,0xa8,0x8c,0x0c,0xd7,
|
||||
0xd5,0x0f,0x01,0xdd,0xfb,0x33,0xe5,0x57,
|
||||
0xa0,0x0e,0x3f,0xdb,0x7f,0x24,0xfd,0x25,
|
||||
0xf1,0x23,0xd9,0x37,0x29,0x4d,0x08,0x51,
|
||||
0xce,0x1b,0x5b,0xa4,0x26,0x27,0x2b,0x2d,
|
||||
0x05,0x11,0xe1,0x9b,0xba,0xa6,0x60,0x2a,
|
||||
0xbf,0x00,0x7d,0xfe,0xf3,0xf9,0xd7,0xeb,
|
||||
0x0f,0x85,0xde,0xe3,0x39,0xb5,0x6a,0x40,
|
||||
0x82,0x7c,0xf2,0xf5,0xd1,0xc3,0x1b,0x75,
|
||||
0xa4,0xc2,0x25,0x73,0x20,0xd5,0x3d,0x01,
|
||||
0x71,0xf8,0xdb,0xed,0x27,0x91,0x2e,0x99,
|
||||
0x18,0xa9,0xac,0x0a,0x17,0xc3,0x8f,0x76,
|
||||
0xdc,0xc9,0x35,0x49,0x40,0x48,0x7e,0x4e,
|
||||
0xfa,0x59,0xe2,0x2b,0xb3,0x06,0x55,0xe2,
|
||||
0x03,0x83,0xf6,0xf7,0xc9,0xcf,0x4b,0x5c,
|
||||
0x04,0x3e,0x67,0x4e,0xac,0x60,0x17,0x7f,
|
||||
0x80,0xfe,0xc1,0xf9,0x7b,0xe8,0xe7,0x87,
|
||||
0xae,0xc2,0x19,0x93,0xfc,0x96,0x08,0x8f,
|
||||
0xc0,0xe7,0xfc,0x2c,0xf0,0x1d,0xcc,0xc3,
|
||||
0x9e,0x70,0x00,0xc0,0x63,0x7f,0x54,0x78,
|
||||
0x40,0xfe,0x61,0x9b,0xf3,0x40,0x64,0x3f,
|
||||
0x0f,0xf8,0x2c,0xf3,0x3f,0x99,0x83,0x2a,
|
||||
0x79,0x07,0xcb,0xe1,0x9f,0xcc,0xce,0x60,
|
||||
0x6c,0x00,0x84,0x7c,0x0f,0xf5,0xe8,0xcf,
|
||||
0x15,0x66,0x80,0xb0,0xf8,0x5d,0xf4,0x33,
|
||||
0x8a,0x57,0x44,0x0c,0x67,0xd6,0xaf,0x08,
|
||||
0x1f,0xcf,0xb3,0x5e,0x54,0x3a,0x07,0x63,
|
||||
0xec,0xb7,0x94,0x4e,0x86,0x58,0xea,0x2d,
|
||||
0x83,0x12,0xf5,0x91,0xc2,0x9b,0x70,0xa4,
|
||||
0xdc,0x25,0x37,0x21,0x4d,0x38,0x51,0x6e,
|
||||
0x18,0x9b,0xac,0xa6,0x14,0x2b,0x87,0x06,
|
||||
0xed,0xe9,0x93,0x8a,0x96,0xc0,0x89,0x7c,
|
||||
0xc8,0xf5,0x4d,0xc0,0x53,0x7e,0x14,0xfb,
|
||||
0x85,0xe6,0xe3,0xa9,0xb6,0x0a,0x4b,0xc2,
|
||||
0x47,0x72,0x6c,0xd2,0x95,0x10,0x81,0x9c,
|
||||
0xfa,0xb5,0xe0,0x43,0xbe,0x76,0x7a,0xca,
|
||||
0xe1,0x41,0xb8,0x7a,0x6e,0xe2,0x99,0xb0,
|
||||
0xaa,0x5c,0x02,0x37,0xf3,0x4f,0xd4,0x5f,
|
||||
0x06,0x3d,0xeb,0x73,0x84,0xd6,0xe5,0x09,
|
||||
0xa1,0xca,0x3b,0x43,0x64,0x74,0xa6,0xc4,
|
||||
0x29,0x67,0x08,0xad,0xcc,0x13,0x57,0x94,
|
||||
0x0e,0x87,0xd8,0xef,0x2d,0x9d,0x12,0xb1,
|
||||
0x90,0x5a,0x9e,0x20,0xbb,0x3c,0x65,0x76,
|
||||
0xa0,0xc8,0x3d,0x4f,0x70,0x5c,0xde,0x35,
|
||||
0x3b,0x41,0x64,0x78,0xa6,0xec,0x29,0x97,
|
||||
0x0a,0x8d,0xc0,0xd3,0x7d,0x14,0xf1,0x85,
|
||||
0xda,0xe3,0x21,0xb5,0x3a,0x41,0x62,0x78,
|
||||
0xb2,0xec,0x51,0x96,0x1a,0x8b,0xa0,0xc6,
|
||||
0x3d,0x6b,0x70,0x84,0xdc,0xe5,0x35,0xa1,
|
||||
0x42,0x38,0x73,0x6e,0xd4,0x99,0x04,0xa9,
|
||||
0xe4,0x0b,0xa7,0xc6,0x2f,0x6b,0x1c,0x85,
|
||||
0xb4,0xe2,0x45,0xb2,0x62,0x52,0xb2,0x10,
|
||||
0x53,0x9e,0x16,0xbb,0x88,0x66,0xce,0xa9,
|
||||
0x58,0x08,0x2f,0xcf,0x1f,0x5d,0xbc,0x32,
|
||||
0x77,0x52,0xcc,0x11,0x57,0x98,0x0e,0xaf,
|
||||
0xd8,0x1f,0x2f,0xbd,0x1e,0x71,0xba,0xda,
|
||||
0x61,0x22,0xb9,0x30,0x69,0x5e,0x88,0x38,
|
||||
0xcf,0x6d,0x5c,0x90,0x34,0x9f,0x44,0xbc,
|
||||
0x64,0x76,0xa6,0xc8,0x29,0x4f,0x08,0x5d,
|
||||
0xce,0x33,0x5b,0x54,0x24,0x07,0x27,0xed,
|
||||
0x2f,0x91,0x1e,0x99,0xb8,0xaa,0x6c,0x02,
|
||||
0x97,0xf0,0x8f,0xdc,0xdf,0x35,0x3d,0x41,
|
||||
0x70,0x78,0xde,0xed,0x39,0x91,0x6a,0x98,
|
||||
0x80,0xac,0xfc,0x15,0xf7,0x83,0xce,0xf7,
|
||||
0x59,0xcc,0x2b,0x57,0x04,0x0d,0xe7,0xd3,
|
||||
0xaf,0x16,0x1d,0x8b,0xb2,0xc6,0x51,0x6a,
|
||||
0x18,0x83,0xac,0xf6,0x15,0xcb,0x83,0x46,
|
||||
0xf4,0x69,0xc6,0x8b,0x68,0xc4,0x8d,0x64,
|
||||
0xd0,0xa5,0x1c,0x21,0xb7,0x3a,0x4d,0x62,
|
||||
0x50,0xb2,0x1c,0x53,0xb6,0x16,0x4b,0x8a,
|
||||
0x46,0xc2,0x69,0x72,0x88,0xd0,0xcd,0x1d,
|
||||
0x51,0xb0,0x1a,0x5f,0xa2,0x3e,0x33,0x7b,
|
||||
0x54,0xe4,0x05,0xa7,0xe2,0x2f,0xb3,0x1e,
|
||||
0x55,0xba,0x02,0x63,0xf2,0xb7,0xd0,0x4f,
|
||||
0x1e,0x5d,0xba,0x32,0x63,0x52,0xb4,0x10,
|
||||
0x47,0x9e,0x6e,0xba,0x98,0x60,0xae,0xbc,
|
||||
0x18,0x77,0xae,0xce,0x19,0x5b,0xa8,0x26,
|
||||
0x0f,0x2b,0xdd,0x07,0x31,0xed,0x5b,0x90,
|
||||
0x26,0x9f,0x28,0xbd,0x0c,0x71,0xd6,0xdb,
|
||||
0x09,0x25,0xc9,0x23,0x49,0x34,0x49,0x46,
|
||||
0x48,0x6a,0x4e,0x82,0x58,0xf2,0x2d,0xd3,
|
||||
0x13,0x15,0x95,0x82,0x82,0xf0,0xf1,0xdd,
|
||||
0xdb,0x33,0x25,0x55,0x20,0x01,0x3f,0xf9,
|
||||
0x7f,0xe8,0xff,0x8d,0xfe,0xd3,0xf9,0x17,
|
||||
0xe9,0x8f,0x8a,0xde,0xc1,0x39,0x79,0x68,
|
||||
0xe8,0x8d,0x8c,0xd2,0xd5,0x11,0x01,0x99,
|
||||
0xfa,0xab,0xe0,0x07,0xbf,0xee,0x7f,0x9a,
|
||||
0xfe,0xa1,0xf8,0x3b,0xef,0x67,0x9c,0xae,
|
||||
0xb4,0x18,0x47,0xae,0x6e,0x1a,0x9b,0xa0,
|
||||
0xa6,0x3c,0x2b,0x77,0x04,0xcd,0xe5,0x53,
|
||||
0xa0,0x16,0x3f,0x8b,0x7e,0xc4,0xf9,0x65,
|
||||
0xe8,0xa3,0x8c,0x36,0xd7,0x49,0x0c,0x49,
|
||||
0xd6,0x4b,0x0a,0x45,0xc2,0x63,0x72,0xb4,
|
||||
0xd0,0x45,0x1e,0x61,0xba,0xba,0x60,0x62,
|
||||
0xbe,0xb0,0x78,0x5e,0xee,0x39,0x9b,0x6a,
|
||||
0xa4,0x80,0x24,0xff,0x25,0xfd,0x23,0xf1,
|
||||
0x37,0xd9,0x4f,0x28,0x5d,0x0e,0x31,0xdb,
|
||||
0x5b,0x24,0x25,0x27,0x21,0x2d,0x39,0x11,
|
||||
0x69,0x98,0x8a,0xac,0xc0,0x15,0x7f,0x80,
|
||||
0xfe,0xfd,0xf9,0xf3,0xeb,0xd7,0x87,0x0e,
|
||||
0xed,0xd9,0x93,0x2a,0x95,0x00,0x81,0xfc,
|
||||
0xfb,0xf5,0xe7,0xc3,0xaf,0x76,0x1c,0xcb,
|
||||
0xb5,0x46,0x40,0x6a,0x7e,0x82,0xf8,0xf1,
|
||||
0xed,0xdb,0x93,0x26,0x95,0x28,0x81,0x0c,
|
||||
0xf9,0xd5,0xeb,0x03,0x85,0xf6,0xe3,0xc9,
|
||||
0xb7,0x4a,0x4c,0x42,0x56,0x72,0x0a,0xd3,
|
||||
0xc1,0x17,0x79,0x8c,0xea,0xd5,0x81,0x02,
|
||||
0xf9,0xf1,0xeb,0xdb,0x87,0x26,0xed,0x29,
|
||||
0x91,0x0a,0x99,0xc0,0xab,0x7c,0x04,0xf7,
|
||||
0xe5,0xcf,0xa3,0x5e,0x34,0x3b,0x47,0x64,
|
||||
0x6c,0xa6,0x94,0x28,0x87,0x0c,0xed,0xd5,
|
||||
0x93,0x02,0x95,0xf0,0x83,0xdc,0xf7,0x35,
|
||||
0xcd,0x43,0x50,0x74,0x1e,0xc7,0xb9,0x6e,
|
||||
0x68,0x9a,0x8c,0xa0,0xd4,0x3d,0x07,0x71,
|
||||
0xec,0xdb,0x95,0x26,0x81,0x28,0xf9,0x0d,
|
||||
0xe9,0xd3,0x8b,0x16,0xc5,0x89,0x62,0xc8,
|
||||
0xb1,0x4c,0x58,0x56,0x2e,0x0b,0x1b,0xc5,
|
||||
0xa7,0x62,0x2c,0xb3,0x14,0x55,0x86,0x02,
|
||||
0xeb,0xf1,0x87,0xda,0xef,0x21,0x9d,0x3a,
|
||||
0xb1,0x60,0x58,0xbe,0x2c,0x7b,0x16,0xe5,
|
||||
0x89,0xa2,0xca,0x31,0x43,0x58,0x74,0x2e,
|
||||
0xc7,0x19,0x6d,0xa8,0x92,0x0c,0x93,0xd4,
|
||||
0x97,0x04,0x8d,0xe4,0xd3,0xa5,0x16,0x21,
|
||||
0x8b,0x3a,0xc5,0x61,0x60,0xb8,0xbc,0x6c,
|
||||
0x76,0x96,0xc8,0x89,0x4c,0xc8,0x55,0x4e,
|
||||
0x00,0x5b,0xfe,0x27,0xfb,0x2f,0xe5,0x1f,
|
||||
0xa1,0xbe,0x3a,0x7b,0x62,0xe4,0xb1,0xa4,
|
||||
0x5a,0x26,0x23,0x2b,0x35,0x05,0x41,0xe0,
|
||||
0x7b,0xbe,0xe6,0x79,0xaa,0xea,0x01,0x83,
|
||||
0xfa,0xf7,0xe1,0xcf,0xbb,0x5e,0x64,0x3a,
|
||||
0xa7,0x60,0x2c,0xbf,0x14,0x7d,0x86,0xf2,
|
||||
0xe9,0xd1,0x8b,0x1a,0xc5,0xa1,0x62,0x38,
|
||||
0xb3,0x6c,0x54,0x96,0x04,0x8b,0xe4,0xc7,
|
||||
0xa5,0x6e,0x20,0x9b,0x3c,0xa5,0x74,0x20,
|
||||
0xc7,0x3d,0x6d,0x70,0x90,0xdc,0x9d,0x34,
|
||||
0xb1,0x44,0x58,0x66,0x2e,0xab,0x18,0x05,
|
||||
0xaf,0xe2,0x1f,0xb3,0xbe,0x56,0x7a,0x0a,
|
||||
0xe3,0xc1,0xb7,0x7a,0x4c,0xe2,0x55,0xb2,
|
||||
0x02,0x53,0xf2,0x17,0xd3,0x8f,0x16,0xdd,
|
||||
0x89,0x32,0xc9,0x51,0x48,0x18,0x4f,0xae,
|
||||
0x5e,0x1a,0x3b,0xa3,0x66,0x34,0xab,0x44,
|
||||
0x04,0x67,0xe6,0xaf,0xa8,0x1e,0x0f,0xbb,
|
||||
0xde,0x67,0x3a,0xad,0x60,0x10,0xbf,0x9c,
|
||||
0x7e,0xb6,0xf8,0x49,0xee,0x4b,0x9a,0x46,
|
||||
0xa2,0x68,0x32,0x8f,0x50,0xdc,0x1d,0x37,
|
||||
0xb1,0x4e,0x58,0x5a,0x2e,0x23,0x1b,0x35,
|
||||
0xa5,0x42,0x20,0x73,0x3e,0xd5,0x79,0x00,
|
||||
0xe9,0xfd,0x8b,0xf2,0xc7,0xd1,0x6f,0x18,
|
||||
0x9d,0xac,0xb2,0x14,0x53,0x86,0x16,0xeb,
|
||||
0x89,0x86,0xca,0xe9,0x41,0x88,0x7a,0xce,
|
||||
0xe1,0x59,0xb8,0x2a,0x6f,0x02,0x9d,0xf0,
|
||||
0xb3,0xdc,0x57,0x36,0x0d,0x4b,0xd0,0x47,
|
||||
0x1e,0x6d,0xba,0x92,0x60,0x92,0xbc,0x90,
|
||||
0x74,0x9e,0xc4,0xb9,0x64,0x68,0xa6,0x8c,
|
||||
0x28,0xd7,0x0d,0x0d,0xd1,0xd3,0x1b,0x15,
|
||||
0xa5,0x82,0x22,0xf3,0x31,0xd5,0x5b,0x00,
|
||||
0x25,0xff,0x23,0xfd,0x37,0xf1,0x4f,0xd8,
|
||||
0x5f,0x2e,0x3d,0x1b,0x71,0xa4,0xda,0x25,
|
||||
0x23,0x21,0x35,0x39,0x41,0x68,0x78,0x8e,
|
||||
0xec,0xd9,0x95,0x2a,0x81,0x00,0xf9,0xfd,
|
||||
0xeb,0xf3,0x87,0xd6,0xef,0x09,0x9d,0xca,
|
||||
0xb3,0x40,0x54,0x7e,0x06,0xfb,0xe9,0xe7,
|
||||
0x8b,0xae,0xc6,0x19,0x6b,0xa8,0x86,0x0c,
|
||||
0xeb,0xd5,0x87,0x02,0xed,0xf1,0x93,0xda,
|
||||
0x97,0x20,0x8d,0x3c,0xd1,0x75,0x18,0xc1,
|
||||
0xad,0x7a,0x10,0xe3,0x9d,0xb6,0xb2,0x48,
|
||||
0x52,0x4e,0x12,0x5b,0x92,0x26,0x93,0x28,
|
||||
0x95,0x0c,0x81,0xd4,0xfb,0x05,0xe5,0xe3,
|
||||
0xa3,0xb6,0x36,0x4b,0x4a,0x44,0x42,0x66,
|
||||
0x72,0xaa,0xd0,0x01,0x1f,0xf9,0xbf,0xea,
|
||||
0x7f,0x82,0xfe,0xf1,0xf9,0xdb,0xeb,0x27,
|
||||
0x85,0x2e,0xe1,0x19,0xb9,0xaa,0x6a,0x02,
|
||||
0x83,0xf0,0xf7,0xdd,0xcf,0x33,0x5d,0x54,
|
||||
0x30,0x07,0x5f,0xec,0x3f,0x97,0x7e,0x8c,
|
||||
0xf8,0xd5,0xed,0x03,0x91,0xf6,0x9b,0xc8,
|
||||
0xa7,0x4c,0x2c,0x57,0x16,0x0d,0x8b,0xd2,
|
||||
0xc7,0x11,0x6d,0x98,0x92,0xac,0x90,0x14,
|
||||
0x9f,0x84,0xbe,0xe4,0x79,0xa6,0xea,0x29,
|
||||
0x83,0x0a,0xf5,0xc1,0xc3,0x7b,0x74,0xe4,
|
||||
0xc5,0xa5,0x62,0x20,0xb3,0x3c,0x55,0x76,
|
||||
0x00,0xcb,0xfd,0x47,0xf0,0x6f,0xde,0x9f,
|
||||
0x38,0xbd,0x6c,0x70,0x96,0xdc,0x89,0x34,
|
||||
0xc9,0x45,0x48,0x60,0x4e,0xbe,0x58,0x7a,
|
||||
0x2e,0xe3,0x19,0xb5,0xaa,0x42,0x02,0x73,
|
||||
0xf2,0xd7,0xd1,0x0f,0x19,0xdd,0xab,0x32,
|
||||
0x05,0x53,0xe0,0x17,0xbf,0x8e,0x7e,0xda,
|
||||
0xf9,0x21,0xe9,0x3b,0x89,0x66,0xc8,0xa9,
|
||||
0x4c,0x08,0x57,0xce,0x0f,0x5b,0xdc,0x27,
|
||||
0x37,0x2d,0x4d,0x10,0x51,0x9e,0x1a,0xbb,
|
||||
0xa0,0x66,0x3e,0xab,0x78,0x04,0xef,0xe5,
|
||||
0x9f,0xa2,0xbe,0x30,0x7b,0x5e,0xe4,0x39,
|
||||
0xa7,0x6a,0x2c,0x83,0x14,0xf5,0x85,0xc2,
|
||||
0xe3,0x71,0xb4,0xda,0x45,0x22,0x61,0x32,
|
||||
0xb9,0x50,0x68,0x1e,0x8f,0xb8,0xde,0x6d,
|
||||
0x3a,0x91,0x60,0x98,0xbc,0xac,0x74,0x16,
|
||||
0xc7,0x89,0x6e,0xc8,0x99,0x4c,0xa8,0x54,
|
||||
0x0e,0x07,0xdb,0xef,0x27,0x9d,0x2e,0xb1,
|
||||
0x18,0x59,0xae,0x2a,0x1b,0x03,0xa5,0xf6,
|
||||
0x23,0xcb,0x37,0x45,0x4c,0x60,0x56,0xbe,
|
||||
0x08,0x7b,0xce,0xe7,0x59,0xac,0x2a,0x17,
|
||||
0x03,0x8d,0xf6,0xd3,0xc9,0x17,0x49,0x8c,
|
||||
0x4a,0xd6,0x41,0x0a,0x79,0xc2,0xeb,0x71,
|
||||
0x84,0xda,0xe5,0x21,0xa1,0x3a,0x39,0x63,
|
||||
0x68,0xb4,0x8c,0x44,0xd6,0x65,0x0a,0xa1,
|
||||
0xc0,0x3b,0x7f,0x64,0xfc,0xa5,0xf4,0x23,
|
||||
0xc7,0x37,0x6d,0x4c,0x90,0x54,0x9e,0x04,
|
||||
0xbb,0xe4,0x67,0xa6,0xae,0x28,0x1b,0x0f,
|
||||
0xa5,0xde,0x23,0x3b,0x35,0x65,0x40,0xa0,
|
||||
0x7c,0x3e,0xf7,0x79,0xcc,0xeb,0x55,0x84,
|
||||
0x02,0xe7,0xf1,0xaf,0xda,0x1f,0x23,0xbd,
|
||||
0x36,0x71,0x4a,0xd8,0x41,0x2e,0x79,0x1a,
|
||||
0xe9,0xa1,0x8a,0x3a,0xc3,0x61,0x74,0xb8,
|
||||
0xc4,0x6d,0x66,0x90,0xa8,0x9c,0x0c,0xb7,
|
||||
0xd4,0x4f,0x06,0x5d,0xea,0x33,0x83,0x56,
|
||||
0xf4,0x09,0xc7,0xcb,0x6f,0x44,0x9c,0x64,
|
||||
0xb6,0xa4,0x48,0x26,0x4f,0x2a,0x5d,0x02,
|
||||
0x31,0xf3,0x5b,0xd4,0x27,0x07,0x2d,0xed,
|
||||
0x13,0x91,0x96,0x9a,0x88,0xa0,0xcc,0x3d,
|
||||
0x57,0x70,0x0c,0xdf,0xd5,0x3f,0x01,0x7d,
|
||||
0xf8,0xf3,0xed,0xd7,0x93,0x0e,0x95,0xd8,
|
||||
0x83,0x2c,0xf5,0x15,0xc1,0x83,0x7a,0xf4,
|
||||
0xe1,0xc5,0xbb,0x62,0x64,0xb2,0xa4,0x50,
|
||||
0x26,0x1f,0x2b,0xbd,0x06,0x71,0xea,0xdb,
|
||||
0x81,0x26,0xf9,0x29,0xe9,0x0b,0x89,0xc6,
|
||||
0xcb,0x69,0x44,0x88,0x64,0xce,0xa5,0x58,
|
||||
0x20,0x2f,0x3f,0x1d,0x7d,0xb0,0xf2,0x5d,
|
||||
0xd2,0x33,0x13,0x55,0x94,0x02,0x87,0xf0,
|
||||
0xef,0xdd,0x9f,0x32,0xbd,0x50,0x70,0x1e,
|
||||
0xdf,0xb9,0x3e,0x69,0x7a,0x88,0xe0,0xcd,
|
||||
0xbd,0x52,0x70,0x12,0xdf,0x91,0x3e,0x99,
|
||||
0x78,0xa8,0xec,0x0d,0x97,0xd2,0x8f,0x10,
|
||||
0xdd,0x9d,0x32,0xb1,0x50,0x58,0x1e,0x2f,
|
||||
0xbb,0x1e,0x65,0xba,0xa2,0x60,0x32,0xbf,
|
||||
0x50,0x7c,0x1e,0xf7,0xb9,0xce,0x6b,0x5a,
|
||||
0x84,0x20,0xe7,0x3d,0xad,0x72,0x10,0xd3,
|
||||
0x9d,0x16,0xb1,0x88,0x5a,0xce,0x21,0x5b,
|
||||
0x38,0x25,0x6f,0x20,0x9d,0x3c,0xb1,0x74,
|
||||
0x58,0xc6,0x2d,0x6b,0x10,0x85,0x9c,0xe2,
|
||||
0xb5,0xb0,0x42,0x5e,0x72,0x3a,0xd3,0x61,
|
||||
0x14,0xb9,0x84,0x6a,0xe6,0x81,0xa8,0xfa,
|
||||
0x0d,0xe3,0xd3,0xb7,0x16,0x4d,0x8a,0x52,
|
||||
0xc2,0x11,0x73,0x98,0xd6,0xad,0x08,0x11,
|
||||
0xcf,0x9b,0x5e,0xa4,0x38,0x27,0x6f,0x2c,
|
||||
0x9d,0x14,0xb1,0x84,0x5a,0xe6,0x21,0xab,
|
||||
0x3a,0x05,0x63,0xe0,0xb7,0xbc,0x4e,0x76,
|
||||
0x5a,0xca,0x21,0x43,0x38,0x75,0x6e,0xc0,
|
||||
0x99,0x7c,0xa8,0xf4,0x0d,0xc7,0xd3,0x6f,
|
||||
0x14,0x9d,0x84,0xb2,0xe4,0x51,0xa6,0x1a,
|
||||
0x2b,0xa3,0x06,0x35,0xeb,0x43,0x84,0x76,
|
||||
0xe6,0xc9,0xa9,0x4a,0x08,0x43,0xce,0x77,
|
||||
0x5a,0xcc,0x21,0x57,0x38,0x0d,0x6f,0xd0,
|
||||
0x9f,0x1c,0xbd,0xb4,0x72,0x46,0xd2,0x69,
|
||||
0x12,0x89,0x90,0xca,0x9d,0x40,0xb0,0x7c,
|
||||
0x5e,0xf6,0x39,0xcb,0x6b,0x44,0x84,0x64,
|
||||
0xe6,0xa5,0xa8,0x22,0x0f,0x33,0xdd,0x57,
|
||||
0x30,0x0d,0x5f,0xd0,0x3f,0x1f,0x7d,0xbc,
|
||||
0xf2,0x75,0xd2,0xc3,0x11,0x75,0x98,0xc2,
|
||||
0xad,0x70,0x10,0xdf,0x9d,0x3e,0xb1,0x78,
|
||||
0x58,0xee,0x2d,0x9b,0x12,0xa5,0x90,0x22,
|
||||
0x9f,0x30,0xbd,0x5c,0x70,0x36,0xdf,0x49,
|
||||
0x3c,0x49,0x76,0x48,0xca,0x4d,0x42,0x50,
|
||||
0x72,0x1e,0xd3,0xb9,0x16,0x69,0x8a,0x8a,
|
||||
0xc0,0xc1,0x7d,0x78,0xf0,0xed,0xdd,0x93,
|
||||
0x32,0x95,0x50,0x80,0x1c,0xff,0xb5,0xfe,
|
||||
0x43,0xfa,0x77,0xe2,0xcf,0xb1,0x5e,0x58,
|
||||
0x3a,0x2f,0x63,0x1c,0xb5,0xb4,0x42,0x46,
|
||||
0x72,0x6a,0xd2,0x81,0x10,0xf9,0x9d,0xea,
|
||||
0xb3,0x80,0x56,0xfe,0x09,0xfb,0xcb,0xe7,
|
||||
0x47,0xac,0x6e,0x16,0x9b,0x88,0xa6,0xcc,
|
||||
0x29,0x57,0x08,0x0d,0xcf,0xd3,0x5f,0x14,
|
||||
0x3d,0x87,0x72,0xec,0xd1,0x95,0x1a,0x81,
|
||||
0xa0,0xfa,0x3d,0xe3,0x73,0xb4,0xd6,0x45,
|
||||
0x0a,0x61,0xc2,0xbb,0x70,0x64,0xde,0xa5,
|
||||
0x38,0x21,0x6f,0x38,0x9d,0x6c,0xb0,0x94,
|
||||
0x5c,0x86,0x3e,0xeb,0x45,0x84,0x62,0xe6,
|
||||
0xb1,0xa8,0x5a,0x0e,0x23,0xfb,0x33,0x25,
|
||||
0x47,0x20,0x51,0x3e,0x19,0x7f,0xa8,0x66,
|
||||
0x0c,0xfb,0xd0,0x07,0x13,0xe5,0x9f,0x83,
|
||||
0xce,0x98,0x58,0xcd,0x2e,0x19,0x14,0x39,
|
||||
0x86,0x3f,0xff,0x01,0x85,0xff,0xe1,0xe1,
|
||||
0xb3,0xfc,0x46,0x63,0x0f,0xf8,0x00,0x53,
|
||||
0xbe,0x1f,0xfb,0xc0,0xe6,0x7e,0xbc,0xf0,
|
||||
0x01,0xe3,0xc3,0x9f,0xa6,0xcc,0x48,0x7e,
|
||||
0x40,0x82,0x9d,0xf2,0xff,0xd6,0x07,0x13,
|
||||
0xf5,0x87,0x80,0x0f,0x71,0x9c,0xfd,0x35,
|
||||
0x61,0x43,0xf8,0x78,0x7e,0xcf,0x19,0x99,
|
||||
0xa8,0x32,0x00,0x53,0xfc,0x17,0xfb,0x8f,
|
||||
0xc6,0xdf,0xa9,0x3e,0x09,0x7b,0xc8,0xe7,
|
||||
0x4d,0xac,0x52,0x16,0x13,0x8b,0x96,0xc6,
|
||||
0x89,0x68,0xc8,0x8d,0x4c,0xd0,0x55,0x1e,
|
||||
0x01,0xbb,0xfa,0x67,0xe2,0xaf,0xb0,0x1e,
|
||||
0x5f,0xba,0x3e,0x63,0x7a,0xb4,0xe0,0x45,
|
||||
0xbe,0x62,0x7a,0xb2,0xe0,0x51,0xbe,0x1a,
|
||||
0x7b,0xa2,0xe6,0x31,0xab,0x5a,0x04,0x23,
|
||||
0xe7,0x37,0xad,0x4e,0x10,0x5b,0x9e,0x26,
|
||||
0xbb,0x28,0x65,0x0e,0xa1,0xd8,0x3b,0x2f,
|
||||
0x65,0x1c,0xa1,0xb4,0x3a,0x47,0x62,0x6c,
|
||||
0xb2,0x94,0x50,0x86,0x1c,0xeb,0xb5,0x86,
|
||||
0x42,0xea,0x71,0x82,0xda,0xf1,0x21,0xd9,
|
||||
0x3b,0x29,0x65,0x08,0xa1,0xcc,0x3b,0x57,
|
||||
0x64,0x0c,0xa7,0xd4,0x2f,0x07,0x1d,0xed,
|
||||
0xb3,0x92,0x56,0x92,0x08,0x93,0xcc,0x97,
|
||||
0x54,0x8c,0x04,0xd7,0xe5,0x0f,0xa1,0xde,
|
||||
0x3b,0x3b,0x65,0x64,0xa0,0xa4,0x3c,0x27,
|
||||
0x77,0x2c,0xcd,0x15,0x51,0x80,0x1a,0xff,
|
||||
0xa1,0xfe,0x3b,0xfb,0x67,0xe4,0xaf,0xa4,
|
||||
0x1e,0x27,0xbb,0x2e,0x65,0x1a,0xa1,0xa0,
|
||||
0x3a,0x3f,0x63,0x7c,0xb4,0xf4,0x45,0xc6,
|
||||
0x63,0x6a,0xb4,0x80,0x44,0xfe,0x65,0xfa,
|
||||
0xa3,0xe0,0x37,0xbf,0x4e,0x7c,0x5a,0xf6,
|
||||
0x21,0xcb,0x3b,0x45,0x64,0x60,0xa6,0xbc,
|
||||
0x28,0x77,0x0e,0xcd,0xd9,0x53,0x28,0x15,
|
||||
0x0f,0x81,0xde,0xfb,0x39,0xe5,0x6b,0xa0,
|
||||
0x86,0x3c,0xeb,0x75,0x84,0xc2,0xe5,0x71,
|
||||
0xa0,0xda,0x3d,0x23,0x71,0x34,0xd9,0x45,
|
||||
0x28,0x61,0x0e,0xb9,0xd8,0x6b,0x2e,0x85,
|
||||
0x18,0xe1,0xad,0xba,0x12,0x63,0x92,0xb6,
|
||||
0x90,0x48,0x9e,0x4c,0xba,0x54,0x62,0x06,
|
||||
0xb3,0xe8,0x57,0x8e,0x0e,0xdb,0xd9,0x27,
|
||||
0x29,0x2d,0x09,0x11,0xc9,0x9b,0x4a,0xa4,
|
||||
0x40,0x26,0x7f,0x2a,0xfd,0x01,0xf1,0xfb,
|
||||
0xdb,0xe7,0x27,0xad,0x2e,0x11,0x1b,0x99,
|
||||
0xa6,0xaa,0x28,0x03,0x0f,0xf5,0xdf,0xc3,
|
||||
0x3f,0x75,0x7c,0xc0,0xf5,0x7d,0xc0,0xf3,
|
||||
0x7d,0xd4,0xf3,0x05,0xd5,0xe3,0x03,0xb5,
|
||||
0xf6,0x43,0xca,0x77,0x42,0xcc,0x71,0x56,
|
||||
0xd8,0x09,0x2f,0xc9,0x1f,0x49,0xbc,0x4a,
|
||||
0x76,0x42,0xca,0x71,0x42,0xd8,0x71,0x2e,
|
||||
0xd9,0x19,0x29,0xa9,0x0a,0x09,0xc3,0xcb,
|
||||
0x77,0x44,0xcc,0x65,0x56,0xa0,0x08,0x3f,
|
||||
0xcf,0x7f,0x5c,0xfc,0x35,0xf7,0x43,0xcc,
|
||||
0x77,0x56,0xcc,0x09,0x57,0xc8,0x0f,0x4f,
|
||||
0xdc,0x5f,0x36,0x3d,0x4b,0x70,0x44,0xde,
|
||||
0x65,0x3a,0xa1,0x60,0x38,0xbf,0x6c,0x7c,
|
||||
0x96,0xf4,0x89,0xc4,0xcb,0x65,0x44,0xa0,
|
||||
0x64,0x3e,0xa7,0x78,0x2c,0xef,0x15,0x9d,
|
||||
0x82,0xb2,0xf0,0x51,0xde,0x1b,0x3b,0xa5,
|
||||
0x66,0x20,0xab,0x3c,0x05,0x77,0xe0,0xcf,
|
||||
0xbd,0x5e,0x70,0x3a,0xdf,0x61,0x3c,0xb9,
|
||||
0x74,0x68,0xc6,0x8d,0x68,0xd0,0x8d,0x1c,
|
||||
0xd1,0xb5,0x1a,0x41,0xa2,0x7a,0x32,0xe3,
|
||||
0x51,0xb4,0x1a,0x47,0xa2,0x6e,0x32,0x9b,
|
||||
0x50,0xa4,0x1c,0x27,0xb7,0x2e,0x4d,0x1a,
|
||||
0x51,0xa2,0x1a,0x33,0xa3,0x56,0x34,0x0b,
|
||||
0x47,0xc4,0x6f,0x66,0x9c,0xa8,0xb4,0x0c,
|
||||
0x47,0xd6,0x6f,0x0a,0x9d,0xc0,0xb3,0x7c,
|
||||
0x54,0xf6,0x05,0xcb,0xe3,0x47,0xb4,0x6e,
|
||||
0x46,0x9a,0x68,0xa2,0x8c,0x30,0xd7,0x5d,
|
||||
0x0c,0x31,0xd7,0x5b,0x0c,0x25,0xd7,0x23,
|
||||
0x0d,0x35,0xd1,0x43,0x18,0x75,0xae,0xc2,
|
||||
0x19,0x73,0xa8,0xd6,0x0d,0x0b,0xd1,0xc7,
|
||||
0x1b,0x6d,0xa4,0x92,0x24,0x93,0x24,0x95,
|
||||
0x24,0x81,0x24,0xf9,0x25,0xe9,0x23,0x89,
|
||||
0x36,0xc9,0x49,0x48,0x48,0x4e,0x4e,0x5a,
|
||||
0x5a,0x22,0x23,0x33,0x35,0x55,0x40,0x00,
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
43
apps/plugins/rockboy/nosound.c
Normal file
43
apps/plugins/rockboy/nosound.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
|
||||
|
||||
|
||||
#include "rockmacros.h"
|
||||
#include "defs.h"
|
||||
#include "pcm.h"
|
||||
#include "rc.h"
|
||||
|
||||
|
||||
struct pcm pcm;
|
||||
|
||||
static byte buf[4096];
|
||||
|
||||
|
||||
rcvar_t pcm_exports[] =
|
||||
{
|
||||
RCV_END
|
||||
};
|
||||
|
||||
|
||||
void pcm_init(void)
|
||||
{
|
||||
pcm.hz = 11025;
|
||||
pcm.buf = buf;
|
||||
pcm.len = sizeof buf;
|
||||
pcm.pos = 0;
|
||||
}
|
||||
|
||||
void pcm_close(void)
|
||||
{
|
||||
memset(&pcm, 0, sizeof pcm);
|
||||
}
|
||||
|
||||
int pcm_submit(void)
|
||||
{
|
||||
pcm.pos = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
153
apps/plugins/rockboy/palette.c
Normal file
153
apps/plugins/rockboy/palette.c
Normal file
|
@ -0,0 +1,153 @@
|
|||
|
||||
|
||||
#include "rockmacros.h"
|
||||
#include "defs.h"
|
||||
#include "fb.h"
|
||||
#include "palette.h"
|
||||
|
||||
|
||||
static byte palmap[32768];
|
||||
static byte pallock[256];
|
||||
static int palrev[256];
|
||||
|
||||
/* Course color mapping, for when palette is exhausted. */
|
||||
static byte crsmap[4][32768];
|
||||
static int crsrev[4][256];
|
||||
static const int crsmask[4] = { 0x7BDE, 0x739C, 0x6318, 0x4210 };
|
||||
|
||||
enum plstatus
|
||||
{
|
||||
pl_unused = 0,
|
||||
pl_linger,
|
||||
pl_active,
|
||||
pl_locked
|
||||
};
|
||||
|
||||
/*
|
||||
static byte bestmatch(int c)
|
||||
{
|
||||
byte n, best;
|
||||
int r, g, b;
|
||||
int r2, g2, b2, c2;
|
||||
int err, besterr;
|
||||
|
||||
r = (c & 0x001F) << 3;
|
||||
g = (c & 0x03E0) >> 2;
|
||||
b = (c & 0x7C00) >> 7;
|
||||
|
||||
best = 0;
|
||||
besterr = 1024;
|
||||
for (n = 1; n; n++)
|
||||
{
|
||||
c2 = palrev[n];
|
||||
r2 = (c2 & 0x001F) << 3;
|
||||
g2 = (c2 & 0x03E0) >> 2;
|
||||
b2 = (c2 & 0x7C00) >> 7;
|
||||
err = abs(r-r2) + abs(b-b2) + abs(g-g2);
|
||||
if (err < besterr)
|
||||
{
|
||||
besterr = err;
|
||||
best = n;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
*/
|
||||
|
||||
static void makecourse(int c, byte n)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
c &= crsmask[i];
|
||||
crsmap[i][c] = n;
|
||||
crsrev[i][n] = c;
|
||||
}
|
||||
}
|
||||
|
||||
static byte findcourse(int c)
|
||||
{
|
||||
int i;
|
||||
byte n;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
c &= crsmask[i];
|
||||
n = crsmap[i][c];
|
||||
if (crsrev[i][n] == c)
|
||||
return n;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void pal_lock(byte n)
|
||||
{
|
||||
if (!n) return;
|
||||
if (pallock[n] >= pl_locked)
|
||||
pallock[n]++;
|
||||
else pallock[n] = pl_locked;
|
||||
}
|
||||
|
||||
byte pal_getcolor(int c, int r, int g, int b)
|
||||
{
|
||||
byte n;
|
||||
static byte l;
|
||||
n = palmap[c];
|
||||
if (n && pallock[n] && palrev[n] == c)
|
||||
{
|
||||
pal_lock(n);
|
||||
return n;
|
||||
}
|
||||
for (n = l+1; n != l; n++)
|
||||
{
|
||||
if (!n || pallock[n] /* || n < 16 */) continue;
|
||||
pal_lock(n);
|
||||
palmap[c] = n;
|
||||
palrev[n] = c;
|
||||
makecourse(c, n);
|
||||
vid_setpal(n, r, g, b);
|
||||
return (l = n);
|
||||
}
|
||||
n = findcourse(c);
|
||||
pal_lock(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
void pal_release(byte n)
|
||||
{
|
||||
if (pallock[n] >= pl_locked)
|
||||
pallock[n]--;
|
||||
}
|
||||
|
||||
|
||||
void pal_expire(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 256; i++)
|
||||
if (pallock[i] && pallock[i] < pl_locked)
|
||||
pallock[i]--;
|
||||
}
|
||||
|
||||
|
||||
void pal_set332(void)
|
||||
{
|
||||
int i, r, g, b;
|
||||
|
||||
fb.indexed = 0;
|
||||
fb.cc[0].r = 5;
|
||||
fb.cc[1].r = 5;
|
||||
fb.cc[2].r = 6;
|
||||
fb.cc[0].l = 0;
|
||||
fb.cc[1].l = 3;
|
||||
fb.cc[2].l = 6;
|
||||
|
||||
i = 0;
|
||||
for (b = 0; b < 4; b++) for (g = 0; g < 8; g++) for (r = 0; r < 8; r++)
|
||||
vid_setpal(i++, (r<<5)|(r<<2)|(r>>1),
|
||||
(g<<5)|(g<<2)|(g>>1), (b<<6)|(b<<4)|(b<<2)|b);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
6
apps/plugins/rockboy/palette.h
Normal file
6
apps/plugins/rockboy/palette.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
void pal_lock(byte n);
|
||||
byte pal_getcolor(int c, int r, int g, int b);
|
||||
void pal_release(byte n);
|
||||
void pal_expire(void);
|
||||
void pal_set332(void);
|
||||
void vid_setpal(int i, int r, int g, int b);
|
21
apps/plugins/rockboy/pcm.h
Normal file
21
apps/plugins/rockboy/pcm.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
|
||||
#ifndef __PCM_H__
|
||||
#define __PCM_H__
|
||||
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
struct pcm
|
||||
{
|
||||
int hz, len;
|
||||
int stereo;
|
||||
byte *buf;
|
||||
int pos;
|
||||
};
|
||||
|
||||
extern struct pcm pcm;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
71
apps/plugins/rockboy/rc.h
Normal file
71
apps/plugins/rockboy/rc.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
|
||||
|
||||
|
||||
#ifndef __RC_H__
|
||||
#define __RC_H__
|
||||
|
||||
|
||||
|
||||
typedef enum rctype
|
||||
{
|
||||
rcv_end,
|
||||
rcv_int,
|
||||
rcv_string,
|
||||
rcv_vector,
|
||||
rcv_bool
|
||||
} rcvtype_t;
|
||||
|
||||
|
||||
typedef struct rcvar_s
|
||||
{
|
||||
char *name;
|
||||
int type;
|
||||
int len;
|
||||
void *mem;
|
||||
} rcvar_t;
|
||||
|
||||
#define RCV_END { 0, rcv_end, 0, 0 }
|
||||
#define RCV_INT(n,v) { (n), rcv_int, 1, (v) }
|
||||
#define RCV_STRING(n,v) { (n), rcv_string, 0, (v) }
|
||||
#define RCV_VECTOR(n,v,l) { (n), rcv_vector, (l), (v) }
|
||||
#define RCV_BOOL(n,v) { (n), rcv_bool, 1, (v) }
|
||||
|
||||
typedef struct rccmd_s
|
||||
{
|
||||
char *name;
|
||||
int (*func)(int, char **);
|
||||
} rccmd_t;
|
||||
|
||||
#define RCC(n,f) { (n), (f) }
|
||||
#define RCC_END { 0, 0 }
|
||||
|
||||
void rc_export(rcvar_t *v);
|
||||
void rc_exportvars(rcvar_t *vars);
|
||||
|
||||
int rc_findvar(char *name);
|
||||
|
||||
int rc_setvar_n(int i, int c, char **v);
|
||||
int rc_setvar(char *name, int c, char **v);
|
||||
|
||||
int rc_getint_n(int i);
|
||||
int *rc_getvec_n(int i);
|
||||
char *rc_getstr_n(int i);
|
||||
|
||||
int rc_getint(char *name);
|
||||
int *rc_getvec(char *name);
|
||||
char *rc_getstr(char *name);
|
||||
|
||||
int rc_bindkey(char *keyname, char *cmd);
|
||||
int rc_unbindkey(char *keyname);
|
||||
void rc_unbindall(void);
|
||||
|
||||
int rc_sourcefile(char *filename);
|
||||
void rc_dokey(int key, int st);
|
||||
|
||||
int rc_command(char *line);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
122
apps/plugins/rockboy/rccmds.c
Normal file
122
apps/plugins/rockboy/rccmds.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
|
||||
|
||||
|
||||
|
||||
#include "rockmacros.h"
|
||||
|
||||
#include "defs.h"
|
||||
#include "rc.h"
|
||||
#include "hw.h"
|
||||
#include "emu.h"
|
||||
#include "save.h"
|
||||
#include "split.h"
|
||||
|
||||
/*
|
||||
* the set command is used to set rc-exported variables.
|
||||
*/
|
||||
|
||||
static int cmd_set(int argc, char **argv)
|
||||
{
|
||||
if (argc < 3)
|
||||
return -1;
|
||||
return rc_setvar(argv[1], argc-2, argv+2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* the following commands allow keys to be bound to perform rc commands.
|
||||
*/
|
||||
|
||||
static int cmd_reset(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
emu_reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_savestate(int argc, char **argv)
|
||||
{
|
||||
state_save(argc > 1 ? atoi(argv[1]) : -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_loadstate(int argc, char **argv)
|
||||
{
|
||||
state_load(argc > 1 ? atoi(argv[1]) : -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* table of command names and the corresponding functions to be called
|
||||
*/
|
||||
|
||||
rccmd_t rccmds[] =
|
||||
{
|
||||
RCC("set", cmd_set),
|
||||
RCC("reset", cmd_reset),
|
||||
RCC("savestate", cmd_savestate),
|
||||
RCC("loadstate", cmd_loadstate),
|
||||
RCC_END
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int rc_command(char *line)
|
||||
{
|
||||
int i, argc, ret;
|
||||
char *argv[128], linecopy[500];
|
||||
|
||||
// linecopy = malloc(strlen(line)+1);
|
||||
strcpy(linecopy, line);
|
||||
|
||||
argc = splitline(argv, (sizeof argv)/(sizeof argv[0]), linecopy);
|
||||
if (!argc)
|
||||
{
|
||||
// free(linecopy);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; rccmds[i].name; i++)
|
||||
{
|
||||
if (!strcmp(argv[0], rccmds[i].name))
|
||||
{
|
||||
ret = rccmds[i].func(argc, argv);
|
||||
// free(linecopy);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* printf("unknown command: %s\n", argv[0]); */
|
||||
// free(linecopy);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
233
apps/plugins/rockboy/rcvars.c
Normal file
233
apps/plugins/rockboy/rcvars.c
Normal file
|
@ -0,0 +1,233 @@
|
|||
|
||||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "rockmacros.h"
|
||||
|
||||
#include "defs.h"
|
||||
#include "rc.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static rcvar_t rcvars[150];
|
||||
|
||||
static int nvars;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void rc_export(rcvar_t *v)
|
||||
{
|
||||
const rcvar_t end = RCV_END;
|
||||
|
||||
if (!v) return;
|
||||
nvars++;
|
||||
// rcvars = realloc(rcvars, sizeof (rcvar_t) * (nvars+1));
|
||||
// if (!rcvars)
|
||||
// die("out of memory adding rcvar %s\n", v->name);
|
||||
rcvars[nvars-1] = *v;
|
||||
rcvars[nvars] = end;
|
||||
}
|
||||
|
||||
void rc_exportvars(rcvar_t *vars)
|
||||
{
|
||||
while(vars->type)
|
||||
rc_export(vars++);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int rc_findvar(char *name)
|
||||
{
|
||||
int i;
|
||||
if (!rcvars) return -1;
|
||||
for (i = 0; rcvars[i].name; i++)
|
||||
if (!strcmp(rcvars[i].name, name))
|
||||
break;
|
||||
if (!rcvars[i].name)
|
||||
return -1;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
int my_atoi(const char *s)
|
||||
{
|
||||
int a = 0;
|
||||
if (*s == '0')
|
||||
{
|
||||
s++;
|
||||
if (*s == 'x' || *s == 'X')
|
||||
{
|
||||
s++;
|
||||
while (*s)
|
||||
{
|
||||
if (isdigit(*s))
|
||||
a = (a<<4) + *s - '0';
|
||||
else if (strchr("ABCDEF", *s))
|
||||
a = (a<<4) + *s - 'A' + 10;
|
||||
else if (strchr("abcdef", *s))
|
||||
a = (a<<4) + *s - 'a' + 10;
|
||||
else return a;
|
||||
s++;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
while (*s)
|
||||
{
|
||||
if (strchr("01234567", *s))
|
||||
a = (a<<3) + *s - '0';
|
||||
else return a;
|
||||
s++;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
if (*s == '-')
|
||||
{
|
||||
s++;
|
||||
for (;;)
|
||||
{
|
||||
if (isdigit(*s))
|
||||
a = (a*10) + *s - '0';
|
||||
else return -a;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
while (*s)
|
||||
{
|
||||
if (isdigit(*s))
|
||||
a = (a*10) + *s - '0';
|
||||
else return a;
|
||||
s++;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
int rc_setvar_n(int i, int c, char **v)
|
||||
{
|
||||
int j;
|
||||
int *n;
|
||||
char **s;
|
||||
|
||||
switch (rcvars[i].type)
|
||||
{
|
||||
case rcv_int:
|
||||
if (c < 1) return -1;
|
||||
n = (int *)rcvars[i].mem;
|
||||
*n = my_atoi(v[0]);
|
||||
return 0;
|
||||
case rcv_string:
|
||||
if (c < 1) return -1;
|
||||
s = (char **)rcvars[i].mem;
|
||||
// if (*s) free(*s);
|
||||
strcpy(*s,v[0]);
|
||||
if (!*s)
|
||||
die("out of memory setting rcvar %s\n", rcvars[i].name);
|
||||
return 0;
|
||||
case rcv_vector:
|
||||
if (c > rcvars[i].len)
|
||||
c = rcvars[i].len;
|
||||
for (j = 0; j < c ; j++)
|
||||
((int *)rcvars[i].mem)[j] = my_atoi(v[j]);
|
||||
return 0;
|
||||
case rcv_bool:
|
||||
if (c < 1 || atoi(v[0]) || strchr("yYtT", v[0][0]))
|
||||
*(int *)rcvars[i].mem = 1;
|
||||
else if (strchr("0nNfF", v[0][0]))
|
||||
*(int *)rcvars[i].mem = 0;
|
||||
else
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int rc_setvar(char *name, int c, char **v)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = rc_findvar(name);
|
||||
if (i < 0) return i;
|
||||
|
||||
return rc_setvar_n(i, c, v);
|
||||
}
|
||||
|
||||
|
||||
void *rc_getmem_n(int i)
|
||||
{
|
||||
return rcvars[i].mem;
|
||||
}
|
||||
|
||||
|
||||
void *rc_getmem(char *name)
|
||||
{
|
||||
int i;
|
||||
i = rc_findvar(name);
|
||||
if (i < 0) return NULL;
|
||||
return rcvars[i].mem;
|
||||
}
|
||||
|
||||
int rc_getint_n(int i)
|
||||
{
|
||||
if (i < 0) return 0;
|
||||
switch (rcvars[i].type)
|
||||
{
|
||||
case rcv_int:
|
||||
case rcv_bool:
|
||||
return *(int *)rcvars[i].mem;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int *rc_getvec_n(int i)
|
||||
{
|
||||
if (i < 0) return NULL;
|
||||
switch (rcvars[i].type)
|
||||
{
|
||||
case rcv_int:
|
||||
case rcv_bool:
|
||||
case rcv_vector:
|
||||
return (int *)rcvars[i].mem;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *rc_getstr_n(int i)
|
||||
{
|
||||
if (i < 0) return 0;
|
||||
switch (rcvars[i].type)
|
||||
{
|
||||
case rcv_string:
|
||||
return *(char **)rcvars[i].mem;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rc_getint(char *name)
|
||||
{
|
||||
return rc_getint_n(rc_findvar(name));
|
||||
}
|
||||
|
||||
int *rc_getvec(char *name)
|
||||
{
|
||||
return rc_getvec_n(rc_findvar(name));
|
||||
}
|
||||
|
||||
char *rc_getstr(char *name)
|
||||
{
|
||||
return rc_getstr_n(rc_findvar(name));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
181
apps/plugins/rockboy/regs.h
Normal file
181
apps/plugins/rockboy/regs.h
Normal file
|
@ -0,0 +1,181 @@
|
|||
|
||||
#ifndef __REGS_H__
|
||||
#define __REGS_H__
|
||||
|
||||
|
||||
#include "mem.h"
|
||||
|
||||
/* General internal/io stuff */
|
||||
|
||||
#define RI_P1 0x00
|
||||
#define RI_SB 0x01
|
||||
#define RI_SC 0x02
|
||||
#define RI_DIV 0x04
|
||||
#define RI_TIMA 0x05
|
||||
#define RI_TMA 0x06
|
||||
#define RI_TAC 0x07
|
||||
|
||||
#define RI_KEY1 0x4D
|
||||
|
||||
#define RI_RP 0x56
|
||||
|
||||
#define RI_SVBK 0x70
|
||||
|
||||
|
||||
|
||||
/* Interrupts flags */
|
||||
|
||||
#define RI_IF 0x0F
|
||||
#define RI_IE 0xFF
|
||||
|
||||
|
||||
|
||||
|
||||
/* LCDC */
|
||||
|
||||
#define RI_LCDC 0x40
|
||||
#define RI_STAT 0x41
|
||||
#define RI_SCY 0x42
|
||||
#define RI_SCX 0x43
|
||||
#define RI_LY 0x44
|
||||
#define RI_LYC 0x45
|
||||
#define RI_DMA 0x46
|
||||
#define RI_BGP 0x47
|
||||
#define RI_OBP0 0x48
|
||||
#define RI_OBP1 0x49
|
||||
#define RI_WY 0x4A
|
||||
#define RI_WX 0x4B
|
||||
|
||||
#define RI_VBK 0x4F
|
||||
|
||||
#define RI_HDMA1 0x51
|
||||
#define RI_HDMA2 0x52
|
||||
#define RI_HDMA3 0x53
|
||||
#define RI_HDMA4 0x54
|
||||
#define RI_HDMA5 0x55
|
||||
|
||||
#define RI_BCPS 0x68
|
||||
#define RI_BCPD 0x69
|
||||
#define RI_OCPS 0x6A
|
||||
#define RI_OCPD 0x6B
|
||||
|
||||
|
||||
|
||||
/* Sound */
|
||||
|
||||
#define RI_NR10 0x10
|
||||
#define RI_NR11 0x11
|
||||
#define RI_NR12 0x12
|
||||
#define RI_NR13 0x13
|
||||
#define RI_NR14 0x14
|
||||
#define RI_NR21 0x16
|
||||
#define RI_NR22 0x17
|
||||
#define RI_NR23 0x18
|
||||
#define RI_NR24 0x19
|
||||
#define RI_NR30 0x1A
|
||||
#define RI_NR31 0x1B
|
||||
#define RI_NR32 0x1C
|
||||
#define RI_NR33 0x1D
|
||||
#define RI_NR34 0x1E
|
||||
#define RI_NR41 0x20
|
||||
#define RI_NR42 0x21
|
||||
#define RI_NR43 0x22
|
||||
#define RI_NR44 0x23
|
||||
#define RI_NR50 0x24
|
||||
#define RI_NR51 0x25
|
||||
#define RI_NR52 0x26
|
||||
|
||||
|
||||
|
||||
#define REG(n) ram.hi[(n)]
|
||||
|
||||
|
||||
|
||||
/* General internal/io stuff */
|
||||
|
||||
#define R_P1 REG(RI_P1)
|
||||
#define R_SB REG(RI_SB)
|
||||
#define R_SC REG(RI_SC)
|
||||
#define R_DIV REG(RI_DIV)
|
||||
#define R_TIMA REG(RI_TIMA)
|
||||
#define R_TMA REG(RI_TMA)
|
||||
#define R_TAC REG(RI_TAC)
|
||||
|
||||
#define R_KEY1 REG(RI_KEY1)
|
||||
|
||||
#define R_RP REG(RI_RP)
|
||||
|
||||
#define R_SVBK REG(RI_SVBK)
|
||||
|
||||
|
||||
|
||||
/* Interrupts flags */
|
||||
|
||||
#define R_IF REG(RI_IF)
|
||||
#define R_IE REG(RI_IE)
|
||||
|
||||
|
||||
|
||||
|
||||
/* LCDC */
|
||||
|
||||
#define R_LCDC REG(RI_LCDC)
|
||||
#define R_STAT REG(RI_STAT)
|
||||
#define R_SCY REG(RI_SCY)
|
||||
#define R_SCX REG(RI_SCX)
|
||||
#define R_LY REG(RI_LY)
|
||||
#define R_LYC REG(RI_LYC)
|
||||
#define R_DMA REG(RI_DMA)
|
||||
#define R_BGP REG(RI_BGP)
|
||||
#define R_OBP0 REG(RI_OBP0)
|
||||
#define R_OBP1 REG(RI_OBP1)
|
||||
#define R_WY REG(RI_WY)
|
||||
#define R_WX REG(RI_WX)
|
||||
|
||||
#define R_VBK REG(RI_VBK)
|
||||
|
||||
#define R_HDMA1 REG(RI_HDMA1)
|
||||
#define R_HDMA2 REG(RI_HDMA2)
|
||||
#define R_HDMA3 REG(RI_HDMA3)
|
||||
#define R_HDMA4 REG(RI_HDMA4)
|
||||
#define R_HDMA5 REG(RI_HDMA5)
|
||||
|
||||
#define R_BCPS REG(RI_BCPS)
|
||||
#define R_BCPD REG(RI_BCPD)
|
||||
#define R_OCPS REG(RI_OCPS)
|
||||
#define R_OCPD REG(RI_OCPD)
|
||||
|
||||
|
||||
|
||||
/* Sound */
|
||||
|
||||
#define R_NR10 REG(RI_NR10)
|
||||
#define R_NR11 REG(RI_NR11)
|
||||
#define R_NR12 REG(RI_NR12)
|
||||
#define R_NR13 REG(RI_NR13)
|
||||
#define R_NR14 REG(RI_NR14)
|
||||
#define R_NR21 REG(RI_NR21)
|
||||
#define R_NR22 REG(RI_NR22)
|
||||
#define R_NR23 REG(RI_NR23)
|
||||
#define R_NR24 REG(RI_NR24)
|
||||
#define R_NR30 REG(RI_NR30)
|
||||
#define R_NR31 REG(RI_NR31)
|
||||
#define R_NR32 REG(RI_NR32)
|
||||
#define R_NR33 REG(RI_NR33)
|
||||
#define R_NR34 REG(RI_NR34)
|
||||
#define R_NR41 REG(RI_NR41)
|
||||
#define R_NR42 REG(RI_NR42)
|
||||
#define R_NR43 REG(RI_NR43)
|
||||
#define R_NR44 REG(RI_NR44)
|
||||
#define R_NR50 REG(RI_NR50)
|
||||
#define R_NR51 REG(RI_NR51)
|
||||
#define R_NR52 REG(RI_NR52)
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
137
apps/plugins/rockboy/rockboy.c
Normal file
137
apps/plugins/rockboy/rockboy.c
Normal file
|
@ -0,0 +1,137 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Gameboy emulator based on gnuboy
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "plugin.h"
|
||||
#include "loader.h"
|
||||
#include "rockmacros.h"
|
||||
|
||||
#if MEM <= 8 && !defined(SIMULATOR)
|
||||
/* On archos this is loaded as an overlay */
|
||||
|
||||
/* These are defined in the linker script */
|
||||
extern unsigned char ovl_start_addr[];
|
||||
extern unsigned char ovl_end_addr[];
|
||||
|
||||
const struct {
|
||||
unsigned long magic;
|
||||
unsigned char *start_addr;
|
||||
unsigned char *end_addr;
|
||||
enum plugin_status (*entry_point)(struct plugin_api*, void*);
|
||||
} header __attribute__ ((section (".header"))) = {
|
||||
0x524f564c, /* ROVL */
|
||||
ovl_start_addr, ovl_end_addr, plugin_start
|
||||
};
|
||||
#endif
|
||||
|
||||
/* here is a global api struct pointer. while not strictly necessary,
|
||||
it's nice not to have to pass the api pointer in all function calls
|
||||
in the plugin */
|
||||
struct plugin_api* rb;
|
||||
int shut,cleanshut;
|
||||
char *errormsg;
|
||||
int gnuboy_main(char *rom);
|
||||
|
||||
/* libc functions */
|
||||
|
||||
int isdigit(int c) {
|
||||
return c>='0' && c<= '9';
|
||||
}
|
||||
|
||||
int isalpha(int c) {
|
||||
return (c>='a' && c<='z')||(c>='A' && c<='Z');
|
||||
}
|
||||
|
||||
int isupper(int c) {
|
||||
return c>='A'&&c<='Z';
|
||||
}
|
||||
|
||||
int isalnum(int c) {
|
||||
return isdigit(c)||isalpha(c);
|
||||
}
|
||||
|
||||
void die(char *message, ...)
|
||||
{
|
||||
shut=1;
|
||||
errormsg=message;
|
||||
}
|
||||
|
||||
void *mp3_bufferbase;
|
||||
void *mp3_bufferpointer;
|
||||
unsigned int mp3_buffer_free;
|
||||
|
||||
void *my_malloc(size_t size)
|
||||
{
|
||||
void *alloc;
|
||||
|
||||
if (!mp3_bufferbase)
|
||||
{
|
||||
mp3_bufferbase = mp3_bufferpointer
|
||||
= rb->plugin_get_mp3_buffer(&mp3_buffer_free);
|
||||
#if MEM <= 8 && !defined(SIMULATOR)
|
||||
/* loaded as an overlay, protect from overwriting ourselves */
|
||||
if ((unsigned)(ovl_start_addr - (unsigned char *)mp3_bufferbase)
|
||||
< mp3_buffer_free)
|
||||
mp3_buffer_free = ovl_start_addr - (unsigned char *)mp3_bufferbase;
|
||||
#endif
|
||||
}
|
||||
if (size + 4 > mp3_buffer_free)
|
||||
return 0;
|
||||
alloc = mp3_bufferpointer;
|
||||
mp3_bufferpointer += size + 4;
|
||||
mp3_buffer_free -= size + 4;
|
||||
return alloc;
|
||||
}
|
||||
|
||||
void setmallocpos(void *pointer)
|
||||
{
|
||||
mp3_bufferpointer = pointer;
|
||||
mp3_buffer_free = mp3_bufferpointer - mp3_bufferbase;
|
||||
}
|
||||
|
||||
/* this is the plugin entry point */
|
||||
enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||
{
|
||||
/* this macro should be called as the first thing you do in the plugin.
|
||||
it test that the api version and model the plugin was compiled for
|
||||
matches the machine it is running on */
|
||||
TEST_PLUGIN_API(api);
|
||||
|
||||
/* if you are using a global api pointer, don't forget to copy it!
|
||||
otherwise you will get lovely "I04: IllInstr" errors... :-) */
|
||||
rb = api;
|
||||
shut=0;
|
||||
cleanshut=0;
|
||||
mp3_bufferbase=mp3_bufferpointer=0;
|
||||
mp3_buffer_free=0;
|
||||
|
||||
/* now go ahead and have fun! */
|
||||
rb->splash(HZ*2, true, "Rockboy v0.3");
|
||||
rb->lcd_clear_display();
|
||||
gnuboy_main(parameter);
|
||||
|
||||
if(shut&&!cleanshut) {
|
||||
rb->splash(HZ*2, true, errormsg);
|
||||
return PLUGIN_ERROR;
|
||||
}
|
||||
|
||||
rb->splash(HZ*2, true, "Shutting down.. byebye ^^");
|
||||
|
||||
cleanup();
|
||||
|
||||
return PLUGIN_OK;
|
||||
}
|
88
apps/plugins/rockboy/rockmacros.h
Normal file
88
apps/plugins/rockboy/rockmacros.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2005 Michiel van der Kolk, Jens Arnold
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <plugin.h>
|
||||
|
||||
/* workaround for cygwin not defining endian macros */
|
||||
#if !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN) && defined(_X86_)
|
||||
#define LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#define malloc(a) my_malloc(a)
|
||||
void *my_malloc(size_t size);
|
||||
|
||||
extern struct plugin_api* rb;
|
||||
extern int shut,cleanshut;
|
||||
void vid_update(int scanline);
|
||||
void vid_init(void);
|
||||
void vid_begin(void);
|
||||
void vid_end(void);
|
||||
void die(char *message, ...);
|
||||
void setmallocpos(void *pointer);
|
||||
void vid_settitle(char *title);
|
||||
void *sys_timer(void);
|
||||
int sys_elapsed(long *oldtick);
|
||||
void sys_sleep(int us);
|
||||
int pcm_submit(void);
|
||||
void pcm_init(void);
|
||||
void doevents(void);
|
||||
int isupper(int c);
|
||||
int isdigit(int c);
|
||||
void ev_poll(void);
|
||||
|
||||
#ifdef SIMULATOR
|
||||
#undef opendir
|
||||
#define opendir(a) rb->sim_opendir((a))
|
||||
#undef closedir
|
||||
#define closedir(a) rb->sim_closedir((a))
|
||||
#undef mkdir
|
||||
#define mkdir(a,b) rb->sim_mkdir((a),(b))
|
||||
#undef open
|
||||
#define open(a,b) rb->sim_open((a),(b))
|
||||
#undef lseek
|
||||
#define lseek(a,b,c) rb->sim_lseek((a),(b),(c))
|
||||
#else /* !SIMULATOR */
|
||||
#define opendir(a) rb->opendir((a))
|
||||
#define closedir(a) rb->closedir((a))
|
||||
#define mkdir(a,b) rb->mkdir((a),(b))
|
||||
#define open(a,b) rb->open((a),(b))
|
||||
#define lseek(a,b,c) rb->lseek((a),(b),(c))
|
||||
#endif /* !SIMULATOR */
|
||||
|
||||
#define strcat(a,b) rb->strcat((a),(b))
|
||||
#define close(a) rb->close((a))
|
||||
#define read(a,b,c) rb->read((a),(b),(c))
|
||||
#define write(a,b,c) rb->write((a),(b),(c))
|
||||
#define memset(a,b,c) rb->memset((a),(b),(c))
|
||||
#define memcpy(a,b,c) rb->memcpy((a),(b),(c))
|
||||
#define strcpy(a,b) rb->strcpy((a),(b))
|
||||
#define strncpy(a,b,c) rb->strncpy((a),(b),(c))
|
||||
#define strlen(a) rb->strlen((a))
|
||||
#define strcmp(a,b) rb->strcmp((a),(b))
|
||||
#define strchr(a,b) rb->strchr((a),(b))
|
||||
#define strrchr(a,b) rb->strrchr((a),(b))
|
||||
#define strcasecmp(a,b) rb->strcasecmp((a),(b))
|
||||
#define srand(a) rb->srand((a))
|
||||
#define rand() rb->rand()
|
||||
#define atoi(a) rb->atoi((a))
|
||||
#define strcat(a,b) rb->strcat((a),(b))
|
||||
#define snprintf(...) rb->snprintf(__VA_ARGS__)
|
||||
#define fprintf(...) rb->fdprintf(__VA_ARGS__)
|
||||
#define tolower(_A_) (isupper(_A_) ? (_A_ - 'A' + 'a') : _A_)
|
||||
|
135
apps/plugins/rockboy/rtc.c
Normal file
135
apps/plugins/rockboy/rtc.c
Normal file
|
@ -0,0 +1,135 @@
|
|||
|
||||
|
||||
|
||||
#include "rockmacros.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "mem.h"
|
||||
#include "rtc.h"
|
||||
#include "rc.h"
|
||||
|
||||
struct rtc rtc;
|
||||
|
||||
static int syncrtc = 1;
|
||||
|
||||
rcvar_t rtc_exports[] =
|
||||
{
|
||||
RCV_BOOL("syncrtc", &syncrtc),
|
||||
RCV_END
|
||||
};
|
||||
|
||||
|
||||
void rtc_latch(byte b)
|
||||
{
|
||||
if ((rtc.latch ^ b) & b & 1)
|
||||
{
|
||||
rtc.regs[0] = rtc.s;
|
||||
rtc.regs[1] = rtc.m;
|
||||
rtc.regs[2] = rtc.h;
|
||||
rtc.regs[3] = rtc.d;
|
||||
rtc.regs[4] = (rtc.d>>9) | (rtc.stop<<6) | (rtc.carry<<7);
|
||||
rtc.regs[5] = 0xff;
|
||||
rtc.regs[6] = 0xff;
|
||||
rtc.regs[7] = 0xff;
|
||||
}
|
||||
rtc.latch = b;
|
||||
}
|
||||
|
||||
void rtc_write(byte b)
|
||||
{
|
||||
/* printf("write %02X: %02X (%d)\n", rtc.sel, b, b); */
|
||||
if (!(rtc.sel & 8)) return;
|
||||
switch (rtc.sel & 7)
|
||||
{
|
||||
case 0:
|
||||
rtc.s = rtc.regs[0] = b;
|
||||
while (rtc.s >= 60) rtc.s -= 60;
|
||||
break;
|
||||
case 1:
|
||||
rtc.m = rtc.regs[1] = b;
|
||||
while (rtc.m >= 60) rtc.m -= 60;
|
||||
break;
|
||||
case 2:
|
||||
rtc.h = rtc.regs[2] = b;
|
||||
while (rtc.h >= 24) rtc.h -= 24;
|
||||
break;
|
||||
case 3:
|
||||
rtc.regs[3] = b;
|
||||
rtc.d = (rtc.d & 0x100) | b;
|
||||
break;
|
||||
case 4:
|
||||
rtc.regs[4] = b;
|
||||
rtc.d = (rtc.d & 0xff) | ((b&1)<<9);
|
||||
rtc.stop = (b>>6)&1;
|
||||
rtc.carry = (b>>7)&1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_tick()
|
||||
{
|
||||
if (rtc.stop) return;
|
||||
if (++rtc.t == 60)
|
||||
{
|
||||
if (++rtc.s == 60)
|
||||
{
|
||||
if (++rtc.m == 60)
|
||||
{
|
||||
if (++rtc.h == 24)
|
||||
{
|
||||
if (++rtc.d == 365)
|
||||
{
|
||||
rtc.d = 0;
|
||||
rtc.carry = 1;
|
||||
}
|
||||
rtc.h = 0;
|
||||
}
|
||||
rtc.m = 0;
|
||||
}
|
||||
rtc.s = 0;
|
||||
}
|
||||
rtc.t = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_save_internal(int fd)
|
||||
{
|
||||
(void)fd; // stop compiler complaining
|
||||
// TODO
|
||||
// fprintf(f, "%d %d %d %02d %02d %02d %02d\n%d\n",
|
||||
// rtc.carry, rtc.stop, rtc.d, rtc.h, rtc.m, rtc.s, rtc.t,
|
||||
// time(0));
|
||||
}
|
||||
|
||||
void rtc_load_internal(int fd)
|
||||
{
|
||||
//int rt = 0;
|
||||
(void)fd; // stop compiler complaining
|
||||
// TODO
|
||||
/* fscanf(
|
||||
f, "%d %d %d %02d %02d %02d %02d\n%d\n",
|
||||
&rtc.carry, &rtc.stop, &rtc.d,
|
||||
&rtc.h, &rtc.m, &rtc.s, &rtc.t, &rt);
|
||||
while (rtc.t >= 60) rtc.t -= 60;
|
||||
while (rtc.s >= 60) rtc.s -= 60;
|
||||
while (rtc.m >= 60) rtc.m -= 60;
|
||||
while (rtc.h >= 24) rtc.h -= 24;
|
||||
while (rtc.d >= 365) rtc.d -= 365;
|
||||
rtc.stop &= 1;
|
||||
rtc.carry &= 1;
|
||||
if (rt) rt = (time(0) - rt) * 60;
|
||||
if (syncrtc) while (rt-- > 0) rtc_tick(); */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
25
apps/plugins/rockboy/rtc.h
Normal file
25
apps/plugins/rockboy/rtc.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
|
||||
#ifndef __RTC_H__
|
||||
#define __RTC_H__
|
||||
|
||||
|
||||
struct rtc
|
||||
{
|
||||
int batt;
|
||||
int sel;
|
||||
int latch;
|
||||
int d, h, m, s, t;
|
||||
int stop, carry;
|
||||
byte regs[8];
|
||||
};
|
||||
|
||||
extern struct rtc rtc;
|
||||
|
||||
void rtc_latch(byte b);
|
||||
void rtc_write(byte b);
|
||||
void rtc_tick(void);
|
||||
void rtc_save_internal(int fd);
|
||||
void rtc_load_internal(int fd);
|
||||
|
||||
#endif
|
286
apps/plugins/rockboy/save.c
Normal file
286
apps/plugins/rockboy/save.c
Normal file
|
@ -0,0 +1,286 @@
|
|||
|
||||
|
||||
#include "rockmacros.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "cpu.h"
|
||||
#include "cpuregs.h"
|
||||
#include "hw.h"
|
||||
#include "regs.h"
|
||||
#include "lcd.h"
|
||||
#include "rtc.h"
|
||||
#include "mem.h"
|
||||
#include "sound.h"
|
||||
|
||||
|
||||
|
||||
#ifdef LITTLE_ENDIAN
|
||||
#define LIL(x) (x)
|
||||
#else
|
||||
#define LIL(x) ((x<<24)|((x&0xff00)<<8)|((x>>8)&0xff00)|(x>>24))
|
||||
#endif
|
||||
|
||||
#define I1(s, p) { 1, s, p }
|
||||
#define I2(s, p) { 2, s, p }
|
||||
#define I4(s, p) { 4, s, p }
|
||||
#define R(r) I1(#r, &R_##r)
|
||||
#define NOSAVE { -1, "\0\0\0\0", 0 }
|
||||
#define END { 0, "\0\0\0\0", 0 }
|
||||
|
||||
struct svar
|
||||
{
|
||||
int len;
|
||||
char key[4];
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
static int ver;
|
||||
static int sramblock, iramblock, vramblock;
|
||||
static int hramofs, hiofs, palofs, oamofs, wavofs;
|
||||
|
||||
struct svar svars[] =
|
||||
{
|
||||
I4("GbSs", &ver),
|
||||
|
||||
I2("PC ", &PC),
|
||||
I2("SP ", &SP),
|
||||
I2("BC ", &BC),
|
||||
I2("DE ", &DE),
|
||||
I2("HL ", &HL),
|
||||
I2("AF ", &AF),
|
||||
|
||||
I4("IME ", &cpu.ime),
|
||||
I4("ima ", &cpu.ima),
|
||||
I4("spd ", &cpu.speed),
|
||||
I4("halt", &cpu.halt),
|
||||
I4("div ", &cpu.div),
|
||||
I4("tim ", &cpu.tim),
|
||||
I4("lcdc", &cpu.lcdc),
|
||||
I4("snd ", &cpu.snd),
|
||||
|
||||
I1("ints", &hw.ilines),
|
||||
I1("pad ", &hw.pad),
|
||||
I4("cgb ", &hw.cgb),
|
||||
I4("gba ", &hw.gba),
|
||||
|
||||
I4("mbcm", &mbc.model),
|
||||
I4("romb", &mbc.rombank),
|
||||
I4("ramb", &mbc.rambank),
|
||||
I4("enab", &mbc.enableram),
|
||||
I4("batt", &mbc.batt),
|
||||
|
||||
I4("rtcR", &rtc.sel),
|
||||
I4("rtcL", &rtc.latch),
|
||||
I4("rtcC", &rtc.carry),
|
||||
I4("rtcS", &rtc.stop),
|
||||
I4("rtcd", &rtc.d),
|
||||
I4("rtch", &rtc.h),
|
||||
I4("rtcm", &rtc.m),
|
||||
I4("rtcs", &rtc.s),
|
||||
I4("rtct", &rtc.t),
|
||||
I1("rtR8", &rtc.regs[0]),
|
||||
I1("rtR9", &rtc.regs[1]),
|
||||
I1("rtRA", &rtc.regs[2]),
|
||||
I1("rtRB", &rtc.regs[3]),
|
||||
I1("rtRC", &rtc.regs[4]),
|
||||
|
||||
I4("S1on", &snd.ch[0].on),
|
||||
I4("S1p ", &snd.ch[0].pos),
|
||||
I4("S1c ", &snd.ch[0].cnt),
|
||||
I4("S1ec", &snd.ch[0].encnt),
|
||||
I4("S1sc", &snd.ch[0].swcnt),
|
||||
I4("S1sf", &snd.ch[0].swfreq),
|
||||
|
||||
I4("S2on", &snd.ch[1].on),
|
||||
I4("S2p ", &snd.ch[1].pos),
|
||||
I4("S2c ", &snd.ch[1].cnt),
|
||||
I4("S2ec", &snd.ch[1].encnt),
|
||||
|
||||
I4("S3on", &snd.ch[2].on),
|
||||
I4("S3p ", &snd.ch[2].pos),
|
||||
I4("S3c ", &snd.ch[2].cnt),
|
||||
|
||||
I4("S4on", &snd.ch[3].on),
|
||||
I4("S4p ", &snd.ch[3].pos),
|
||||
I4("S4c ", &snd.ch[3].cnt),
|
||||
I4("S4ec", &snd.ch[3].encnt),
|
||||
|
||||
I4("hdma", &hw.hdma),
|
||||
|
||||
I4("sram", &sramblock),
|
||||
I4("iram", &iramblock),
|
||||
I4("vram", &vramblock),
|
||||
I4("hi ", &hiofs),
|
||||
I4("pal ", &palofs),
|
||||
I4("oam ", &oamofs),
|
||||
I4("wav ", &wavofs),
|
||||
|
||||
/* NOSAVE is a special code to prevent the rest of the table
|
||||
* from being saved, used to support old stuff for backwards
|
||||
* compatibility... */
|
||||
NOSAVE,
|
||||
|
||||
/* the following are obsolete as of 0x104 */
|
||||
|
||||
I4("hram", &hramofs),
|
||||
|
||||
R(P1), R(SB), R(SC),
|
||||
R(DIV), R(TIMA), R(TMA), R(TAC),
|
||||
R(IE), R(IF),
|
||||
R(LCDC), R(STAT), R(LY), R(LYC),
|
||||
R(SCX), R(SCY), R(WX), R(WY),
|
||||
R(BGP), R(OBP0), R(OBP1),
|
||||
R(DMA),
|
||||
|
||||
R(VBK), R(SVBK), R(KEY1),
|
||||
R(BCPS), R(BCPD), R(OCPS), R(OCPD),
|
||||
|
||||
R(NR10), R(NR11), R(NR12), R(NR13), R(NR14),
|
||||
R(NR21), R(NR22), R(NR23), R(NR24),
|
||||
R(NR30), R(NR31), R(NR32), R(NR33), R(NR34),
|
||||
R(NR41), R(NR42), R(NR43), R(NR44),
|
||||
R(NR50), R(NR51), R(NR52),
|
||||
|
||||
I1("DMA1", &R_HDMA1),
|
||||
I1("DMA2", &R_HDMA2),
|
||||
I1("DMA3", &R_HDMA3),
|
||||
I1("DMA4", &R_HDMA4),
|
||||
I1("DMA5", &R_HDMA5),
|
||||
|
||||
END
|
||||
};
|
||||
|
||||
|
||||
void loadstate(int fd)
|
||||
{
|
||||
int i, j;
|
||||
byte buf[4096];
|
||||
un32 (*header)[2] = (un32 (*)[2])buf;
|
||||
un32 d;
|
||||
int irl = hw.cgb ? 8 : 2;
|
||||
int vrl = hw.cgb ? 4 : 2;
|
||||
int srl = mbc.ramsize << 1;
|
||||
|
||||
ver = hramofs = hiofs = palofs = oamofs = wavofs = 0;
|
||||
|
||||
read(fd,buf, 4096);
|
||||
|
||||
for (j = 0; header[j][0]; j++)
|
||||
{
|
||||
for (i = 0; svars[i].ptr; i++)
|
||||
{
|
||||
if (header[j][0] != *(un32 *)svars[i].key)
|
||||
continue;
|
||||
d = LIL(header[j][1]);
|
||||
switch (svars[i].len)
|
||||
{
|
||||
case 1:
|
||||
*(byte *)svars[i].ptr = d;
|
||||
break;
|
||||
case 2:
|
||||
*(un16 *)svars[i].ptr = d;
|
||||
break;
|
||||
case 4:
|
||||
*(un32 *)svars[i].ptr = d;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* obsolete as of version 0x104 */
|
||||
if (hramofs) memcpy(ram.hi+128, buf+hramofs, 127);
|
||||
|
||||
if (hiofs) memcpy(ram.hi, buf+hiofs, sizeof ram.hi);
|
||||
if (palofs) memcpy(lcd.pal, buf+palofs, sizeof lcd.pal);
|
||||
if (oamofs) memcpy(lcd.oam.mem, buf+oamofs, sizeof lcd.oam);
|
||||
|
||||
if (wavofs) memcpy(snd.wave, buf+wavofs, sizeof snd.wave);
|
||||
else memcpy(snd.wave, ram.hi+0x30, 16); /* patch data from older files */
|
||||
|
||||
lseek(fd, iramblock<<12, SEEK_SET);
|
||||
read(fd,ram.ibank, 4096*irl);
|
||||
|
||||
lseek(fd, vramblock<<12, SEEK_SET);
|
||||
read(fd,lcd.vbank, 4096*vrl);
|
||||
|
||||
lseek(fd, sramblock<<12, SEEK_SET);
|
||||
read(fd,ram.sbank, 4096*srl);
|
||||
}
|
||||
|
||||
void savestate(int fd)
|
||||
{
|
||||
int i;
|
||||
byte buf[4096];
|
||||
un32 (*header)[2] = (un32 (*)[2])buf;
|
||||
un32 d = 0;
|
||||
int irl = hw.cgb ? 8 : 2;
|
||||
int vrl = hw.cgb ? 4 : 2;
|
||||
int srl = mbc.ramsize << 1;
|
||||
|
||||
ver = 0x105;
|
||||
iramblock = 1;
|
||||
vramblock = 1+irl;
|
||||
sramblock = 1+irl+vrl;
|
||||
wavofs = 4096 - 784;
|
||||
hiofs = 4096 - 768;
|
||||
palofs = 4096 - 512;
|
||||
oamofs = 4096 - 256;
|
||||
memset(buf, 0, sizeof buf);
|
||||
|
||||
for (i = 0; svars[i].len > 0; i++)
|
||||
{
|
||||
header[i][0] = *(un32 *)svars[i].key;
|
||||
switch (svars[i].len)
|
||||
{
|
||||
case 1:
|
||||
d = *(byte *)svars[i].ptr;
|
||||
break;
|
||||
case 2:
|
||||
d = *(un16 *)svars[i].ptr;
|
||||
break;
|
||||
case 4:
|
||||
d = *(un32 *)svars[i].ptr;
|
||||
break;
|
||||
}
|
||||
header[i][1] = LIL(d);
|
||||
}
|
||||
header[i][0] = header[i][1] = 0;
|
||||
|
||||
memcpy(buf+hiofs, ram.hi, sizeof ram.hi);
|
||||
memcpy(buf+palofs, lcd.pal, sizeof lcd.pal);
|
||||
memcpy(buf+oamofs, lcd.oam.mem, sizeof lcd.oam);
|
||||
memcpy(buf+wavofs, snd.wave, sizeof snd.wave);
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
write(fd,buf, 4096);
|
||||
|
||||
lseek(fd, iramblock<<12, SEEK_SET);
|
||||
write(fd,ram.ibank, 4096*irl);
|
||||
|
||||
lseek(fd, vramblock<<12, SEEK_SET);
|
||||
write(fd,lcd.vbank, 4096*vrl);
|
||||
|
||||
lseek(fd, sramblock<<12, SEEK_SET);
|
||||
write(fd,ram.sbank, 4096*srl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
4
apps/plugins/rockboy/save.h
Normal file
4
apps/plugins/rockboy/save.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
void loadstate(int fd);
|
||||
void savestate(int fd);
|
||||
void state_save(int n);
|
||||
void state_load(int n);
|
466
apps/plugins/rockboy/sound.c
Normal file
466
apps/plugins/rockboy/sound.c
Normal file
|
@ -0,0 +1,466 @@
|
|||
|
||||
|
||||
|
||||
#include "rockmacros.h"
|
||||
#include "defs.h"
|
||||
#include "pcm.h"
|
||||
#include "sound.h"
|
||||
#include "cpu.h"
|
||||
#include "hw.h"
|
||||
#include "regs.h"
|
||||
#include "rc.h"
|
||||
#include "noise.h"
|
||||
|
||||
|
||||
static const byte dmgwave[16] =
|
||||
{
|
||||
0xac, 0xdd, 0xda, 0x48,
|
||||
0x36, 0x02, 0xcf, 0x16,
|
||||
0x2c, 0x04, 0xe5, 0x2c,
|
||||
0xac, 0xdd, 0xda, 0x48
|
||||
};
|
||||
|
||||
static const byte cgbwave[16] =
|
||||
{
|
||||
0x00, 0xff, 0x00, 0xff,
|
||||
0x00, 0xff, 0x00, 0xff,
|
||||
0x00, 0xff, 0x00, 0xff,
|
||||
0x00, 0xff, 0x00, 0xff,
|
||||
};
|
||||
|
||||
|
||||
static const byte sqwave[4][8] =
|
||||
{
|
||||
{ 0, 0,-1, 0, 0, 0, 0, 0 },
|
||||
{ 0,-1,-1, 0, 0, 0, 0, 0 },
|
||||
{ -1,-1,-1,-1, 0, 0, 0, 0 },
|
||||
{ -1, 0, 0,-1,-1,-1,-1,-1 }
|
||||
};
|
||||
|
||||
static const int freqtab[8] =
|
||||
{
|
||||
(1<<14)*2,
|
||||
(1<<14),
|
||||
(1<<14)/2,
|
||||
(1<<14)/3,
|
||||
(1<<14)/4,
|
||||
(1<<14)/5,
|
||||
(1<<14)/6,
|
||||
(1<<14)/7
|
||||
};
|
||||
|
||||
struct snd snd;
|
||||
int pcm_submit(void);
|
||||
|
||||
#define RATE (snd.rate)
|
||||
#define WAVE (snd.wave) /* ram.hi+0x30 */
|
||||
#define S1 (snd.ch[0])
|
||||
#define S2 (snd.ch[1])
|
||||
#define S3 (snd.ch[2])
|
||||
#define S4 (snd.ch[3])
|
||||
|
||||
rcvar_t sound_exports[] =
|
||||
{
|
||||
RCV_END
|
||||
};
|
||||
|
||||
|
||||
static void s1_freq_d(int d)
|
||||
{
|
||||
if (RATE > (d<<4)) S1.freq = 0;
|
||||
else S1.freq = (RATE << 17)/d;
|
||||
}
|
||||
|
||||
static void s1_freq(void)
|
||||
{
|
||||
s1_freq_d(2048 - (((R_NR14&7)<<8) + R_NR13));
|
||||
}
|
||||
|
||||
static void s2_freq(void)
|
||||
{
|
||||
int d = 2048 - (((R_NR24&7)<<8) + R_NR23);
|
||||
if (RATE > (d<<4)) S2.freq = 0;
|
||||
else S2.freq = (RATE << 17)/d;
|
||||
}
|
||||
|
||||
static void s3_freq(void)
|
||||
{
|
||||
int d = 2048 - (((R_NR34&7)<<8) + R_NR33);
|
||||
if (RATE > (d<<3)) S3.freq = 0;
|
||||
else S3.freq = (RATE << 21)/d;
|
||||
}
|
||||
|
||||
static void s4_freq(void)
|
||||
{
|
||||
S4.freq = (freqtab[R_NR43&7] >> (R_NR43 >> 4)) * RATE;
|
||||
if (S4.freq >> 18) S4.freq = 1<<18;
|
||||
}
|
||||
|
||||
void sound_dirty(void)
|
||||
{
|
||||
S1.swlen = ((R_NR10>>4) & 7) << 14;
|
||||
S1.len = (64-(R_NR11&63)) << 13;
|
||||
S1.envol = R_NR12 >> 4;
|
||||
S1.endir = (R_NR12>>3) & 1;
|
||||
S1.endir |= S1.endir - 1;
|
||||
S1.enlen = (R_NR12 & 7) << 15;
|
||||
s1_freq();
|
||||
S2.len = (64-(R_NR21&63)) << 13;
|
||||
S2.envol = R_NR22 >> 4;
|
||||
S2.endir = (R_NR22>>3) & 1;
|
||||
S2.endir |= S2.endir - 1;
|
||||
S2.enlen = (R_NR22 & 7) << 15;
|
||||
s2_freq();
|
||||
S3.len = (256-R_NR31) << 20;
|
||||
s3_freq();
|
||||
S4.len = (64-(R_NR41&63)) << 13;
|
||||
S4.envol = R_NR42 >> 4;
|
||||
S4.endir = (R_NR42>>3) & 1;
|
||||
S4.endir |= S4.endir - 1;
|
||||
S4.enlen = (R_NR42 & 7) << 15;
|
||||
s4_freq();
|
||||
}
|
||||
|
||||
void sound_off(void)
|
||||
{
|
||||
memset(&S1, 0, sizeof S1);
|
||||
memset(&S2, 0, sizeof S2);
|
||||
memset(&S3, 0, sizeof S3);
|
||||
memset(&S4, 0, sizeof S4);
|
||||
R_NR10 = 0x80;
|
||||
R_NR11 = 0xBF;
|
||||
R_NR12 = 0xF3;
|
||||
R_NR14 = 0xBF;
|
||||
R_NR21 = 0x3F;
|
||||
R_NR22 = 0x00;
|
||||
R_NR24 = 0xBF;
|
||||
R_NR30 = 0x7F;
|
||||
R_NR31 = 0xFF;
|
||||
R_NR32 = 0x9F;
|
||||
R_NR33 = 0xBF;
|
||||
R_NR41 = 0xFF;
|
||||
R_NR42 = 0x00;
|
||||
R_NR43 = 0x00;
|
||||
R_NR44 = 0xBF;
|
||||
R_NR50 = 0x77;
|
||||
R_NR51 = 0xF3;
|
||||
R_NR52 = 0xF1;
|
||||
sound_dirty();
|
||||
}
|
||||
|
||||
void sound_reset(void)
|
||||
{
|
||||
memset(&snd, 0, sizeof snd);
|
||||
if (pcm.hz) snd.rate = (1<<21) / pcm.hz;
|
||||
else snd.rate = 0;
|
||||
memcpy(WAVE, hw.cgb ? cgbwave : dmgwave, 16);
|
||||
memcpy(ram.hi+0x30, WAVE, 16);
|
||||
sound_off();
|
||||
}
|
||||
|
||||
|
||||
void sound_mix(void)
|
||||
{
|
||||
int s, l, r, f, n;
|
||||
|
||||
if (!RATE || cpu.snd < RATE) return;
|
||||
|
||||
for (; cpu.snd >= RATE; cpu.snd -= RATE)
|
||||
{
|
||||
l = r = 0;
|
||||
|
||||
if (S1.on)
|
||||
{
|
||||
s = sqwave[R_NR11>>6][(S1.pos>>18)&7] & S1.envol;
|
||||
S1.pos += S1.freq;
|
||||
if ((R_NR14 & 64) && ((S1.cnt += RATE) >= S1.len))
|
||||
S1.on = 0;
|
||||
if (S1.enlen && (S1.encnt += RATE) >= S1.enlen)
|
||||
{
|
||||
S1.encnt -= S1.enlen;
|
||||
S1.envol += S1.endir;
|
||||
if (S1.envol < 0) S1.envol = 0;
|
||||
if (S1.envol > 15) S1.envol = 15;
|
||||
}
|
||||
if (S1.swlen && (S1.swcnt += RATE) >= S1.swlen)
|
||||
{
|
||||
S1.swcnt -= S1.swlen;
|
||||
f = S1.swfreq;
|
||||
n = (R_NR10 & 7);
|
||||
if (R_NR10 & 8) f -= (f >> n);
|
||||
else f += (f >> n);
|
||||
if (f > 2047)
|
||||
S1.on = 0;
|
||||
else
|
||||
{
|
||||
S1.swfreq = f;
|
||||
R_NR13 = f;
|
||||
R_NR14 = (R_NR14 & 0xF8) | (f>>8);
|
||||
s1_freq_d(2048 - f);
|
||||
}
|
||||
}
|
||||
s <<= 2;
|
||||
if (R_NR51 & 1) r += s;
|
||||
if (R_NR51 & 16) l += s;
|
||||
}
|
||||
|
||||
if (S2.on)
|
||||
{
|
||||
s = sqwave[R_NR21>>6][(S2.pos>>18)&7] & S2.envol;
|
||||
S2.pos += S2.freq;
|
||||
if ((R_NR24 & 64) && ((S2.cnt += RATE) >= S2.len))
|
||||
S2.on = 0;
|
||||
if (S2.enlen && (S2.encnt += RATE) >= S2.enlen)
|
||||
{
|
||||
S2.encnt -= S2.enlen;
|
||||
S2.envol += S2.endir;
|
||||
if (S2.envol < 0) S2.envol = 0;
|
||||
if (S2.envol > 15) S2.envol = 15;
|
||||
}
|
||||
s <<= 2;
|
||||
if (R_NR51 & 2) r += s;
|
||||
if (R_NR51 & 32) l += s;
|
||||
}
|
||||
|
||||
if (S3.on)
|
||||
{
|
||||
s = WAVE[(S3.pos>>22) & 15];
|
||||
if (S3.pos & (1<<21)) s &= 15;
|
||||
else s >>= 4;
|
||||
s -= 8;
|
||||
S3.pos += S3.freq;
|
||||
if ((R_NR34 & 64) && ((S3.cnt += RATE) >= S3.len))
|
||||
S3.on = 0;
|
||||
if (R_NR32 & 96) s <<= (3 - ((R_NR32>>5)&3));
|
||||
else s = 0;
|
||||
if (R_NR51 & 4) r += s;
|
||||
if (R_NR51 & 64) l += s;
|
||||
}
|
||||
|
||||
if (S4.on)
|
||||
{
|
||||
if (R_NR43 & 8) s = 1 & (noise7[
|
||||
(S4.pos>>20)&15] >> (7-((S4.pos>>17)&7)));
|
||||
else s = 1 & (noise15[
|
||||
(S4.pos>>20)&4095] >> (7-((S4.pos>>17)&7)));
|
||||
s = (-s) & S4.envol;
|
||||
S4.pos += S4.freq;
|
||||
if ((R_NR44 & 64) && ((S4.cnt += RATE) >= S4.len))
|
||||
S4.on = 0;
|
||||
if (S4.enlen && (S4.encnt += RATE) >= S4.enlen)
|
||||
{
|
||||
S4.encnt -= S4.enlen;
|
||||
S4.envol += S4.endir;
|
||||
if (S4.envol < 0) S4.envol = 0;
|
||||
if (S4.envol > 15) S4.envol = 15;
|
||||
}
|
||||
s += s << 1;
|
||||
if (R_NR51 & 8) r += s;
|
||||
if (R_NR51 & 128) l += s;
|
||||
}
|
||||
|
||||
l *= (R_NR50 & 0x07);
|
||||
r *= ((R_NR50 & 0x70)>>4);
|
||||
l >>= 4;
|
||||
r >>= 4;
|
||||
|
||||
if (l > 127) l = 127;
|
||||
else if (l < -128) l = -128;
|
||||
if (r > 127) r = 127;
|
||||
else if (r < -128) r = -128;
|
||||
|
||||
if (pcm.buf)
|
||||
{
|
||||
if (pcm.pos >= pcm.len)
|
||||
pcm_submit();
|
||||
if (pcm.stereo)
|
||||
{
|
||||
pcm.buf[pcm.pos++] = l+128;
|
||||
pcm.buf[pcm.pos++] = r+128;
|
||||
}
|
||||
else pcm.buf[pcm.pos++] = ((l+r)>>1)+128;
|
||||
}
|
||||
}
|
||||
R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
byte sound_read(byte r)
|
||||
{
|
||||
sound_mix();
|
||||
/* printf("read %02X: %02X\n", r, REG(r)); */
|
||||
return REG(r);
|
||||
}
|
||||
|
||||
void s1_init(void)
|
||||
{
|
||||
S1.swcnt = 0;
|
||||
S1.swfreq = ((R_NR14&7)<<8) + R_NR13;
|
||||
S1.envol = R_NR12 >> 4;
|
||||
S1.endir = (R_NR12>>3) & 1;
|
||||
S1.endir |= S1.endir - 1;
|
||||
S1.enlen = (R_NR12 & 7) << 15;
|
||||
if (!S1.on) S1.pos = 0;
|
||||
S1.on = 1;
|
||||
S1.cnt = 0;
|
||||
S1.encnt = 0;
|
||||
}
|
||||
|
||||
void s2_init(void)
|
||||
{
|
||||
S2.envol = R_NR22 >> 4;
|
||||
S2.endir = (R_NR22>>3) & 1;
|
||||
S2.endir |= S2.endir - 1;
|
||||
S2.enlen = (R_NR22 & 7) << 15;
|
||||
if (!S2.on) S2.pos = 0;
|
||||
S2.on = 1;
|
||||
S2.cnt = 0;
|
||||
S2.encnt = 0;
|
||||
}
|
||||
|
||||
void s3_init(void)
|
||||
{
|
||||
int i;
|
||||
if (!S3.on) S3.pos = 0;
|
||||
S3.cnt = 0;
|
||||
S3.on = R_NR30 >> 7;
|
||||
if (S3.on) for (i = 0; i < 16; i++)
|
||||
ram.hi[i+0x30] = 0x13 ^ ram.hi[i+0x31];
|
||||
}
|
||||
|
||||
void s4_init(void)
|
||||
{
|
||||
S4.envol = R_NR42 >> 4;
|
||||
S4.endir = (R_NR42>>3) & 1;
|
||||
S4.endir |= S4.endir - 1;
|
||||
S4.enlen = (R_NR42 & 7) << 15;
|
||||
S4.on = 1;
|
||||
S4.pos = 0;
|
||||
S4.cnt = 0;
|
||||
S4.encnt = 0;
|
||||
}
|
||||
|
||||
|
||||
void sound_write(byte r, byte b)
|
||||
{
|
||||
#if 0
|
||||
static void *timer;
|
||||
if (!timer) timer = sys_timer();
|
||||
printf("write %02X: %02X @ %d\n", r, b, sys_elapsed(timer));
|
||||
#endif
|
||||
|
||||
if (!(R_NR52 & 128) && r != RI_NR52) return;
|
||||
if ((r & 0xF0) == 0x30)
|
||||
{
|
||||
if (S3.on) sound_mix();
|
||||
if (!S3.on)
|
||||
WAVE[r-0x30] = ram.hi[r] = b;
|
||||
return;
|
||||
}
|
||||
sound_mix();
|
||||
switch (r)
|
||||
{
|
||||
case RI_NR10:
|
||||
R_NR10 = b;
|
||||
S1.swlen = ((R_NR10>>4) & 7) << 14;
|
||||
S1.swfreq = ((R_NR14&7)<<8) + R_NR13;
|
||||
break;
|
||||
case RI_NR11:
|
||||
R_NR11 = b;
|
||||
S1.len = (64-(R_NR11&63)) << 13;
|
||||
break;
|
||||
case RI_NR12:
|
||||
R_NR12 = b;
|
||||
S1.envol = R_NR12 >> 4;
|
||||
S1.endir = (R_NR12>>3) & 1;
|
||||
S1.endir |= S1.endir - 1;
|
||||
S1.enlen = (R_NR12 & 7) << 15;
|
||||
break;
|
||||
case RI_NR13:
|
||||
R_NR13 = b;
|
||||
s1_freq();
|
||||
break;
|
||||
case RI_NR14:
|
||||
R_NR14 = b;
|
||||
s1_freq();
|
||||
if (b & 128) s1_init();
|
||||
break;
|
||||
case RI_NR21:
|
||||
R_NR21 = b;
|
||||
S2.len = (64-(R_NR21&63)) << 13;
|
||||
break;
|
||||
case RI_NR22:
|
||||
R_NR22 = b;
|
||||
S2.envol = R_NR22 >> 4;
|
||||
S2.endir = (R_NR22>>3) & 1;
|
||||
S2.endir |= S2.endir - 1;
|
||||
S2.enlen = (R_NR22 & 7) << 15;
|
||||
break;
|
||||
case RI_NR23:
|
||||
R_NR23 = b;
|
||||
s2_freq();
|
||||
break;
|
||||
case RI_NR24:
|
||||
R_NR24 = b;
|
||||
s2_freq();
|
||||
if (b & 128) s2_init();
|
||||
break;
|
||||
case RI_NR30:
|
||||
R_NR30 = b;
|
||||
if (!(b & 128)) S3.on = 0;
|
||||
break;
|
||||
case RI_NR31:
|
||||
R_NR31 = b;
|
||||
S3.len = (256-R_NR31) << 13;
|
||||
break;
|
||||
case RI_NR32:
|
||||
R_NR32 = b;
|
||||
break;
|
||||
case RI_NR33:
|
||||
R_NR33 = b;
|
||||
s3_freq();
|
||||
break;
|
||||
case RI_NR34:
|
||||
R_NR34 = b;
|
||||
s3_freq();
|
||||
if (b & 128) s3_init();
|
||||
break;
|
||||
case RI_NR41:
|
||||
R_NR41 = b;
|
||||
S4.len = (64-(R_NR41&63)) << 13;
|
||||
break;
|
||||
case RI_NR42:
|
||||
R_NR42 = b;
|
||||
S4.envol = R_NR42 >> 4;
|
||||
S4.endir = (R_NR42>>3) & 1;
|
||||
S4.endir |= S4.endir - 1;
|
||||
S4.enlen = (R_NR42 & 7) << 15;
|
||||
break;
|
||||
case RI_NR43:
|
||||
R_NR43 = b;
|
||||
s4_freq();
|
||||
break;
|
||||
case RI_NR44:
|
||||
R_NR44 = b;
|
||||
if (b & 128) s4_init();
|
||||
break;
|
||||
case RI_NR50:
|
||||
R_NR50 = b;
|
||||
break;
|
||||
case RI_NR51:
|
||||
R_NR51 = b;
|
||||
break;
|
||||
case RI_NR52:
|
||||
R_NR52 = b;
|
||||
if (!(R_NR52 & 128))
|
||||
sound_off();
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
41
apps/plugins/rockboy/sound.h
Normal file
41
apps/plugins/rockboy/sound.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
|
||||
|
||||
#ifndef __SOUND_H__
|
||||
#define __SOUND_H__
|
||||
|
||||
|
||||
struct sndchan
|
||||
{
|
||||
int on;
|
||||
unsigned pos;
|
||||
int cnt, encnt, swcnt;
|
||||
int len, enlen, swlen;
|
||||
int swfreq;
|
||||
int freq;
|
||||
int envol, endir;
|
||||
};
|
||||
|
||||
|
||||
struct snd
|
||||
{
|
||||
int rate;
|
||||
struct sndchan ch[4];
|
||||
byte wave[16];
|
||||
};
|
||||
|
||||
|
||||
extern struct snd snd;
|
||||
|
||||
byte sound_read(byte r);
|
||||
void sound_write(byte r, byte b);
|
||||
void sound_dirty(void);
|
||||
void sound_off(void);
|
||||
void sound_reset(void);
|
||||
void sound_mix(void);
|
||||
void s1_init(void);
|
||||
void s2_init(void);
|
||||
void s3_init(void);
|
||||
void s4_init(void);
|
||||
|
||||
#endif
|
||||
|
59
apps/plugins/rockboy/split.c
Normal file
59
apps/plugins/rockboy/split.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
|
||||
#include "rockmacros.h"
|
||||
|
||||
/*
|
||||
* splitline is a destructive argument parser, much like a very primitive
|
||||
* form of a shell parser. it supports quotes for embedded spaces and
|
||||
* literal quotes with the backslash escape.
|
||||
*/
|
||||
|
||||
char *splitnext(char **pos)
|
||||
{
|
||||
char *a, *d, *s;
|
||||
|
||||
d = s = *pos;
|
||||
while (*s == ' ' || *s == '\t') s++;
|
||||
a = s;
|
||||
while (*s && *s != ' ' && *s != '\t')
|
||||
{
|
||||
if (*s == '"')
|
||||
{
|
||||
s++;
|
||||
while (*s && *s != '"')
|
||||
{
|
||||
if (*s == '\\')
|
||||
s++;
|
||||
if (*s)
|
||||
*(d++) = *(s++);
|
||||
}
|
||||
if (*s == '"') s++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*s == '\\')
|
||||
s++;
|
||||
*(d++) = *(s++);
|
||||
}
|
||||
}
|
||||
while (*s == ' ' || *s == '\t') s++;
|
||||
*d = 0;
|
||||
*pos = s;
|
||||
return a;
|
||||
}
|
||||
|
||||
int splitline(char **argv, int max, char *line)
|
||||
{
|
||||
char *s;
|
||||
int i;
|
||||
|
||||
s = line;
|
||||
for (i = 0; *s && i < max + 1; i++)
|
||||
argv[i] = splitnext(&s);
|
||||
argv[i] = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
1
apps/plugins/rockboy/split.h
Normal file
1
apps/plugins/rockboy/split.h
Normal file
|
@ -0,0 +1 @@
|
|||
int splitline(char **argv, int max, char *line);
|
271
apps/plugins/rockboy/sys_rockbox.c
Normal file
271
apps/plugins/rockboy/sys_rockbox.c
Normal file
|
@ -0,0 +1,271 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2005 Michiel van der Kolk, Jens Arnold
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "rockmacros.h"
|
||||
#include "fb.h"
|
||||
#include "input.h"
|
||||
#include "rc.h"
|
||||
#include "lcd.h"
|
||||
#include "hw.h"
|
||||
#include "config.h"
|
||||
|
||||
rcvar_t joy_exports[] =
|
||||
{
|
||||
RCV_END
|
||||
};
|
||||
|
||||
rcvar_t vid_exports[] =
|
||||
{
|
||||
RCV_END
|
||||
};
|
||||
|
||||
struct fb fb;
|
||||
byte *video_base_buf;
|
||||
|
||||
extern int debug_trace;
|
||||
|
||||
static byte frameb[145][160];
|
||||
|
||||
void vid_settitle(char *title)
|
||||
{
|
||||
rb->splash(HZ*2, true, title);
|
||||
}
|
||||
|
||||
void joy_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void joy_close(void)
|
||||
{
|
||||
}
|
||||
|
||||
#if CONFIG_KEYPAD == IRIVER_H100_PAD
|
||||
#define ROCKBOY_PAD_A BUTTON_ON
|
||||
#define ROCKBOY_PAD_B BUTTON_OFF
|
||||
#define ROCKBOY_PAD_START BUTTON_REC
|
||||
#define ROCKBOY_PAD_SELECT BUTTON_MODE
|
||||
#define ROCKBOY_QUIT BUTTON_SELECT
|
||||
|
||||
#elif CONFIG_KEYPAD == RECORDER_PAD
|
||||
#define ROCKBOY_PAD_A BUTTON_F1
|
||||
#define ROCKBOY_PAD_B BUTTON_F2
|
||||
#define ROCKBOY_PAD_START BUTTON_F3
|
||||
#define ROCKBOY_PAD_SELECT BUTTON_PLAY
|
||||
#define ROCKBOY_QUIT BUTTON_OFF
|
||||
|
||||
#endif
|
||||
|
||||
unsigned int oldbuttonstate = 0, newbuttonstate;
|
||||
|
||||
void ev_poll(void)
|
||||
{
|
||||
event_t ev;
|
||||
int released, pressed;
|
||||
newbuttonstate = rb->button_status();
|
||||
released = ~newbuttonstate & oldbuttonstate;
|
||||
pressed = newbuttonstate & ~oldbuttonstate;
|
||||
oldbuttonstate = newbuttonstate;
|
||||
|
||||
if(released) {
|
||||
ev.type = EV_RELEASE;
|
||||
if(released & BUTTON_LEFT) { ev.code=PAD_LEFT; ev_postevent(&ev); }
|
||||
if(released & BUTTON_RIGHT) {ev.code=PAD_RIGHT; ev_postevent(&ev);}
|
||||
if(released & BUTTON_DOWN) { ev.code=PAD_DOWN; ev_postevent(&ev); }
|
||||
if(released & BUTTON_UP) { ev.code=PAD_UP; ev_postevent(&ev); }
|
||||
if(released & ROCKBOY_PAD_A) { ev.code=PAD_A; ev_postevent(&ev); }
|
||||
if(released & ROCKBOY_PAD_B) { ev.code=PAD_B; ev_postevent(&ev); }
|
||||
if(released & ROCKBOY_PAD_START) {
|
||||
ev.code=PAD_START;
|
||||
ev_postevent(&ev);
|
||||
}
|
||||
if(released & ROCKBOY_PAD_SELECT) {
|
||||
ev.code=PAD_SELECT;
|
||||
ev_postevent(&ev);
|
||||
}
|
||||
}
|
||||
if(pressed) { /* button press */
|
||||
ev.type = EV_PRESS;
|
||||
if(pressed & BUTTON_LEFT) { ev.code=PAD_LEFT; ev_postevent(&ev); }
|
||||
if(pressed & BUTTON_RIGHT) { ev.code=PAD_RIGHT; ev_postevent(&ev);}
|
||||
if(pressed & BUTTON_DOWN) { ev.code=PAD_DOWN; ev_postevent(&ev); }
|
||||
if(pressed & BUTTON_UP) { ev.code=PAD_UP; ev_postevent(&ev); }
|
||||
if(pressed & ROCKBOY_PAD_A) { ev.code=PAD_A; ev_postevent(&ev); }
|
||||
if(pressed & ROCKBOY_PAD_B) { ev.code=PAD_B; ev_postevent(&ev); }
|
||||
if(pressed & ROCKBOY_PAD_START) {
|
||||
ev.code=PAD_START;
|
||||
ev_postevent(&ev);
|
||||
}
|
||||
if(pressed & ROCKBOY_PAD_SELECT) {
|
||||
ev.code=PAD_SELECT;
|
||||
ev_postevent(&ev);
|
||||
}
|
||||
if(pressed & ROCKBOY_QUIT) {
|
||||
die("");
|
||||
cleanshut=1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void vid_setpal(int i, int r, int g, int b)
|
||||
{
|
||||
(void)i;
|
||||
(void)r;
|
||||
(void)g;
|
||||
(void)b;
|
||||
}
|
||||
|
||||
void vid_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void vid_begin(void)
|
||||
{
|
||||
fb.pelsize=1; // 8 bit framebuffer.. (too much.. but lowest gnuboy will support.. so yea...
|
||||
fb.h=144;
|
||||
fb.w=160;
|
||||
fb.pitch=160;
|
||||
fb.enabled=1;
|
||||
fb.dirty=0;
|
||||
video_base_buf=fb.ptr=(byte *)frameb;
|
||||
}
|
||||
|
||||
void vid_update(int scanline)
|
||||
{
|
||||
int cnt=0,scanline_remapped;
|
||||
byte *frameb;
|
||||
#if LCD_HEIGHT == 64 /* Archos */
|
||||
int balance = 0;
|
||||
if (scanline >= 128)
|
||||
return;
|
||||
scanline_remapped = scanline / 16;
|
||||
frameb = rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH;
|
||||
while (cnt < 160) {
|
||||
balance += LCD_WIDTH;
|
||||
if (balance > 0)
|
||||
{
|
||||
#ifdef SIMULATOR /* simulator uses C */
|
||||
register unsigned scrbyte = 0;
|
||||
if (scan.buf[0][cnt] & 0x02) scrbyte |= 0x01;
|
||||
if (scan.buf[1][cnt] & 0x02) scrbyte |= 0x02;
|
||||
if (scan.buf[2][cnt] & 0x02) scrbyte |= 0x04;
|
||||
if (scan.buf[3][cnt] & 0x02) scrbyte |= 0x08;
|
||||
if (scan.buf[4][cnt] & 0x02) scrbyte |= 0x10;
|
||||
if (scan.buf[5][cnt] & 0x02) scrbyte |= 0x20;
|
||||
if (scan.buf[6][cnt] & 0x02) scrbyte |= 0x40;
|
||||
if (scan.buf[7][cnt] & 0x02) scrbyte |= 0x80;
|
||||
*(frameb++) = scrbyte;
|
||||
#else
|
||||
asm volatile (
|
||||
"mov.b @%0,r0 \n"
|
||||
"add %1,%0 \n"
|
||||
"tst #0x02, r0 \n" /* ~bit 1 */
|
||||
"rotcr r1 \n"
|
||||
"mov.b @%0,r0 \n"
|
||||
"add %1,%0 \n"
|
||||
"tst #0x02, r0 \n" /* ~bit 1 */
|
||||
"rotcr r1 \n"
|
||||
"mov.b @%0,r0 \n"
|
||||
"add %1,%0 \n"
|
||||
"tst #0x02, r0 \n" /* ~bit 1 */
|
||||
"rotcr r1 \n"
|
||||
"mov.b @%0,r0 \n"
|
||||
"add %1,%0 \n"
|
||||
"tst #0x02, r0 \n" /* ~bit 1 */
|
||||
"rotcr r1 \n"
|
||||
"mov.b @%0,r0 \n"
|
||||
"add %1,%0 \n"
|
||||
"tst #0x02, r0 \n" /* ~bit 1 */
|
||||
"rotcr r1 \n"
|
||||
"mov.b @%0,r0 \n"
|
||||
"add %1,%0 \n"
|
||||
"tst #0x02, r0 \n" /* ~bit 1 */
|
||||
"rotcr r1 \n"
|
||||
"mov.b @%0,r0 \n"
|
||||
"add %1,%0 \n"
|
||||
"tst #0x02, r0 \n" /* ~bit 1 */
|
||||
"rotcr r1 \n"
|
||||
"mov.b @%0,r0 \n"
|
||||
"add %1,%0 \n"
|
||||
"tst #0x02, r0 \n" /* ~bit 1 */
|
||||
"rotcr r1 \n"
|
||||
|
||||
"shlr16 r1 \n"
|
||||
"shlr8 r1 \n"
|
||||
"not r1,r1 \n" /* account for negated bits */
|
||||
"mov.b r1,@%2 \n"
|
||||
: /* outputs */
|
||||
: /* inputs */
|
||||
/* %0 */ "r"(scan.buf[0] + cnt),
|
||||
/* %1 */ "r"(256), /* scan.buf line length */
|
||||
/* %2 */ "r"(frameb++)
|
||||
: /* clobbers */
|
||||
"r0", "r1"
|
||||
);
|
||||
#endif
|
||||
balance -= 160;
|
||||
}
|
||||
cnt ++;
|
||||
}
|
||||
rb->lcd_update_rect(0, (scanline/2) & ~7, LCD_WIDTH, 8);
|
||||
#else /* LCD_HEIGHT != 64, iRiver */
|
||||
if (scanline >= 128)
|
||||
return;
|
||||
scanline_remapped = scanline / 8;
|
||||
frameb = rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH;
|
||||
while (cnt < 160) {
|
||||
register unsigned scrbyte = 0;
|
||||
if (scan.buf[0][cnt] & 0x02) scrbyte |= 0x01;
|
||||
if (scan.buf[1][cnt] & 0x02) scrbyte |= 0x02;
|
||||
if (scan.buf[2][cnt] & 0x02) scrbyte |= 0x04;
|
||||
if (scan.buf[3][cnt] & 0x02) scrbyte |= 0x08;
|
||||
if (scan.buf[4][cnt] & 0x02) scrbyte |= 0x10;
|
||||
if (scan.buf[5][cnt] & 0x02) scrbyte |= 0x20;
|
||||
if (scan.buf[6][cnt] & 0x02) scrbyte |= 0x40;
|
||||
if (scan.buf[7][cnt] & 0x02) scrbyte |= 0x80;
|
||||
*(frameb++) = scrbyte;
|
||||
cnt++;
|
||||
}
|
||||
rb->lcd_update_rect(0, scanline & ~7, LCD_WIDTH, 8);
|
||||
#endif
|
||||
}
|
||||
|
||||
void vid_end(void)
|
||||
{
|
||||
}
|
||||
|
||||
long timerresult;
|
||||
|
||||
void *sys_timer(void)
|
||||
{
|
||||
timerresult=*rb->current_tick;
|
||||
return &timerresult;
|
||||
}
|
||||
|
||||
// returns microseconds passed since sys_timer
|
||||
int sys_elapsed(long *oldtick)
|
||||
{
|
||||
return ((*rb->current_tick-(*oldtick))*1000000)/HZ;
|
||||
}
|
||||
|
||||
void sys_sleep(int us)
|
||||
{
|
||||
if (us <= 0) return;
|
||||
// rb->sleep(HZ*us/1000000);
|
||||
}
|
|
@ -6,6 +6,8 @@ rvf,video.rock,5D 7F 5D 7F 5D 7F
|
|||
mp3,vbrfix.rock,10 08 58 38 04 02
|
||||
m3u,search.rock,00 00 00 00 00 00
|
||||
txt,sort.rock, 00 00 00 00 00 00
|
||||
gb,rockboy.rock, 0C 2A 59 7A 2E 0C
|
||||
cgb,rockboy.rock, 0C 2A 59 7A 2E 0C
|
||||
mp2,mpa2wav.rock, 00 00 00 00 00 00
|
||||
mp3,mpa2wav.rock, 00 00 00 00 00 00
|
||||
ac3,a52towav.rock, 00 00 00 00 00 00
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue