Initial Commit

This commit is contained in:
Ed Mandy 2016-10-14 11:01:29 -06:00
parent 705814d8bc
commit 0240f78550
105 changed files with 51867 additions and 0 deletions

76
DrZ80.h Normal file
View File

@ -0,0 +1,76 @@
/*
* DrZ80 Version 1.0
* Z80 Emulator by Reesy
* Copyright 2005 Reesy
*
* This file is part of DrZ80.
*
* DrZ80 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.
*
* DrZ80 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 DrZ80; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef DRZ80_H
#define DRZ80_H
extern int DrZ80Ver; /* Version number of library */
struct DrZ80
{
unsigned int Z80PC; /*0x00 - PC Program Counter (Memory Base + PC) */
unsigned int Z80A; /*0x04 - A Register: 0xAA------ */
unsigned int Z80F; /*0x08 - F Register: 0xFF------ */
unsigned int Z80BC; /*0x0C - BC Registers: 0xBBCC---- */
unsigned int Z80DE; /*0x10 - DE Registers: 0xDDEE---- */
unsigned int Z80HL; /*0x14 - HL Registers: 0xHHLL---- */
unsigned int Z80SP; /*0x18 - SP Stack Pointer (Memory Base + PC) */
unsigned int Z80PC_BASE; /*0x1C - PC Program Counter (Memory Base) */
unsigned int Z80SP_BASE; /*0x20 - SP Stack Pointer (Memory Base) */
unsigned int Z80IX; /*0x24 - IX Index Register */
unsigned int Z80IY; /*0x28 - IY Index Register */
unsigned int Z80I; /*0x2C - I Interrupt Register */
unsigned int Z80A2; /*0x30 - A' Register: 0xAA------ */
unsigned int Z80F2; /*0x34 - F' Register: 0xFF------ */
unsigned int Z80BC2; /*0x38 - B'C' Registers: 0xBBCC---- */
unsigned int Z80DE2; /*0x3C - D'E' Registers: 0xDDEE---- */
unsigned int Z80HL2; /*0x40 - H'L' Registers: 0xHHLL---- */
int cycles; /* Cycles pending to be executed yet */
int previouspc; /* Previous PC */
unsigned char Z80_IRQ; /*0x44 - Set IRQ Number */
unsigned char Z80IF; /*0x48 - Interrupt Flags: bit1=_IFF1, bit2=_IFF2, bit3=_HALT */
unsigned char Z80IM; /*0x4C - Set IRQ Mode */
unsigned char spare; /*0x4C - N/A */
unsigned int z80irqvector; /*0x38 - Set IRQ Vector i.e. 0xFF=RST */
void (*z80_irq_callback )(void);
void (*z80_write8 )(unsigned char d,unsigned short a);
void (*z80_write16 )(unsigned short d,unsigned short a);
unsigned char (*z80_in)(unsigned short p);
void (*z80_out )(unsigned short p,unsigned char d);
unsigned char (*z80_read8)(unsigned short a);
unsigned short (*z80_read16)(unsigned short a);
unsigned int (*z80_rebaseSP)(unsigned short new_sp);
unsigned int (*z80_rebasePC)(unsigned short new_pc);
};
extern void DrZ80Run(struct DrZ80 *pcy,unsigned int cyc);
#endif
#ifdef __cplusplus
} /* End of extern "C" */
#endif

7842
DrZ80.s Normal file

File diff suppressed because it is too large Load Diff

340
DrZ80_gpl.txt Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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
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) <year> <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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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) year 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.

323
DrZ80_support.cpp Normal file
View File

@ -0,0 +1,323 @@
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
//
// Support functions for interfacing with DrZ80
//
#ifndef __GP32__
#include "stdafx.h"
#endif
#include "main.h"
#include "memory.h"
//#include "mainemu.h"
#include "DrZ80_support.h"
#define INT_IRQ 0x01
#define NMI_IRQ 0x02
#define PUSH_PC() { Z80.regs.Z80SP=z80_rebaseSP(Z80.regs.Z80SP-Z80.regs.Z80SP_BASE-2); Z80.regs.z80_write16(Z80.regs.Z80PC - Z80.regs.Z80PC_BASE,Z80.regs.Z80SP - Z80.regs.Z80SP_BASE); }
/*#define PUSH_PC() { Z80.regs.Z80SP-=2; Z80.regs.z80_write16(Z80.regs.Z80PC - Z80.regs.Z80PC_BASE,Z80.regs.Z80SP); }*/
/*int Z80_ICount;*/
Z80_Regs Z80;
static unsigned int z80_rebaseSP(unsigned short address)
{
//Z80.regs.Z80SP_BASE = (unsigned int)&mainram[0x3000];
Z80.regs.Z80SP = Z80.regs.Z80SP_BASE + address;
return (Z80.regs.Z80SP);
}
static unsigned int z80_rebasePC(unsigned short address)
{
//Z80.regs.Z80PC_BASE = (unsigned int)&mainram[0x3000];
Z80.regs.Z80PC = Z80.regs.Z80PC_BASE + address;
return (Z80.regs.Z80PC);
}
static void z80_irq_callback(void)
{
Z80.regs.Z80_IRQ = 0x00;
}
/****************************************************************************
* Reset registers to their initial values
****************************************************************************/
void Z80_Reset(void)
{
memset (&Z80, 0, sizeof(Z80_Regs));
#ifdef DRZ80
Z80.regs.z80_rebasePC=z80_rebasePC;
Z80.regs.z80_rebaseSP=z80_rebaseSP /* 0 */;
Z80.regs.z80_read8 =z80MemReadB; /* z80_read8 */
Z80.regs.z80_read16 =z80MemReadW;
Z80.regs.z80_write8 =DrZ80ngpMemWriteB;
Z80.regs.z80_write16 =DrZ80ngpMemWriteW;
Z80.regs.z80_in =DrZ80ngpPortReadB;
Z80.regs.z80_out =DrZ80ngpPortWriteB;
//Z80.regs.z80_irq_callback=z80_irq_callback;
Z80.regs.z80_irq_callback=z80_irq_callback;
Z80.regs.Z80BC = 0013;
Z80.regs.Z80DE = 0x00D8;
Z80.regs.Z80HL = 0x014D;
/*
Z80.regs.Z80A = 0x00 <<24;
Z80.regs.Z80F = (1<<2); // set ZFlag
Z80.regs.Z80A2 = 0x00 <<24;
Z80.regs.Z80F2 = 1<<2; // set ZFlag
Z80.regs.Z80BC2 = 0x0000 <<16;
Z80.regs.Z80DE2 = 0x0000 <<16;
Z80.regs.Z80HL2 = 0x0000 <<16;
Z80.regs.Z80IX = 0xFFFF <<16;
Z80.regs.Z80IY = 0xFFFF <<16;
Z80.regs.Z80I = 0x00;
Z80.regs.Z80IM = 0x00;
Z80.regs.Z80_IRQ = 0x00;
Z80.regs.Z80IF = 0x00;
*/
//Z80.regs.Z80PC=Z80.regs.z80_rebasePC(0x0000);
//Z80.regs.Z80SP=Z80.regs.z80_rebaseSP(0xFFFE); /* 0xf000 */
Z80.regs.Z80SP_BASE = (unsigned int)&mainram[0x3000];
Z80.regs.Z80SP = Z80.regs.Z80SP_BASE + 0xFFFE;
Z80.regs.Z80PC_BASE = (unsigned int)&mainram[0x3000];
Z80.regs.Z80PC = Z80.regs.Z80PC_BASE + 0x0000;
Z80.request_irq = Z80.service_irq = -1;
Z80_Clear_Pending_Interrupts();
#endif
}
void Z80_Cause_Interrupt(int type)
{
/* type value : */
/* Z80_NMI_INT -> NMI request */
/* Z80_IGNORE_INT -> no request */
/* vector(0x00-0xff) -> SINGLE interrupt request */
/* Z80_VECTOR(device,status) -> DaisyChain change interrupt status */
/* device : device number of daisy-chain link */
/* status : Z80_INT_REQ -> interrupt request */
/* Z80_INT_IEO -> interrupt disable output */
if (type == Z80_NMI_INT)
{
Z80.pending_irq |= NMI_IRQ;
}
else if (type != Z80_IGNORE_INT)
{
if( Z80.irq_max )
{ /* daisy chain mode */
int device = type >> 8;
int state = type & 0xff;
if( Z80.int_state[device] != state )
{
/* set new interrupt status */
Z80.int_state[device] = state;
/* check interrupt status */
/* search highest interrupt request device (next interrupt device) */
/* and highest interrupt service device (next reti device) */
{
int device;
Z80.request_irq = Z80.service_irq = -1;
/* search higher IRQ or IEO */
for( device = 0 ; device < Z80.irq_max ; device ++ )
{
/* IEO = disable ? */
if( Z80.int_state[device] & Z80_INT_IEO )
{
/* if IEO is disable , masking lower IRQ */
Z80.request_irq = -1;
/* set highest interrupt service device */
Z80.service_irq = device;
}
/* IRQ = ON ? */
if( Z80.int_state[device] & Z80_INT_REQ )
Z80.request_irq = device;
}
/* set interrupt pending flag */
if( Z80.request_irq >= 0 )
Z80.pending_irq |= INT_IRQ;
else
Z80.pending_irq &= ~INT_IRQ;
}
}
}
else
{
/* single int mode */
Z80.regs.z80irqvector = type & 0xff;
Z80.pending_irq |= INT_IRQ;
}
}
}
void Z80_Clear_Pending_Interrupts(void)
{
int i;
/* clear irq for all devices */
for( i = 0 ; i < Z80_MAXDAISY ; i++ )
Z80.int_state[i] = 0;
Z80.pending_irq = 0;
Z80.service_irq = -1;
}
// Set all registers to given values
/*void Z80_SetRegs (Z80_Regs *Regs)
{
memcpy(&Z80,Regs,sizeof(Z80));
//change_pc(Z80.regs.Z80PC - Z80.regs.Z80PC_BASE);
}
// Get all registers in given buffer
void Z80_GetRegs (Z80_Regs *Regs)
{
memcpy(Regs,&Z80,sizeof(Z80));
}
// Return program counter
unsigned Z80_GetPC (void)
{
return (Z80.regs.Z80PC - Z80.regs.Z80PC_BASE);
}
int Z80_GetPreviousPC (void)
{
return (Z80.regs.previouspc);
}*/
void Interrupt(void)
{
/* This extra check is because DrZ80 calls this function directly but does
not have access to the Z80.pending_irq variable. So we check here instead. */
if(!Z80.pending_irq)
{
return;
} /* If no pending ints exit */
/* Check if ints enabled */
if ( (Z80.pending_irq & NMI_IRQ) || (Z80.regs.Z80IF&1) )
{
int irq_vector = Z80_IGNORE_INT;
/* there isn't a valid previouspc */
//{
//extern int previouspc;
//previouspc = -1;
// Z80.regs.previouspc=-1;
//}
/* DrZ80 Z80IF */
/* bit1 = _IFF1 */
/* bit2 = _IFF2 */
/* bit3 = _HALT */
/* Check if processor was halted */
if (Z80.regs.Z80IF&4)
{
Z80.regs.Z80PC=Z80.regs.z80_rebasePC(Z80.regs.Z80PC - Z80.regs.Z80PC_BASE + 1); /* Inc PC */
Z80.regs.Z80IF&= ~4; /* and clear halt */
}
if (Z80.pending_irq & NMI_IRQ)
{
Z80.regs.Z80IF = (Z80.regs.Z80IF&1)<<1; /* Save interrupt flip-flop 1 to 2 and Clear interrupt flip-flop 1 */
PUSH_PC();
Z80.regs.Z80PC=Z80.regs.z80_rebasePC(0x0066);
/* reset NMI interrupt request */
Z80.pending_irq &= ~NMI_IRQ;
}
else
{
/* Clear interrupt flip-flop 1 */
Z80.regs.Z80IF&= ~1;
/* reset INT interrupt request */
Z80.pending_irq &= ~INT_IRQ;
if ( Z80.irq_max )
{
if( Z80.request_irq >= 0 )
{
irq_vector = Z80.irq[Z80.request_irq].interrupt_entry(Z80.irq[Z80.request_irq].irq_param);
Z80.request_irq = -1;
}
}
else
{
irq_vector = Z80.regs.z80irqvector;
}
/* Interrupt mode 2. Call [Z80.I:databyte] */
if( Z80.regs.Z80IM == 2 )
{
/*irq_vector = (irq_vector & 0xff) | (Z80.regs.Z80I << 8);
PUSH_PC();
Z80.regs.Z80PC=Z80.regs.z80_rebasePC(Z80.regs.z80_read16(irq_vector));*/
}
else
{
/* Interrupt mode 1. RST 38h */
if( Z80.regs.Z80IM == 1 )
{
PUSH_PC();
Z80.regs.Z80PC=Z80.regs.z80_rebasePC(0x0038);
}
else
{
/* Interrupt mode 0. We check for CALL and JP instructions, */
/* if neither of these were found we assume a 1 byte opcode */
/* was placed on the databus */
/*switch (irq_vector & 0xff0000)
{
case 0xcd0000: /// call
PUSH_PC();
case 0xc30000: // jump
Z80.regs.Z80PC=Z80.regs.z80_rebasePC(irq_vector & 0xffff);
break;
default:
irq_vector &= 0xff;
PUSH_PC();
Z80.regs.Z80PC=Z80.regs.z80_rebasePC(0x0038);
break;
}*/
}
}
}
}
else
{
}
}
/****************************************************************************
* Execute IPeriod T-states. Return number of T-states really executed
****************************************************************************/
extern "C" int Z80_Execute(int cycles)
{
Z80.regs.cycles = cycles;
//Z80.regs.previouspc=(Z80.regs.Z80PC - Z80.regs.Z80PC_BASE);
if (Z80.pending_irq)
Interrupt();
DrZ80Run(&Z80.regs, cycles);
//change_pc(Z80.regs.Z80PC - Z80.regs.Z80PC_BASE);
return cycles;// (cycles-Z80.regs.cycles);
}

67
DrZ80_support.h Normal file
View File

@ -0,0 +1,67 @@
#ifndef Z80_H
#define Z80_H
#ifdef __cplusplus
extern "C" {
#endif
//#include "osd_cpu.h"
//#include "cpuintrf.h"
#include "DrZ80.h"
/* daisy-chain link */
typedef struct {
void (*reset)(int); /* reset callback */
int (*interrupt_entry)(int); /* entry callback */
void (*interrupt_reti)(int); /* reti callback */
int irq_param; /* callback paramater */
} Z80_DaisyChain;
#define Z80_MAXDAISY 4 /* maximum of daisy chan device */
#define Z80_INT_REQ 0x01 /* interrupt request mask */
#define Z80_INT_IEO 0x02 /* interrupt disable mask(IEO) */
#define Z80_VECTOR(device,state) (((device)<<8)|(state))
/****************************************************************************/
/* The Z80 registers. HALT is set to 1 when the CPU is halted, the refresh */
/* register is calculated as follows: refresh=(Regs.R&127)|(Regs.R2&128) */
/****************************************************************************/
typedef struct {
struct DrZ80 regs;
int pending_irq;
int irq_max; /* number of daisy chain devices */
int request_irq; /* daisy chain next request device */
int service_irq; /* daisy chain next reti handling device */
int int_state[Z80_MAXDAISY];
Z80_DaisyChain irq[Z80_MAXDAISY];
} Z80_Regs;
/*extern int Z80_ICount; // T-state count */
extern Z80_Regs Z80;
//#define Z80_ICount (Z80.regs.cycles)
#define Z80_IGNORE_INT -1 /* Ignore interrupt */
#define Z80_NMI_INT -2 /* Execute NMI */
#define Z80_IRQ_INT -1000 /* Execute IRQ */
extern unsigned Z80_GetPC (void); /* Get program counter */
extern int Z80_GetPreviousPC (void);
extern void Z80_GetRegs (Z80_Regs *Regs); /* Get registers */
extern void Z80_SetRegs (Z80_Regs *Regs); /* Set registers */
//extern void Z80_Reset (Z80_DaisyChain *daisy_chain);
extern void Z80_Reset(void);
extern int Z80_Execute(int cycles); /* Execute cycles T-States - returns number of cycles actually run */
extern int Z80_Interrupt(void);
extern void Z80_Cause_Interrupt(int type);
extern void Z80_Clear_Pending_Interrupts(void);
extern void Interrupt(void); /* required for DrZ80 int hack */
#ifdef __cplusplus
} /* End of extern "C" */
#endif
#endif

45
Makefile.psp Normal file
View File

@ -0,0 +1,45 @@
PSPSDK=$(shell psp-config --pspsdk-path)
PSPAPP=psp
PSPLIB=$(PSPAPP)/psplib
PSP_FW_VERSION=200
export PSP_FW_VERSION
PSP_APP_NAME=RACE! PSP
PSP_APP_VER=2.20
TARGET=racepsp
EXTRA_TARGETS=EBOOT.PBP
PSP_EBOOT_TITLE=$(PSP_APP_NAME) $(PSP_APP_VER)
PSP_EBOOT_ICON=$(PSPAPP)/race-icon.png
BUILD_EMUL=cz80.o cz80_support.o input.o neopopsound.o \
ngpBios.o tlcs900h.o memory.o flash.o graphics.o \
main.o state.o sound.o
BUILD_MZ=ioapi.o unzip.o
BUILD_PORT=$(PSPAPP)/main.o $(PSPAPP)/emulate.o $(PSPAPP)/menu.o
OBJS=$(BUILD_EMUL) $(BUILD_MZ) $(BUILD_PORT)
DEFINES=-DCZ80 -DTARGET_PSP -D_MAX_PATH=2048 -DHOST_FPS=60
BASE_DEFS=-DPSP -DPSP_APP_VER=\"$(PSP_APP_VER)\" -DPSP_APP_NAME="\"$(PSP_APP_NAME)\""
CFLAGS=-O2 -G0 -Wall $(BASE_DEFS) $(DEFINES)
CXXFLAGS=$(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS=$(CFLAGS)
INCDIR=$(PSPLIB)
LIBDIR=$(PSPLIB)
LIBS=-lpsplib -lpng -lpspgu -lpsppower \
-lz -lm -lc -lpspaudio -lpsprtc -lpspwlan -lpspnet_adhoc \
-lpspnet_adhocctl -lpspnet_adhocmatching
all: build_libs
clean: clean_libs
include $(PSPSDK)/lib/build.mak
build_libs:
cd $(PSPLIB) ; $(MAKE)
clean_libs:
cd $(PSPLIB) ; $(MAKE) clean

BIN
PARAM.SFO Normal file

Binary file not shown.

104
StdAfx.h Normal file
View File

@ -0,0 +1,104 @@
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
#ifndef STDAFX_H
#define STDAFX_H
#ifdef TARGET_PSP
#include <stdio.h>
#define DWORD unsigned int
#define byte unsigned char
#define _u8 unsigned char
#define Uint8 unsigned char
#define _u16 unsigned short
#define _u32 unsigned int
#define BOOL int
#define FALSE 0
#define TRUE (!0)
#define HWND void*
#else /* ifdef TARGET_PSP */
#ifdef TARGET_GP2X
//extern "C" void gp2x_memcpy(unsigned char *, unsigned char *, unsigned int);
#define memcpy gp2x_memcpy
#define memcmp gp2x_memcmp
//#define memset gp2x_memset
#define GENREGSPC_AS_REG //comment out to do it as a regular mem loc
#define GENREGSSR_AS_REG //comment out to do it as a regular mem loc
register unsigned char *my_pc asm ("r9");
register unsigned long opcode asm ("r6");
#ifdef GENREGSPC_AS_REG
register unsigned long gen_regsPC asm("r8");
#endif
#ifdef GENREGSSR_AS_REG
register unsigned long gen_regsSR asm("r7");
#endif
#endif
#include "StdAfx.h"
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
typedef unsigned int UINT32;
typedef unsigned int DWORD;
typedef void * HRESULT;
typedef unsigned char byte;
typedef unsigned char _u8;
typedef unsigned short _u16;
typedef unsigned int _u32;
#define MB_OK 1
typedef bool BOOL;
#define FALSE false
#define TRUE true
#ifndef _MAX_PATH
#define _MAX_PATH 150
#endif
#ifdef TARGET_WIN
#define DEBUG
#endif
#ifdef DEBUG
#define dbg_printf printf
#else
#define dbg_printf if(0) printf
#endif
#define dbg_print dbg_printf
void AfxMessageBox(char *a, int b, int c);
void AfxMessageBox(char *a, int b);
void AfxMessageBox(char *a);
#define HWND void*
#define BITMAP
#endif /* ifdef TARGET_PSP */
#endif //STDAFX_H

132
crypt.h Normal file
View File

@ -0,0 +1,132 @@
/* crypt.h -- base code for crypt/uncrypt ZIPfile
Version 1.00, September 10th, 2003
Copyright (C) 1998-2003 Gilles Vollant
This code is a modified version of crypting code in Infozip distribution
The encryption/decryption parts of this source code (as opposed to the
non-echoing password parts) were originally written in Europe. The
whole source package can be freely distributed, including from the USA.
(Prior to January 2000, re-export from the US was a violation of US law.)
This encryption code is a direct transcription of the algorithm from
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
file (appnote.txt) is distributed with the PKZIP program (even in the
version without encryption capabilities).
If you don't need crypting in your application, just define symbols
NOCRYPT and NOUNCRYPT.
This code support the "Traditional PKWARE Encryption".
The new AES encryption added on Zip format by Winzip (see the page
http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
Encryption is not supported.
*/
#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
/***********************************************************************
* Return the next byte in the pseudo-random sequence
*/
static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
{
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
* unpredictable manner on 16-bit systems; not a problem
* with any known compiler so far, though */
temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
}
/***********************************************************************
* Update the encryption keys with the next byte of plain text
*/
static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
{
(*(pkeys+0)) = CRC32((*(pkeys+0)), c);
(*(pkeys+1)) += (*(pkeys+0)) & 0xff;
(*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
{
register int keyshift = (int)((*(pkeys+1)) >> 24);
(*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
}
return c;
}
/***********************************************************************
* Initialize the encryption keys and the random header according to
* the given password.
*/
static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
{
*(pkeys+0) = 305419896L;
*(pkeys+1) = 591751049L;
*(pkeys+2) = 878082192L;
while (*passwd != '\0') {
update_keys(pkeys,pcrc_32_tab,(int)*passwd);
passwd++;
}
}
#define zdecode(pkeys,pcrc_32_tab,c) \
(update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
#define zencode(pkeys,pcrc_32_tab,c,t) \
(t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
#define RAND_HEAD_LEN 12
/* "last resort" source for second part of crypt seed pattern */
# ifndef ZCR_SEED2
# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
# endif
static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
const char *passwd; /* password string */
unsigned char *buf; /* where to write header */
int bufSize;
unsigned long* pkeys;
const unsigned long* pcrc_32_tab;
unsigned long crcForCrypting;
{
int n; /* index in random header */
int t; /* temporary */
int c; /* random byte */
unsigned char header[RAND_HEAD_LEN-2]; /* random header */
static unsigned calls = 0; /* ensure different random header each time */
if (bufSize<RAND_HEAD_LEN)
return 0;
/* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
* output of rand() to get less predictability, since rand() is
* often poorly implemented.
*/
if (++calls == 1)
{
srand((unsigned)(time(NULL) ^ ZCR_SEED2));
}
init_keys(passwd, pkeys, pcrc_32_tab);
for (n = 0; n < RAND_HEAD_LEN-2; n++)
{
c = (rand() >> 7) & 0xff;
header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
}
/* Encrypt random header (last two bytes is high word of crc) */
init_keys(passwd, pkeys, pcrc_32_tab);
for (n = 0; n < RAND_HEAD_LEN-2; n++)
{
buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
}
buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
return n;
}
#endif

376
cz80.cpp Normal file
View File

@ -0,0 +1,376 @@
/********************************************************************************/
/* */
/* CZ80 (Z80 CPU emulator) version 0.92 */
/* Compiled with Dev-C++ */
/* Copyright 2004-2005 Stéphane Dallongeville */
/* */
/********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*#ifdef GP2X
#include "gp2x/minimal.h"
#else
#include "sdl/minimal.h"
#endif*/
#include "StdAfx.h"
#include "main.h"
#include "memory.h"
#include "cz80.h"
// include macro file
//////////////////////
#include "cz80.inc"
// lookup tables
/////////////////
static u8 SZXY[256]; // zero and sign flags
static u8 SZXYP[256]; // zero, sign and parity flags
static u8 SZXY_BIT[256]; // zero, sign and parity/overflow (=zero) flags for BIT opcode
static u8 SZXYHV_inc[256]; // zero, sign, half carry and overflow flags INC R8
static u8 SZXYHV_dec[256]; // zero, sign, half carry and overflow flags DEC R8
#define fast_memset memset
// core main functions
///////////////////////
void Cz80_Init(cz80_struc *cpu)
{
u32 i, j, p;
fast_memset(cpu, 0, sizeof(cz80_struc));
// flags tables initialisation
for (i = 0; i < 256; i++)
{
SZXY[i] = i & (CZ80_SF | CZ80_YF | CZ80_XF);
if (!i) SZXY[i] |= CZ80_ZF;
SZXY_BIT[i] = i & (CZ80_SF | CZ80_YF | CZ80_XF);
if (!i) SZXY_BIT[i] |= CZ80_ZF | CZ80_PF;
for (j = 0, p = 0; j < 8; j++) if (i & (1 << j)) p++;
SZXYP[i] = SZXY[i];
if (!(p & 1)) SZXYP[i] |= CZ80_PF;
SZXYHV_inc[i] = SZXY[i];
if(i == 0x80) SZXYHV_inc[i] |= CZ80_VF;
if((i & 0x0F) == 0x00) SZXYHV_inc[i] |= CZ80_HF;
SZXYHV_dec[i] = SZXY[i] | CZ80_NF;
if (i == 0x7F) SZXYHV_dec[i] |= CZ80_VF;
if ((i & 0x0F) == 0x0F) SZXYHV_dec[i] |= CZ80_HF;
}
}
u32 Cz80_Reset(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
fast_memset(CPU, 0, (u32)(&(CPU->CycleSup)) - (u32)(&(CPU->BC)));
Cz80_Set_PC(CPU, 0);
zIX = 0xFFFF;
zIY = 0xFFFF;
#if CZ80_DEBUG
zF = CZ80_ZF;
#else
zSP = 0xFFFE;
zFA = 0xFFFF;
#endif
return CPU->Status;
}
/////////////////////////////////
void CZ80_FASTCALL Cz80_Enable(cz80_struc *cpu)
{
cpu->Status &= ~CZ80_DISABLE;
}
void CZ80_FASTCALL Cz80_Disable(cz80_struc *cpu)
{
cpu->Status |= CZ80_DISABLE;
}
/////////////////////////////////
#include "cz80exec.inc"
/////////////////////////////////
void CZ80_FASTCALL Cz80_Set_IRQ(cz80_struc *cpu, s32 vector)
{
cpu->IntVect = vector;
cpu->Status |= CZ80_HAS_INT;
cpu->CycleSup = cpu->CycleIO;
cpu->CycleIO = 0;
}
void CZ80_FASTCALL Cz80_Set_NMI(cz80_struc *cpu)
{
cpu->Status |= CZ80_HAS_NMI;
cpu->CycleSup = cpu->CycleIO;
cpu->CycleIO = 0;
}
void CZ80_FASTCALL Cz80_Clear_IRQ(cz80_struc *cpu)
{
cpu->Status &= ~CZ80_HAS_INT;
}
void CZ80_FASTCALL Cz80_Clear_NMI(cz80_struc *cpu)
{
cpu->Status &= ~CZ80_HAS_NMI;
}
/////////////////////////////////
s32 CZ80_FASTCALL Cz80_Get_CycleToDo(cz80_struc *cpu)
{
if (!(cpu->Status & CZ80_RUNNING)) return 0;
return cpu->CycleToDo;
}
s32 CZ80_FASTCALL Cz80_Get_CycleRemaining(cz80_struc *cpu)
{
if (!(cpu->Status & CZ80_RUNNING)) return 0;
return (cpu->CycleIO + cpu->CycleSup);
}
s32 CZ80_FASTCALL Cz80_Get_CycleDone(cz80_struc *cpu)
{
if (!(cpu->Status & CZ80_RUNNING)) return 0;
return (cpu->CycleToDo - (cpu->CycleIO + cpu->CycleSup));
}
void CZ80_FASTCALL Cz80_End_Execute(cz80_struc *cpu)
{
cpu->CycleToDo -= cpu->CycleIO + cpu->CycleSup;
cpu->CycleIO = cpu->CycleSup = 0;
}
void CZ80_FASTCALL Cz80_Waste_Cycle(cz80_struc *cpu, s32 cycle)
{
cpu->CycleIO -= cycle;
}
// externals main functions
////////////////////////////
u32 CZ80_FASTCALL Cz80_Get_BC(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
return zBC;
}
u32 CZ80_FASTCALL Cz80_Get_DE(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
return zDE;
}
u32 CZ80_FASTCALL Cz80_Get_HL(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
return zHL;
}
u32 CZ80_FASTCALL Cz80_Get_AF(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
return (zF | (zA << 8));
}
u32 CZ80_FASTCALL Cz80_Get_BC2(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
return zBC2;
}
u32 CZ80_FASTCALL Cz80_Get_DE2(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
return zDE2;
}
u32 CZ80_FASTCALL Cz80_Get_HL2(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
return zHL2;
}
u32 CZ80_FASTCALL Cz80_Get_AF2(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
return (zF2 | (zA2 << 8));
}
u32 CZ80_FASTCALL Cz80_Get_IX(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
return zIX;
}
u32 CZ80_FASTCALL Cz80_Get_IY(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
return zIY;
}
u32 CZ80_FASTCALL Cz80_Get_SP(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
return zSP;
}
u32 CZ80_FASTCALL Cz80_Get_PC(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
u8* PC = cpu->PC;
return zRealPC;
}
u32 CZ80_FASTCALL Cz80_Get_R(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
return zR;
}
u32 CZ80_FASTCALL Cz80_Get_IFF(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
u32 value = 0;
if (zIFF1 & CZ80_IFF) value |= 1;
if (zIFF2 & CZ80_IFF) value |= 2;
return value;
}
u32 CZ80_FASTCALL Cz80_Get_IM(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
return zIM;
}
u32 CZ80_FASTCALL Cz80_Get_I(cz80_struc *cpu)
{
cz80_struc *CPU = cpu;
return zI;
}
void CZ80_FASTCALL Cz80_Set_BC(cz80_struc *cpu, u32 value)
{
cz80_struc *CPU = cpu;
zBC = value;
}
void CZ80_FASTCALL Cz80_Set_DE(cz80_struc *cpu, u32 value)
{
cz80_struc *CPU = cpu;
zDE = value;
}
void CZ80_FASTCALL Cz80_Set_HL(cz80_struc *cpu, u32 value)
{
cz80_struc *CPU = cpu;
zHL = value;
}
void CZ80_FASTCALL Cz80_Set_AF(cz80_struc *cpu, u32 val)
{
cz80_struc *CPU = cpu;
zF = val;
zA = val >> 8;
}
void CZ80_FASTCALL Cz80_Set_BC2(cz80_struc *cpu, u32 value)
{
cz80_struc *CPU = cpu;
zBC2 = value;
}
void CZ80_FASTCALL Cz80_Set_DE2(cz80_struc *cpu, u32 value)
{
cz80_struc *CPU = cpu;
zDE2 = value;
}
void CZ80_FASTCALL Cz80_Set_HL2(cz80_struc *cpu, u32 value)
{
cz80_struc *CPU = cpu;
zHL2 = value;
}
void CZ80_FASTCALL Cz80_Set_AF2(cz80_struc *cpu, u32 val)
{
cz80_struc *CPU = cpu;
zF2 = val;
zA2 = val >> 8;
}
void CZ80_FASTCALL Cz80_Set_IX(cz80_struc *cpu, u32 value)
{
cz80_struc *CPU = cpu;
zIX = value;
}
void CZ80_FASTCALL Cz80_Set_IY(cz80_struc *cpu, u32 value)
{
cz80_struc *CPU = cpu;
zIY = value;
}
void CZ80_FASTCALL Cz80_Set_SP(cz80_struc *cpu, u32 value)
{
cz80_struc *CPU = cpu;
zSP = value;
}
void CZ80_FASTCALL Cz80_Set_PC(cz80_struc *cpu, u32 val)
{
#ifdef CZ80_USE_MAME_CHANGE_PC
change_pc16(val);
#endif
cpu->PC = (u8*)&mame4all_cz80_rom[val];
}
void CZ80_FASTCALL Cz80_Set_R(cz80_struc *cpu, u32 value)
{
cz80_struc *CPU = cpu;
zR = value & 0xFF;
zR2 = value & 0x80;
}
void CZ80_FASTCALL Cz80_Set_IFF(cz80_struc *cpu, u32 value)
{
cz80_struc *CPU = cpu;
zIFF = 0;
if (value & 1) zIFF1 = CZ80_IFF;
if (value & 2) zIFF2 = CZ80_IFF;
}
void CZ80_FASTCALL Cz80_Set_IM(cz80_struc *cpu, u32 value)
{
cz80_struc *CPU = cpu;
zIM = value & 3;
}
void CZ80_FASTCALL Cz80_Set_I(cz80_struc *cpu, u32 value)
{
cz80_struc *CPU = cpu;
zI = value & 0xFF;
}

262
cz80.h Normal file
View File

@ -0,0 +1,262 @@
/********************************************************************************/
/* */
/* CZ80 include file */
/* C Z80 emulator version 0.92 */
/* Copyright 2004-2005 St<53>phane Dallongeville */
/* */
/********************************************************************************/
#ifndef _CZ80_H_
#define _CZ80_H_
#if defined(__cplusplus) && !defined(USE_CPLUS)
extern "C" {
#endif
/******************************/
/* Compiler dependant defines */
/******************************/
#ifndef u8
#define u8 unsigned char
#endif
#ifndef s8
#define s8 char
#endif
#ifndef u16
#define u16 unsigned short
#endif
#ifndef s16
#define s16 short
#endif
#ifndef u32
#define u32 unsigned int
#endif
#ifndef s32
#define s32 int
#endif
//#define CZ80_FASTCALL __fastcall
#define CZ80_FASTCALL
/*************************************/
/* Z80 core Structures & definitions */
/*************************************/
#define CZ80_FETCH_BITS 4 // [4-12] default = 8
#define CZ80_FETCH_SFT (16 - CZ80_FETCH_BITS)
#define CZ80_FETCH_BANK (1 << CZ80_FETCH_BITS)
#define CZ80_LITTLE_ENDIAN 1
#define CZ80_USE_JUMPTABLE 1
#define CZ80_IRQ_CYCLES 1
#define CZ80_SIZE_OPT 1
#define CZ80_USE_WORD_HANDLER 0
#define CZ80_EXACT 0
#define CZ80_DEBUG 0
//use MAME's change_pc function or internal?
//#define CZ80_USE_MAME_CHANGE_PC
#define CZ80_SF_SFT 7
#define CZ80_ZF_SFT 6
#define CZ80_YF_SFT 5
#define CZ80_HF_SFT 4
#define CZ80_XF_SFT 3
#define CZ80_PF_SFT 2
#define CZ80_VF_SFT 2
#define CZ80_NF_SFT 1
#define CZ80_CF_SFT 0
#define CZ80_SF (1 << CZ80_SF_SFT)
#define CZ80_ZF (1 << CZ80_ZF_SFT)
#define CZ80_YF (1 << CZ80_YF_SFT)
#define CZ80_HF (1 << CZ80_HF_SFT)
#define CZ80_XF (1 << CZ80_XF_SFT)
#define CZ80_PF (1 << CZ80_PF_SFT)
#define CZ80_VF (1 << CZ80_VF_SFT)
#define CZ80_NF (1 << CZ80_NF_SFT)
#define CZ80_CF (1 << CZ80_CF_SFT)
#define CZ80_IFF_SFT CZ80_PF_SFT
#define CZ80_IFF CZ80_PF
#define CZ80_HAS_INT CZ80_IFF
#define CZ80_HAS_NMI 0x08
#define CZ80_RUNNING 0x10
#define CZ80_HALTED 0x20
#define CZ80_FAULTED 0x80
#define CZ80_DISABLE 0x40
typedef u32 CZ80_FASTCALL CZ80_READ(u32 adr);
typedef void CZ80_FASTCALL CZ80_WRITE(u32 adr, u32 data);
typedef void CZ80_FASTCALL CZ80_RETI_CALLBACK();
typedef s32 CZ80_FASTCALL CZ80_INT_CALLBACK(s32 param);
typedef union
{
u8 B;
s8 SB;
} union8;
typedef union
{
struct
{
#if CZ80_LITTLE_ENDIAN
u8 L;
u8 H;
#else
u8 H;
u8 L;
#endif
} B;
struct
{
#if CZ80_LITTLE_ENDIAN
s8 L;
s8 H;
#else
s8 H;
s8 L;
#endif
} SB;
u16 W;
s16 SW;
} union16;
typedef struct
{
union
{
u8 r8[8];
union16 r16[4];
struct
{
union16 BC; // 32 bytes aligned
union16 DE;
union16 HL;
union16 FA;
};
};
union16 IX;
union16 IY;
union16 SP;
u8 *PC;
union16 BC2;
union16 DE2;
union16 HL2;
union16 FA2;
union16 R;
union16 IFF;
u8 I;
u8 IM;
u8 IntVect;
u8 Status;
u32 BasePC;
u32 CycleIO;
u32 CycleToDo; // 32 bytes aligned
u32 CycleSup;
} cz80_struc;
/*************************/
/* Publics Z80 variables */
/*************************/
//extern cz80_struc CZ80;
/*************************/
/* Publics Z80 functions */
/*************************/
void Cz80_Init(cz80_struc *cpu);
u32 Cz80_Reset(cz80_struc *cpu);
u32 Cz80_Read_Byte(cz80_struc *cpu, u32 adr);
u32 Cz80_Read_Word(cz80_struc *cpu, u32 adr);
void Cz80_Write_Byte(cz80_struc *cpu, u32 adr, u32 data);
void Cz80_Write_Word(cz80_struc *cpu, u32 adr, u32 data);
void CZ80_FASTCALL Cz80_Enable(cz80_struc *cpu);
void CZ80_FASTCALL Cz80_Disable(cz80_struc *cpu);
s32 CZ80_FASTCALL Cz80_Exec(cz80_struc *cpu, s32 cycles);
void CZ80_FASTCALL Cz80_Set_IRQ(cz80_struc *cpu, s32 vector);
void CZ80_FASTCALL Cz80_Set_NMI(cz80_struc *cpu);
void CZ80_FASTCALL Cz80_Clear_IRQ(cz80_struc *cpu);
void CZ80_FASTCALL Cz80_Clear_NMI(cz80_struc *cpu);
s32 CZ80_FASTCALL Cz80_Get_CycleToDo(cz80_struc *cpu);
s32 CZ80_FASTCALL Cz80_Get_CycleRemaining(cz80_struc *cpu);
s32 CZ80_FASTCALL Cz80_Get_CycleDone(cz80_struc *cpu);
void CZ80_FASTCALL Cz80_End_Execute(cz80_struc *cpu);
void CZ80_FASTCALL Cz80_Waste_Cycle(cz80_struc *cpu, s32 cycle);
u32 CZ80_FASTCALL Cz80_Get_BC(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_DE(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_HL(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_AF(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_BC2(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_DE2(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_HL2(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_AF2(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_IX(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_IY(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_SP(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_PC(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_R(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_IFF(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_IM(cz80_struc *cpu);
u32 CZ80_FASTCALL Cz80_Get_I(cz80_struc *cpu);
void CZ80_FASTCALL Cz80_Set_BC(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_DE(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_HL(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_AF(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_BC2(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_DE2(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_HL2(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_AF2(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_IX(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_IY(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_SP(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_PC(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_R(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_IFF(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_IM(cz80_struc *cpu, u32 value);
void CZ80_FASTCALL Cz80_Set_I(cz80_struc *cpu, u32 value);
#if defined(__cplusplus) && !defined(USE_CPLUS)
};
#endif
#endif // _CZ80_H_

219
cz80.inc Normal file
View File

@ -0,0 +1,219 @@
/********************************************************************************/
/* */
/* CZ80 macro file */
/* C Z80 emulator version 0.92 */
/* Copyright 2004-2005 Stéphane Dallongeville */
/* */
/********************************************************************************/
// use zR8 for B/C/D/E/H/L registers only
// use zR16 for BC/DE/HL registers only
#ifdef CZ80_USE_MAME_CHANGE_PC
#include "memory.h"
#undef READ_WORD
#undef WRITE_WORD
#endif
//#define mame4all_cz80_rom OP_ROM
//#define mame4all_cz80_ram OP_RAM
extern unsigned char *mame4all_cz80_rom;
extern unsigned char *mame4all_cz80_ram;
int cpu_readmem16(int address);
void cpu_writemem16(int address,int data);
int cpu_readport(int Port);
void cpu_writeport(int Port,int Value);
#define zR8(A) CPU->r8[(A) ^ 1]
#define zR16(A) CPU->r16[A].W
#define pzR16(A) &(CPU->r16[A])
#define pzFA &(CPU->FA)
#define zFA CPU->FA.W
#define zlFA CPU->FA.B.L
#define zhFA CPU->FA.B.H
#define zA zlFA
#define zF zhFA
#define pzBC &(CPU->BC)
#define zBC CPU->BC.W
#define zlBC CPU->BC.B.L
#define zhBC CPU->BC.B.H
#define zB zhBC
#define zC zlBC
#define pzDE &(CPU->DE)
#define zDE CPU->DE.W
#define zlDE CPU->DE.B.L
#define zhDE CPU->DE.B.H
#define zD zhDE
#define zE zlDE
#define pzHL &(CPU->HL)
#define zHL CPU->HL.W
#define zlHL CPU->HL.B.L
#define zhHL CPU->HL.B.H
#define zH zhHL
#define zL zlHL
#define zFA2 CPU->FA2.W
#define zlFA2 CPU->FA2.B.L
#define zhFA2 CPU->FA2.B.H
#define zA2 zlFA2
#define zF2 zhFA2
#define zBC2 CPU->BC2.W
#define zDE2 CPU->DE2.W
#define zHL2 CPU->HL2.W
#define pzIX &(CPU->IX)
#define zIX CPU->IX.W
#define zlIX CPU->IX.B.L
#define zhIX CPU->IX.B.H
#define pzIY &(CPU->IY)
#define zIY CPU->IY.W
#define zlIY CPU->IY.B.L
#define zhIY CPU->IY.B.H
#define pzSP &(CPU->SP)
#define zSP CPU->SP.W
#define zlSP CPU->SP.B.L
#define zhSP CPU->SP.B.H
#define zPC PC
#define zRealPC ((u32)(PC) - ((u32)mame4all_cz80_rom))
#define zI CPU->I
#define zIM CPU->IM
#define zwR CPU->R.W
#define zR1 CPU->R.B.L
#define zR2 CPU->R.B.H
#define zR zR1
#define zIFF CPU->IFF.W
#define zIFF1 CPU->IFF.B.L
#define zIFF2 CPU->IFF.B.H
#if CZ80_USE_JUMPTABLE
#define _SSOP(A,B) A##B
#define OP(A) _SSOP(OP,A)
#define OPCB(A) _SSOP(OPCB,A)
#define OPED(A) _SSOP(OPED,A)
#define OPXY(A) _SSOP(OPXY,A)
#define OPXYCB(A) _SSOP(OPXYCB,A)
#else
#define OP(A) case A
#define OPCB(A) case A
#define OPED(A) case A
#define OPXY(A) case A
#define OPXYCB(A) case A
#endif
#define REAL_FETCH_BYTE \
(*zPC++)
#define REAL_FETCH_BYTE_S \
((s8)(*zPC++))
#define FETCH_BYTE(A) \
A = (mame4all_cz80_ram[((unsigned)zPC)-((unsigned)mame4all_cz80_rom)]); \
zPC++
#define FETCH_BYTE_S(A) \
A = ((s8)(mame4all_cz80_ram[((unsigned)zPC)-((unsigned)mame4all_cz80_rom)])); \
zPC++
#if CZ80_LITTLE_ENDIAN
#define FETCH_WORD(A) \
A= ((unsigned short)(mame4all_cz80_ram[((unsigned)zPC)-((unsigned)mame4all_cz80_rom)])) | (((unsigned short)(mame4all_cz80_ram[1+((unsigned)zPC)-((unsigned)mame4all_cz80_rom)])) << 8); \
zPC += 2
#else
#define FETCH_WORD(A) \
A= ((unsigned short)(mame4all_cz80_ram[1+((unsigned)zPC)-((unsigned)mame4all_cz80_rom)])) | (((unsigned short)(mame4all_cz80_ram[((unsigned)zPC)-((unsigned)mame4all_cz80_rom)])) << 8); \
zPC += 2
#endif
#if CZ80_SIZE_OPT
#define RET(A) \
Z80_ICount -= A; \
goto Cz80_Exec_Check;
#else
#define RET(A) \
if ((Z80_ICount -= A) <= 0) goto Cz80_Check_Int; \
goto Cz80_Exec;
#endif
#ifdef CZ80_USE_MAME_CHANGE_PC
#define SET_PC(A) \
change_pc16(A) \
zPC = (u8*)&mame4all_cz80_rom[A]
#else
#define SET_PC(A) zPC = (u8*)&mame4all_cz80_rom[A]
#endif
#define PRE_IO \
CPU->CycleIO = Z80_ICount;
#define POST_IO \
Z80_ICount = CPU->CycleIO;
#define READ_BYTE(A, D) \
D = cpu_readmem16(A);
#if CZ80_USE_WORD_HANDLER
#define READ_WORD(A, D) \
D = CPU->Read_Word(A);
#elif CZ80_LITTLE_ENDIAN
#define READ_WORD(A, D) \
D = cpu_readmem16(A) | (cpu_readmem16((A) + 1) << 8);
#else
#define READ_WORD(A, D) \
D = (cpu_readmem16(A) << 8) | cpu_readmem16((A) + 1);
#endif
#define READSX_BYTE(A, D) \
D = (s8)cpu_readmem16(A);
#define WRITE_BYTE(A, D) \
cpu_writemem16(A, D);
#if CZ80_USE_WORD_HANDLER
#define WRITE_WORD(A, D) \
cpu_writemem16(A, D);
#elif CZ80_LITTLE_ENDIAN
#define WRITE_WORD(A, D) \
cpu_writemem16(A, D); \
cpu_writemem16((A) + 1, (D) >> 8);
#else
#define WRITE_WORD(A, D) \
cpu_writemem16(A, D); \
cpu_writemem16((A) + 1, (D) >> 8);
#endif
#define PUSH_16(A) \
{ \
u32 sp; \
\
zSP -= 2; \
sp = zSP; \
WRITE_WORD(sp, A); \
}
#define POP_16(A) \
{ \
u32 sp; \
\
sp = zSP; \
READ_WORD(sp, A) \
zSP = sp + 2; \
}
#define IN(A, D) \
D = cpu_readport(A);
#define OUT(A, D) \
cpu_writeport(A, D);

1332
cz80_op.inc Normal file

File diff suppressed because it is too large Load Diff

548
cz80_opCB.inc Normal file
View File

@ -0,0 +1,548 @@
/********************************************************************************/
/* */
/* CZ80 CB opcode include source file */
/* C Z80 emulator version 0.92 */
/* Copyright 2004-2005 Stéphane Dallongeville */
/* */
/********************************************************************************/
#if CZ80_USE_JUMPTABLE
goto *JumpTableCB[Opcode];
#else
switch (Opcode)
{
#endif
OPCB(0x00): // RLC B
OPCB(0x01): // RLC C
OPCB(0x02): // RLC D
OPCB(0x03): // RLC E
OPCB(0x04): // RLC H
OPCB(0x05): // RLC L
OPCB(0x07): // RLC A
{
u8 src = zR8(Opcode);
zR8(Opcode) = (src << 1) | (src >> 7);
zF = SZXYP[zR8(Opcode)] | (src >> 7);
RET(4 + 4)
}
OPCB(0x06): // RLC (HL)
{
u32 adr;
u32 src;
u32 res;
PRE_IO
adr = zHL;
READ_BYTE(adr, src)
res = ((src << 1) | (src >> 7)) & 0xFF;
zF = SZXYP[res] | (src >> 7);
WRITE_BYTE(adr, res)
POST_IO
RET(11 + 4)
}
OPCB(0x08): // RRC B
OPCB(0x09): // RRC C
OPCB(0x0a): // RRC D
OPCB(0x0b): // RRC E
OPCB(0x0c): // RRC H
OPCB(0x0d): // RRC L
OPCB(0x0f): // RRC A
{
u8 src = zR8(Opcode & 7);
zR8(Opcode & 7) = (src >> 1) | (src << 7);
zF = SZXYP[zR8(Opcode & 7)] | (src & CZ80_CF);
RET(4 + 4)
}
OPCB(0x0e): // RRC (HL)
{
u32 adr;
u32 src;
u32 res;
PRE_IO
adr = zHL;
READ_BYTE(adr, src)
res = ((src >> 1) | (src << 7)) & 0xFF;
zF = SZXYP[res] | (src & CZ80_CF);
WRITE_BYTE(adr, res)
POST_IO
RET(11 + 4)
}
OPCB(0x10): // RL B
OPCB(0x11): // RL C
OPCB(0x12): // RL D
OPCB(0x13): // RL E
OPCB(0x14): // RL H
OPCB(0x15): // RL L
OPCB(0x17): // RL A
{
u8 src = zR8(Opcode & 7);
zR8(Opcode & 7) = (src << 1) | (zF & CZ80_CF);
zF = SZXYP[zR8(Opcode & 7)] | (src >> 7);
}
RET(4 + 4)
OPCB(0x16): // RL (HL)
{
u32 adr;
u32 src;
u32 res;
PRE_IO
adr = zHL;
READ_BYTE(adr, src)
res = ((src << 1) | (zF & CZ80_CF)) & 0xFF;
zF = SZXYP[res] | (src >> 7);
WRITE_BYTE(adr, res)
POST_IO
RET(11 + 4)
}
OPCB(0x18): // RR B
OPCB(0x19): // RR C
OPCB(0x1a): // RR D
OPCB(0x1b): // RR E
OPCB(0x1c): // RR H
OPCB(0x1d): // RR L
OPCB(0x1f): // RR A
{
u8 src = zR8(Opcode & 7);
zR8(Opcode & 7) = (src >> 1) | (zF << 7);
zF = SZXYP[zR8(Opcode & 7)] | (src & CZ80_CF);
}
RET(4 + 4)
OPCB(0x1e): // RR (HL)
{
u32 adr;
u32 src;
u32 res;
PRE_IO
adr = zHL;
READ_BYTE(adr, src)
res = ((src >> 1) | (zF << 7)) & 0xFF;
zF = SZXYP[res] | (src & CZ80_CF);
WRITE_BYTE(adr, res)
POST_IO
RET(11 + 4)
}
OPCB(0x20): // SLA B
OPCB(0x21): // SLA C
OPCB(0x22): // SLA D
OPCB(0x23): // SLA E
OPCB(0x24): // SLA H
OPCB(0x25): // SLA L
OPCB(0x27): // SLA A
{
u8 src = zR8(Opcode & 7);
zR8(Opcode & 7) = src << 1;
zF = SZXYP[zR8(Opcode & 7)] | (src >> 7);
}
RET(4 + 4)
OPCB(0x26): // SLA (HL)
{
u32 adr;
u32 src;
u32 res;
PRE_IO
adr = zHL;
READ_BYTE(adr, src)
res = (src << 1) & 0xFF;
zF = SZXYP[res] | (src >> 7);
WRITE_BYTE(adr, res)
POST_IO
RET(11 + 4)
}
OPCB(0x28): // SRA B
OPCB(0x29): // SRA C
OPCB(0x2a): // SRA D
OPCB(0x2b): // SRA E
OPCB(0x2c): // SRA H
OPCB(0x2d): // SRA L
OPCB(0x2f): // SRA A
{
s8 src = zR8(Opcode & 7);
zR8(Opcode & 7) = src >> 1;
zF = SZXYP[zR8(Opcode & 7)] | (src & CZ80_CF);
}
RET(4 + 4)
OPCB(0x2e): // SRA (HL)
{
u32 adr;
u32 src;
u32 res;
PRE_IO
adr = zHL;
READ_BYTE(adr, src)
res = (u8)(((s8)(src)) >> 1);
zF = SZXYP[res] | (src & CZ80_CF);
WRITE_BYTE(adr, res)
POST_IO
RET(11 + 4)
}
OPCB(0x30): // SLL B
OPCB(0x31): // SLL C
OPCB(0x32): // SLL D
OPCB(0x33): // SLL E
OPCB(0x34): // SLL H
OPCB(0x35): // SLL L
OPCB(0x37): // SLL A
{
u8 src = zR8(Opcode & 7);
zR8(Opcode & 7) = (src << 1) | 1;
zF = SZXYP[zR8(Opcode & 7)] | (src >> 7);
}
RET(4 + 4)
OPCB(0x36): // SLL (HL)
{
u32 adr;
u32 src;
u32 res;
PRE_IO
adr = zHL;
READ_BYTE(adr, src)
res = ((src << 1) | 1) & 0xFF;
zF = SZXYP[res] | (src >> 7);
WRITE_BYTE(adr, res)
POST_IO
RET(11 + 4)
}
OPCB(0x38): // SRL B
OPCB(0x39): // SRL C
OPCB(0x3a): // SRL D
OPCB(0x3b): // SRL E
OPCB(0x3c): // SRL H
OPCB(0x3d): // SRL L
OPCB(0x3f): // SRL A
{
u8 src = zR8(Opcode & 7);
zR8(Opcode & 7) = src >> 1;
zF = SZXYP[zR8(Opcode & 7)] | (src & CZ80_CF);
}
RET(4 + 4)
OPCB(0x3e): // SRL (HL)
{
u32 adr;
u32 src;
u32 res;
PRE_IO
adr = zHL;
READ_BYTE(adr, src)
res = src >> 1;
zF = SZXYP[res] | (src & CZ80_CF);
WRITE_BYTE(adr, res)
POST_IO
RET(11 + 4)
}
OPCB(0x40): // BIT 0,B
OPCB(0x41): // BIT 0,C
OPCB(0x42): // BIT 0,D
OPCB(0x43): // BIT 0,E
OPCB(0x44): // BIT 0,H
OPCB(0x45): // BIT 0,L
OPCB(0x47): // BIT 0,A
OPCB(0x48): // BIT 1,B
OPCB(0x49): // BIT 1,C
OPCB(0x4a): // BIT 1,D
OPCB(0x4b): // BIT 1,E
OPCB(0x4c): // BIT 1,H
OPCB(0x4d): // BIT 1,L
OPCB(0x4f): // BIT 1,A
OPCB(0x50): // BIT 2,B
OPCB(0x51): // BIT 2,C
OPCB(0x52): // BIT 2,D
OPCB(0x53): // BIT 2,E
OPCB(0x54): // BIT 2,H
OPCB(0x55): // BIT 2,L
OPCB(0x57): // BIT 2,A
OPCB(0x58): // BIT 3,B
OPCB(0x59): // BIT 3,C
OPCB(0x5a): // BIT 3,D
OPCB(0x5b): // BIT 3,E
OPCB(0x5c): // BIT 3,H
OPCB(0x5d): // BIT 3,L
OPCB(0x5f): // BIT 3,A
OPCB(0x60): // BIT 4,B
OPCB(0x61): // BIT 4,C
OPCB(0x62): // BIT 4,D
OPCB(0x63): // BIT 4,E
OPCB(0x64): // BIT 4,H
OPCB(0x65): // BIT 4,L
OPCB(0x67): // BIT 4,A
OPCB(0x68): // BIT 5,B
OPCB(0x69): // BIT 5,C
OPCB(0x6a): // BIT 5,D
OPCB(0x6b): // BIT 5,E
OPCB(0x6c): // BIT 5,H
OPCB(0x6d): // BIT 5,L
OPCB(0x6f): // BIT 5,A
OPCB(0x70): // BIT 6,B
OPCB(0x71): // BIT 6,C
OPCB(0x72): // BIT 6,D
OPCB(0x73): // BIT 6,E
OPCB(0x74): // BIT 6,H
OPCB(0x75): // BIT 6,L
OPCB(0x77): // BIT 6,A
OPCB(0x78): // BIT 7,B
OPCB(0x79): // BIT 7,C
OPCB(0x7a): // BIT 7,D
OPCB(0x7b): // BIT 7,E
OPCB(0x7c): // BIT 7,H
OPCB(0x7d): // BIT 7,L
OPCB(0x7f): // BIT 7,A
{
zF = (zF & CZ80_CF) | CZ80_HF |
SZXY_BIT[zR8(Opcode & 7) & (1 << ((Opcode >> 3) & 7))];
}
RET(4 + 4)
OPCB(0x46): // BIT 0,(HL)
OPCB(0x4e): // BIT 1,(HL)
OPCB(0x56): // BIT 2,(HL)
OPCB(0x5e): // BIT 3,(HL)
OPCB(0x66): // BIT 4,(HL)
OPCB(0x6e): // BIT 5,(HL)
OPCB(0x76): // BIT 6,(HL)
OPCB(0x7e): // BIT 7,(HL)
{
u32 src;
u32 bitm;
PRE_IO
bitm = 1 << ((Opcode >> 3) & 7);
READ_BYTE(zHL, src)
zF = (zF & CZ80_CF) | CZ80_HF | SZXY_BIT[src & bitm];
POST_IO
RET(8 + 4)
}
OPCB(0x80): // RES 0,B
OPCB(0x81): // RES 0,C
OPCB(0x82): // RES 0,D
OPCB(0x83): // RES 0,E
OPCB(0x84): // RES 0,H
OPCB(0x85): // RES 0,L
OPCB(0x87): // RES 0,A
OPCB(0x88): // RES 1,B
OPCB(0x89): // RES 1,C
OPCB(0x8a): // RES 1,D
OPCB(0x8b): // RES 1,E
OPCB(0x8c): // RES 1,H
OPCB(0x8d): // RES 1,L
OPCB(0x8f): // RES 1,A
OPCB(0x90): // RES 2,B
OPCB(0x91): // RES 2,C
OPCB(0x92): // RES 2,D
OPCB(0x93): // RES 2,E
OPCB(0x94): // RES 2,H
OPCB(0x95): // RES 2,L
OPCB(0x97): // RES 2,A
OPCB(0x98): // RES 3,B
OPCB(0x99): // RES 3,C
OPCB(0x9a): // RES 3,D
OPCB(0x9b): // RES 3,E
OPCB(0x9c): // RES 3,H
OPCB(0x9d): // RES 3,L
OPCB(0x9f): // RES 3,A
OPCB(0xa0): // RES 4,B
OPCB(0xa1): // RES 4,C
OPCB(0xa2): // RES 4,D
OPCB(0xa3): // RES 4,E
OPCB(0xa4): // RES 4,H
OPCB(0xa5): // RES 4,L
OPCB(0xa7): // RES 4,A
OPCB(0xa8): // RES 5,B
OPCB(0xa9): // RES 5,C
OPCB(0xaa): // RES 5,D
OPCB(0xab): // RES 5,E
OPCB(0xac): // RES 5,H
OPCB(0xad): // RES 5,L
OPCB(0xaf): // RES 5,A
OPCB(0xb0): // RES 6,B
OPCB(0xb1): // RES 6,C
OPCB(0xb2): // RES 6,D
OPCB(0xb3): // RES 6,E
OPCB(0xb4): // RES 6,H
OPCB(0xb5): // RES 6,L
OPCB(0xb7): // RES 6,A
OPCB(0xb8): // RES 7,B
OPCB(0xb9): // RES 7,C
OPCB(0xba): // RES 7,D
OPCB(0xbb): // RES 7,E
OPCB(0xbc): // RES 7,H
OPCB(0xbd): // RES 7,L
OPCB(0xbf): // RES 7,A
{
zR8(Opcode & 7) &= ~(1 << ((Opcode >> 3) & 7));
}
RET(4 + 4)
OPCB(0x86): // RES 0,(HL)
OPCB(0x8e): // RES 1,(HL)
OPCB(0x96): // RES 2,(HL)
OPCB(0x9e): // RES 3,(HL)
OPCB(0xa6): // RES 4,(HL)
OPCB(0xae): // RES 5,(HL)
OPCB(0xb6): // RES 6,(HL)
OPCB(0xbe): // RES 7,(HL)
{
u32 adr;
u32 res;
u32 bitm;
PRE_IO
adr = zHL;
bitm = ~(1 << ((Opcode >> 3) & 7));
READ_BYTE(adr, res)
res &= bitm;
WRITE_BYTE(adr, res)
POST_IO
RET(11 + 4)
}
OPCB(0xc0): // SET 0,B
OPCB(0xc1): // SET 0,C
OPCB(0xc2): // SET 0,D
OPCB(0xc3): // SET 0,E
OPCB(0xc4): // SET 0,H
OPCB(0xc5): // SET 0,L
OPCB(0xc7): // SET 0,A
OPCB(0xc8): // SET 1,B
OPCB(0xc9): // SET 1,C
OPCB(0xca): // SET 1,D
OPCB(0xcb): // SET 1,E
OPCB(0xcc): // SET 1,H
OPCB(0xcd): // SET 1,L
OPCB(0xcf): // SET 1,A
OPCB(0xd0): // SET 2,B
OPCB(0xd1): // SET 2,C
OPCB(0xd2): // SET 2,D
OPCB(0xd3): // SET 2,E
OPCB(0xd4): // SET 2,H
OPCB(0xd5): // SET 2,L
OPCB(0xd7): // SET 2,A
OPCB(0xd8): // SET 3,B
OPCB(0xd9): // SET 3,C
OPCB(0xda): // SET 3,D
OPCB(0xdb): // SET 3,E
OPCB(0xdc): // SET 3,H
OPCB(0xdd): // SET 3,L
OPCB(0xdf): // SET 3,A
OPCB(0xe0): // SET 4,B
OPCB(0xe1): // SET 4,C
OPCB(0xe2): // SET 4,D
OPCB(0xe3): // SET 4,E
OPCB(0xe4): // SET 4,H
OPCB(0xe5): // SET 4,L
OPCB(0xe7): // SET 4,A
OPCB(0xe8): // SET 5,B
OPCB(0xe9): // SET 5,C
OPCB(0xea): // SET 5,D
OPCB(0xeb): // SET 5,E
OPCB(0xec): // SET 5,H
OPCB(0xed): // SET 5,L
OPCB(0xef): // SET 5,A
OPCB(0xf0): // SET 6,B
OPCB(0xf1): // SET 6,C
OPCB(0xf2): // SET 6,D
OPCB(0xf3): // SET 6,E
OPCB(0xf4): // SET 6,H
OPCB(0xf5): // SET 6,L
OPCB(0xf7): // SET 6,A
OPCB(0xf8): // SET 7,B
OPCB(0xf9): // SET 7,C
OPCB(0xfa): // SET 7,D
OPCB(0xfb): // SET 7,E
OPCB(0xfc): // SET 7,H
OPCB(0xfd): // SET 7,L
OPCB(0xff): // SET 7,A
{
zR8(Opcode & 7) |= 1 << ((Opcode >> 3) & 7);
}
RET(4 + 4)
OPCB(0xc6): // SET 0,(HL)
OPCB(0xce): // SET 1,(HL)
OPCB(0xd6): // SET 2,(HL)
OPCB(0xde): // SET 3,(HL)
OPCB(0xe6): // SET 4,(HL)
OPCB(0xee): // SET 5,(HL)
OPCB(0xf6): // SET 6,(HL)
OPCB(0xfe): // SET 7,(HL)
{
u32 adr;
u32 res;
u32 bitm;
PRE_IO
adr = zHL;
bitm = 1 << ((Opcode >> 3) & 7);
READ_BYTE(adr, res)
res |= bitm;
WRITE_BYTE(adr, res)
POST_IO
RET(11 + 4)
}
#if CZ80_USE_JUMPTABLE
#else
}
#endif

823
cz80_opED.inc Normal file
View File

@ -0,0 +1,823 @@
/********************************************************************************/
/* */
/* CZ80 ED opcode include source file */
/* C Z80 emulator version 0.92 */
/* Copyright 2004-2005 Stéphane Dallongeville */
/* */
/********************************************************************************/
#if CZ80_USE_JUMPTABLE
goto *JumpTableED[Opcode];
#else
switch (Opcode)
{
#endif
// ILLEGAL
OPED(0x00):
OPED(0x01):
OPED(0x02):
OPED(0x03):
OPED(0x04):
OPED(0x05):
OPED(0x06):
OPED(0x07):
OPED(0x08):
OPED(0x09):
OPED(0x0a):
OPED(0x0b):
OPED(0x0c):
OPED(0x0d):
OPED(0x0e):
OPED(0x0f):
OPED(0x10):
OPED(0x11):
OPED(0x12):
OPED(0x13):
OPED(0x14):
OPED(0x15):
OPED(0x16):
OPED(0x17):
OPED(0x18):
OPED(0x19):
OPED(0x1a):
OPED(0x1b):
OPED(0x1c):
OPED(0x1d):
OPED(0x1e):
OPED(0x1f):
OPED(0x20):
OPED(0x21):
OPED(0x22):
OPED(0x23):
OPED(0x24):
OPED(0x25):
OPED(0x26):
OPED(0x27):
OPED(0x28):
OPED(0x29):
OPED(0x2a):
OPED(0x2b):
OPED(0x2c):
OPED(0x2d):
OPED(0x2e):
OPED(0x2f):
OPED(0x30):
OPED(0x31):
OPED(0x32):
OPED(0x33):
OPED(0x34):
OPED(0x35):
OPED(0x36):
OPED(0x37):
OPED(0x38):
OPED(0x39):
OPED(0x3a):
OPED(0x3b):
OPED(0x3c):
OPED(0x3d):
OPED(0x3e):
OPED(0x3f):
OPED(0xbc):
OPED(0xbd):
OPED(0xbe):
OPED(0xbf):
OPED(0xc0):
OPED(0xc1):
OPED(0xc2):
OPED(0xc3):
OPED(0xc4):
OPED(0xc5):
OPED(0xc6):
OPED(0xc7):
OPED(0xc8):
OPED(0xc9):
OPED(0xca):
OPED(0xcb):
OPED(0xcc):
OPED(0xcd):
OPED(0xce):
OPED(0xcf):
OPED(0xd0):
OPED(0xd1):
OPED(0xd2):
OPED(0xd3):
OPED(0xd4):
OPED(0xd5):
OPED(0xd6):
OPED(0xd7):
OPED(0xd8):
OPED(0xd9):
OPED(0xda):
OPED(0xdb):
OPED(0xdc):
OPED(0xdd):
OPED(0xde):
OPED(0xdf):
OPED(0xe0):
OPED(0xe1):
OPED(0xe2):
OPED(0xe3):
OPED(0xe4):
OPED(0xe5):
OPED(0xe6):
OPED(0xe7):
OPED(0xe8):
OPED(0xe9):
OPED(0xea):
OPED(0xeb):
OPED(0xec):
OPED(0xed):
OPED(0xee):
OPED(0xef):
OPED(0xf0):
OPED(0xf1):
OPED(0xf2):
OPED(0xf3):
OPED(0xf4):
OPED(0xf5):
OPED(0xf6):
OPED(0xf7):
OPED(0xf8):
OPED(0xf9):
OPED(0xfa):
OPED(0xfb):
OPED(0xfc):
OPED(0xfd):
OPED(0xfe):
OPED(0xff):
OPED(0x77):
OPED(0x7f):
OPED(0x80):
OPED(0x81):
OPED(0x82):
OPED(0x83):
OPED(0x84):
OPED(0x85):
OPED(0x86):
OPED(0x87):
OPED(0x88):
OPED(0x89):
OPED(0x8a):
OPED(0x8b):
OPED(0x8c):
OPED(0x8d):
OPED(0x8e):
OPED(0x8f):
OPED(0x90):
OPED(0x91):
OPED(0x92):
OPED(0x93):
OPED(0x94):
OPED(0x95):
OPED(0x96):
OPED(0x97):
OPED(0x98):
OPED(0x99):
OPED(0x9a):
OPED(0x9b):
OPED(0x9c):
OPED(0x9d):
OPED(0x9e):
OPED(0x9f):
OPED(0xa4):
OPED(0xa5):
OPED(0xa6):
OPED(0xa7):
OPED(0xac):
OPED(0xad):
OPED(0xae):
OPED(0xaf):
OPED(0xb4):
OPED(0xb5):
OPED(0xb6):
OPED(0xb7):
goto OP_NOP;
OPED(0x43): // LD (w),BC
data = pzBC;
goto OP_LD_mNN_xx;
OPED(0x53): // LD (w),DE
data = pzDE;
goto OP_LD_mNN_xx;
OPED(0x63): // LD (w),HL
data = pzHL;
goto OP_LD_mNN_xx;
OPED(0x73): // LD (w),SP
data = pzSP;
goto OP_LD_mNN_xx;
OPED(0x4b): // LD BC,(w)
data = pzBC;
goto OP_LD_xx_mNN;
OPED(0x5b): // LD DE,(w)
data = pzDE;
goto OP_LD_xx_mNN;
OPED(0x6b): // LD HL,(w)
data = pzHL;
goto OP_LD_xx_mNN;
OPED(0x7b): // LD SP,(w)
data = pzSP;
goto OP_LD_xx_mNN;
OPED(0x47): // LD I,A
zI = zA;
RET(5)
OPED(0x4f): // LD R,A
zR = zA - ((CPU->CycleToDo - Z80_ICount) / 4);
zR2 = zA & 0x80;
RET(5)
OPED(0x57): // LD A,I
{
u8 F;
zA = zI;
F = zF & CZ80_CF;
F |= zA & (CZ80_SF | CZ80_YF | CZ80_XF);
F |= zIFF2;
if (!zA) F |= CZ80_ZF;
zF = F;
RET(5)
}
OPED(0x5f): // LD A,R
{
u8 F;
zA = zR2 + ((zR + ((CPU->CycleToDo - Z80_ICount) / 4)) & 0x7F);
F = zF & CZ80_CF;
F |= zA & (CZ80_SF | CZ80_YF | CZ80_XF);
F |= zIFF2;
if (!zA) F |= CZ80_ZF;
zF = F;
RET(5)
}
OPED(0x5c): // NEG
OPED(0x54): // NEG
OPED(0x4c): // NEG
OPED(0x44): // NEG
OPED(0x64): // NEG
OPED(0x6c): // NEG
OPED(0x74): // NEG
OPED(0x7c): // NEG
{
u32 val;
u32 res;
val = zA;
res = 0 - val;
zF = SZXY[res & 0xFF] | // S/Z/X/Y flag
((res ^ val) & CZ80_HF) | // H flag
(((val & res) & 0x80) >> 5) | // V flag
((res >> 8) & CZ80_CF) | CZ80_NF; // C/N flag
zA = res;
RET(4)
}
OPED(0x67): // RRD (HL)
{
u32 adr;
u8 src;
PRE_IO
adr = zHL;
READ_BYTE(adr, src)
WRITE_BYTE(adr, (src >> 4) | (zA << 4))
zA = (zA & 0xF0) | (src & 0x0F);
zF = SZXYP[zA] | (zF & CZ80_CF);
POST_IO
RET(14)
}
OPED(0x6f): // RLD (HL)
{
u32 adr;
u8 src;
PRE_IO
adr = zHL;
READ_BYTE(adr, src)
WRITE_BYTE(adr, (src << 4) | (zA & 0x0F))
zA = (zA & 0xF0) | (src >> 4);
zF = SZXYP[zA] | (zF & CZ80_CF);
POST_IO
RET(14)
}
{
u32 src;
u32 res;
OPED(0x7a): // ADC HL,SP
src = zSP;
goto OP_ADC_HL;
OPED(0x4a): // ADC HL,BC
OPED(0x5a): // ADC HL,DE
OPED(0x6a): // ADC HL,HL
src = zR16((Opcode >> 4) & 3);
OP_ADC_HL:
res = zHL + src + (zF & CZ80_CF);
zF = (((src ^ zHL ^ res) >> 8) & CZ80_HF) | // H flag
(((src ^ zHL ^ 0x8000) & (src ^ res) & 0x8000) >> 13) | // V flag
((res >> 8) & (CZ80_SF | CZ80_XF | CZ80_YF)) | // S/X/Y flag
((res >> 16) & CZ80_CF) | // C flag
((res & 0xFFFF) ? 0 : CZ80_ZF); // Z flag
zHL = res;
RET(11)
OPED(0x72): // SBC HL,SP
src = zSP;
goto OP_SBC_HL;
OPED(0x42): // SBC HL,BC
OPED(0x52): // SBC HL,DE
OPED(0x62): // SBC HL,HL
src = zR16((Opcode >> 4) & 3);
OP_SBC_HL:
res = zHL - src + (zF & CZ80_CF);
#if CZ80_DEBUG
zF = (((src ^ zHL ^ res) >> 8) & CZ80_HF) | CZ80_NF | // H/N flag
(((src ^ zHL) & (zHL ^ res) & 0x8000) >> 13) | // V flag
((res >> 8) & CZ80_SF) | // S flag
((res >> 16) & CZ80_CF) | // C flag
((res & 0xFFFF) ? 0 : CZ80_ZF); // Z flag
#else
zF = (((src ^ zHL ^ res) >> 8) & CZ80_HF) | CZ80_NF | // H/N flag
(((src ^ zHL) & (zHL ^ res) & 0x8000) >> 13) | // V flag
((res >> 8) & (CZ80_SF | CZ80_XF | CZ80_YF)) | // S/X/Y flag
((res >> 16) & CZ80_CF) | // C flag
((res & 0xFFFF) ? 0 : CZ80_ZF); // Z flag
#endif
zHL = res;
RET(11)
}
{
u32 res;
OPED(0x40): // IN B,(C)
OPED(0x48): // IN C,(C)
OPED(0x50): // IN D,(C)
OPED(0x58): // IN E,(C)
OPED(0x60): // IN H,(C)
OPED(0x68): // IN L,(C)
OPED(0x78): // IN E,(C)
IN(zBC, res);
zR8((Opcode >> 3) & 7) = res;
zF = (zF & CZ80_CF) | SZXYP[res];
RET(8)
OPED(0x70): // IN 0,(C)
IN(zBC, res);
zF = (zF & CZ80_CF) | SZXYP[res];
RET(8)
}
{
u32 src;
OPED(0x71): // OUT (C),0
src = 0;
goto OP_OUT_mBC;
OPED(0x51): // OUT (C),D
OPED(0x41): // OUT (C),B
OPED(0x49): // OUT (C),C
OPED(0x59): // OUT (C),E
OPED(0x61): // OUT (C),H
OPED(0x69): // OUT (C),L
OPED(0x79): // OUT (C),E
src = zR8((Opcode >> 3) & 7);
OP_OUT_mBC:
OUT(zBC, src);
RET(8)
}
{
u32 newPC;
OPED(0x4d): // RETI
OPED(0x5d): // RETI
OPED(0x6d): // RETI
OPED(0x7d): // RETI
// if (CPU->RetI) CPU->RetI();
OPED(0x45): // RETN;
OPED(0x55): // RETN;
OPED(0x65): // RETN;
OPED(0x75): // RETN;
PRE_IO
POP_16(newPC);
SET_PC(newPC);
POST_IO
zIFF1 = zIFF2;
Z80_ICount -= 10;
// we need to test for interrupt
goto Cz80_Check_Int;
}
OPED(0x46): // IM 0
OPED(0x4e): // IM 0
OPED(0x66): // IM 0
OPED(0x6e): // IM 0
zIM = 0;
RET(4)
OPED(0x76): // IM 1
OPED(0x56): // IM 1
zIM = 1;
RET(4)
OPED(0x5e): // IM 2
OPED(0x7e): // IM 2
zIM = 2;
RET(4)
{
u8 val;
u8 F;
OPED(0xa8): // LDD
PRE_IO
READ_BYTE(zHL--, val)
WRITE_BYTE(zDE--, val)
goto OP_LDX;
OPED(0xa0): // LDI
PRE_IO
READ_BYTE(zHL++, val)
WRITE_BYTE(zDE++, val)
OP_LDX:
#if CZ80_EXACT
val += zA;
F = (zF & (CZ80_SF | CZ80_ZF | CZ80_CF)) |
(val & CZ80_XF) | ((val << 4) & CZ80_YF);
#else
F = zF & (CZ80_SF | CZ80_ZF | CZ80_YF | CZ80_XF | CZ80_CF);
#endif
if (--zBC) F |= CZ80_PF;
zF = F;
POST_IO
RET(12)
}
{
u8 val;
u8 F;
OPED(0xb8): // LDDR
do
{
PRE_IO
READ_BYTE(zHL--, val)
WRITE_BYTE(zDE--, val)
POST_IO
zBC--;
Z80_ICount -= 21;
} while ((zBC) && (Z80_ICount > -4));
goto OP_LDXR;
OPED(0xb0): // LDIR
do
{
PRE_IO
READ_BYTE(zHL++, val)
WRITE_BYTE(zDE++, val)
POST_IO
zBC--;
Z80_ICount -= 21;
} while ((zBC) && (Z80_ICount > -4));
OP_LDXR:
#if CZ80_EXACT
val += zA;
F = (zF & (CZ80_SF | CZ80_ZF | CZ80_CF)) |
(val & CZ80_XF) | ((val << 4) & CZ80_YF);
#else
F = zF & (CZ80_SF | CZ80_ZF | CZ80_YF | CZ80_XF | CZ80_CF);
#endif
if (zBC)
{
// instruction not yet completed...
// we will continu it at next CZ80_Exec
zF = F | CZ80_PF;
zPC -= 2;
Z80_ICount += 4;
goto Cz80_Check_Int;
}
// instruction completed...
zF = F;
RET(-(5 + 4))
}
{
u8 val;
u8 res;
u8 F;
OPED(0xa9): // CPD
PRE_IO
READ_BYTE(zHL--, val)
goto OP_CPX;
OPED(0xa1): // CPI
PRE_IO
READ_BYTE(zHL++, val)
OP_CPX:
res = zA - val;
#if CZ80_EXACT
F = (zF & CZ80_CF) | (SZXY[res] & ~(CZ80_YF | CZ80_XF)) |
((zA ^ val ^ res) & CZ80_HF) | CZ80_NF;
if (F & CZ80_HF) res--;
F |= (res & CZ80_XF) | ((res >> 4) & CZ80_YF);
#else
F = (zF & CZ80_CF) | SZXY[res] |
((zA ^ val ^ res) & CZ80_HF) | CZ80_NF;
#endif
if (--zBC) F |= CZ80_PF;
zF = F;
POST_IO
RET(12)
}
{
u32 val;
u32 res;
u8 F;
OPED(0xb9): // CPDR
do
{
PRE_IO
READ_BYTE(zHL--, val)
res = zA - val;
POST_IO
zBC--;
Z80_ICount -= 21;
} while ((zBC) && (res) && (Z80_ICount > -4));
goto OP_CPXR;
OPED(0xb1): // CPIR
do
{
PRE_IO
READ_BYTE(zHL++, val)
res = zA - val;
POST_IO
zBC--;
Z80_ICount -= 21;
} while ((zBC) && (res) && (Z80_ICount > -4));
OP_CPXR:
#if CZ80_EXACT
F = (zF & CZ80_CF) | (SZXY[res] & ~(CZ80_YF | CZ80_XF)) |
((zA ^ val ^ res) & CZ80_HF) | CZ80_NF;
if (F & CZ80_HF) res--;
F |= (res & CZ80_XF) | ((res >> 4) & CZ80_YF);
#else
F = (zF & CZ80_CF) | SZXY[res] |
((zA ^ val ^ res) & CZ80_HF) | CZ80_NF;
#endif
if (zBC)
{
// instruction not yet completed...
// we will continu it at next CZ80_Exec
zF = F | CZ80_PF;
zPC -= 2;
Z80_ICount += 4;
goto Cz80_Check_Int;
}
// instruction completed...
zF = F;
RET(-(3 + 4))
}
{
u8 val;
#if CZ80_EXACT
u8 F;
#endif
OPED(0xaa): // IND
PRE_IO
IN(zBC, val)
WRITE_BYTE(zHL--, val)
#if CZ80_EXACT
if ((((zC - 1) & 0xFF) + val) & 0x100)
{
F = CZ80_HF | CZ80_CF;
goto OP_INX;
}
F = 0;
#endif
goto OP_INX;
OPED(0xa2): // INI
PRE_IO
IN(zBC, val)
WRITE_BYTE(zHL++, val)
#if CZ80_EXACT
if ((((zC + 1) & 0xFF) + val) & 0x100)
{
F = CZ80_HF | CZ80_CF;
goto OP_INX;
}
F = 0;
#endif
OP_INX:
#if CZ80_EXACT
// P FLAG isn't correct here !
zF = F | (SZXY[--zB] + ((val >> 6) & CZ80_NF) + (val & CZ80_PF));
#else
zF = SZXY[--zB] + ((val >> 6) & CZ80_NF);
#endif
POST_IO
RET(12)
}
{
u8 val;
#if CZ80_EXACT
u8 F;
#endif
OPED(0xba): // INDR
do
{
PRE_IO
IN(zBC, val)
WRITE_BYTE(zHL--, val)
POST_IO
zB--;
Z80_ICount -= 21;
} while ((zB) && (Z80_ICount > -4));
#if CZ80_EXACT
if ((((zC - 1) & 0xFF) + val) & 0x100)
{
F = CZ80_HF | CZ80_CF;
goto OP_INXR;
}
F = 0;
#endif
goto OP_INXR;
OPED(0xb2): // INIR
do
{
PRE_IO
IN(zBC, val)
WRITE_BYTE(zHL++, val)
POST_IO
zB--;
Z80_ICount -= 21;
} while ((zB) && (Z80_ICount > -4));
#if CZ80_EXACT
if ((((zC + 1) & 0xFF) + val) & 0x100)
{
F = CZ80_HF | CZ80_CF;
goto OP_INXR;
}
F = 0;
#endif
OP_INXR:
#if CZ80_EXACT
// P FLAG isn't correct here !
zF = F | (SZXY[zB] + ((val >> 6) & CZ80_NF) + (val & CZ80_PF));
#else
zF = SZXY[zB] + ((val >> 6) & CZ80_NF);
#endif
if (zB)
{
// instruction not yet completed...
// we will continu it at next CZ80_Exec
zPC -= 2;
Z80_ICount += 4;
goto Cz80_Check_Int;
}
// instruction completed...
RET(-(5 + 4))
}
{
u8 val;
#if CZ80_EXACT
u8 F;
#endif
OPED(0xab): // OUTD
PRE_IO
READ_BYTE(zHL--, val)
OUT(zBC, val)
goto OP_OUTX;
OPED(0xa3): // OUTI
PRE_IO
READ_BYTE(zHL++, val)
OUT(zBC, val)
OP_OUTX:
#if CZ80_EXACT
// P FLAG isn't correct here !
F = SZXY[--zB] + ((val >> 6) & CZ80_NF) + (val & CZ80_PF);
if ((val + zL) & 0x100) F |= CZ80_HF | CZ80_CF;
zF = F;
#else
zF = SZXY[--zB] + ((val >> 6) & CZ80_NF);
#endif
POST_IO
RET(12)
}
{
u8 val;
#if CZ80_EXACT
u8 F;
#endif
OPED(0xbb): // OUTDR
do
{
PRE_IO
READ_BYTE(zHL--, val)
OUT(zBC, val)
POST_IO
zB--;
Z80_ICount -= 21;
} while ((zB) && (Z80_ICount > -4));
goto OP_OUTXR;
OPED(0xb3): // OUTIR
do
{
PRE_IO
READ_BYTE(zHL++, val)
OUT(zBC, val)
POST_IO
zB--;
Z80_ICount -= 21;
} while ((zB) && (Z80_ICount > -4));
OP_OUTXR:
#if CZ80_EXACT
// P FLAG isn't correct here !
F = SZXY[zB] + ((val >> 6) & CZ80_NF) + (val & CZ80_PF);
if ((val + zL) & 0x100) F |= CZ80_HF | CZ80_CF;
zF = F;
#else
zF = SZXY[zB] + ((val >> 6) & CZ80_NF);
#endif
if (zB)
{
// instruction not yet completed...
// we will continu it at next CZ80_Exec
zPC -= 2;
Z80_ICount += 4;
goto Cz80_Check_Int;
}
// instruction not yet completed...
RET(-(5 + 4))
}
#if CZ80_USE_JUMPTABLE
#else
}
#endif

714
cz80_opXY.inc Normal file
View File

@ -0,0 +1,714 @@
/********************************************************************************/
/* */
/* CZ80 XY opcode include source file */
/* C Z80 emulator version 0.92 */
/* Copyright 2004-2005 Stéphane Dallongeville */
/* */
/********************************************************************************/
#if CZ80_USE_JUMPTABLE
goto *JumpTableXY[Opcode];
#else
switch (Opcode)
{
#endif
OPXY(0x00): // NOP
// 8 BITS LOAD
OPXY(0x40): // LD B,B
OPXY(0x49): // LD C,C
OPXY(0x52): // LD D,D
OPXY(0x5b): // LD E,E
OPXY(0x64): // LD H,H
OPXY(0x6d): // LD L,L
OPXY(0x7f): // LD A,A
goto OP_NOP;
OPXY(0x41): // LD B,C
OPXY(0x42): // LD B,D
OPXY(0x43): // LD B,E
OPXY(0x47): // LD B,A
OPXY(0x48): // LD C,B
OPXY(0x4a): // LD C,D
OPXY(0x4b): // LD C,E
OPXY(0x4f): // LD C,A
OPXY(0x50): // LD D,B
OPXY(0x51): // LD D,C
OPXY(0x53): // LD D,E
OPXY(0x57): // LD D,A
OPXY(0x58): // LD E,B
OPXY(0x59): // LD E,C
OPXY(0x5a): // LD E,D
OPXY(0x5f): // LD E,A
OPXY(0x78): // LD A,B
OPXY(0x79): // LD A,C
OPXY(0x7a): // LD A,D
OPXY(0x7b): // LD A,E
goto OP_LD_R_R;
OPXY(0x44): // LD B,HX
OPXY(0x4c): // LD C,HX
OPXY(0x54): // LD D,HX
OPXY(0x5c): // LD E,HX
OPXY(0x7c): // LD A,HX
zR8((Opcode >> 3) & 7) = data->B.H;
RET(4)
OPXY(0x45): // LD B,LX
OPXY(0x4d): // LD C,LX
OPXY(0x55): // LD D,LX
OPXY(0x5d): // LD E,LX
OPXY(0x7d): // LD A,LX
zR8((Opcode >> 3) & 7) = data->B.L;
RET(4)
OPXY(0x60): // LD HX,B
OPXY(0x61): // LD HX,C
OPXY(0x62): // LD HX,D
OPXY(0x63): // LD HX,E
OPXY(0x67): // LD HX,A
data->B.H = zR8(Opcode & 7);
RET(4)
OPXY(0x68): // LD LX,B
OPXY(0x69): // LD LX,C
OPXY(0x6a): // LD LX,D
OPXY(0x6b): // LD LX,E
OPXY(0x6f): // LD LX,A
data->B.L = zR8(Opcode & 7);
RET(4)
OPXY(0x65): // LD HX,LX
data->B.H = data->B.L;
RET(4)
OPXY(0x6c): // LD LX,HX
data->B.L = data->B.H;
RET(4)
OPXY(0x06): // LD B,#imm
OPXY(0x0e): // LD C,#imm
OPXY(0x16): // LD D,#imm
OPXY(0x1e): // LD E,#imm
OPXY(0x3e): // LD A,#imm
goto OP_LD_R_imm;
OPXY(0x26): // LD HX,#imm
FETCH_BYTE(data->B.H);
RET(7)
OPXY(0x2e): // LD LX,#imm
FETCH_BYTE(data->B.L);
RET(7)
OPXY(0x0a): // LD A,(BC)
goto OP_LOAD_A_mBC;
OPXY(0x1a): // LD A,(DE)
goto OP_LOAD_A_mDE;
OPXY(0x3a): // LD A,(nn)
goto OP_LOAD_A_mNN;
OPXY(0x02): // LD (BC),A
goto OP_LOAD_mBC_A;
OPXY(0x12): // LD (DE),A
goto OP_LOAD_mDE_A;
OPXY(0x32): // LD (nn),A
goto OP_LOAD_mNN_A;
{
u32 adr;
OPXY(0x46): // LD B,(IX+o)
OPXY(0x56): // LD D,(IX+o)
OPXY(0x5e): // LD E,(IX+o)
OPXY(0x66): // LD H,(IX+o)
OPXY(0x6e): // LD L,(IX+o)
OPXY(0x4e): // LD C,(IX+o)
OPXY(0x7e): // LD A,(IX+o)
PRE_IO
{ s8 t; FETCH_BYTE_S(t); adr = data->W + t; }
READ_BYTE(adr, zR8((Opcode >> 3) & 7))
POST_IO
RET(15)
OPXY(0x70): // LD (IX+o),B
OPXY(0x71): // LD (IX+o),C
OPXY(0x72): // LD (IX+o),D
OPXY(0x73): // LD (IX+o),E
OPXY(0x74): // LD (IX+o),H
OPXY(0x75): // LD (IX+o),L
OPXY(0x77): // LD (IX+o),A
PRE_IO
{ s8 t; FETCH_BYTE_S(t); adr = data->W + t; }
WRITE_BYTE(adr, zR8(Opcode & 7))
POST_IO
RET(15)
OPXY(0x36): // LD (IX+o),#imm
PRE_IO
{ s8 t; FETCH_BYTE_S(t); adr = data->W + t; }
{ u8 t; FETCH_BYTE(t); WRITE_BYTE(adr, t); }
POST_IO
RET(15)
}
// 16 BITS LOAD
OPXY(0x01): // LD BC,nn
OPXY(0x11): // LD DE,nn
goto OP_LOAD_RR_imm16;
OPXY(0x21): // LD IX,nn
FETCH_WORD(data->W);
RET(10)
OPXY(0x31): // LD SP,nn
goto OP_LOAD_SP_imm16;
OPXY(0x2a): // LD IX,(w)
goto OP_LD_xx_mNN;
OPXY(0x22): // LD (w),IX
goto OP_LD_mNN_xx;
OPXY(0xf9): // LD SP,IX
goto OP_LD_SP_xx;
// PUSH / POP
OPXY(0xf1): // POP AF
goto OP_POP_AF;
OPXY(0xc1): // POP BC
OPXY(0xd1): // POP DE
goto OP_POP_RR;
OPXY(0xe1): // POP IX
goto OP_POP;
OPXY(0xf5): // PUSH AF
goto OP_PUSH_AF;
OPXY(0xc5): // PUSH BC
OPXY(0xd5): // PUSH DE
goto OP_PUSH_RR;
OPXY(0xe5): // PUSH IX
goto OP_PUSH;
// EXCHANGE
OPXY(0x08): // EX AF,AF'
goto OP_EX_AF_AF2;
OPXY(0xeb): // EX DE,HL
goto OP_EX_DE_HL;
OPXY(0xd9): // EXX
goto OP_EXX;
OPXY(0xe3): // EX (SP),IX
goto OP_EX_xx_mSP;
// 8 BITS ARITHMETIC
// INC
OPXY(0x04): // INC B
OPXY(0x0c): // INC C
OPXY(0x14): // INC D
OPXY(0x1c): // INC E
OPXY(0x3c): // INC A
goto OP_INC_R;
OPXY(0x24): // INC HX
data->B.H++;
zF = (zF & CZ80_CF) | SZXYHV_inc[data->B.H];
RET(4)
OPXY(0x2c): // INC LX
data->B.L++;
zF = (zF & CZ80_CF) | SZXYHV_inc[data->B.L];
RET(4)
OPXY(0x34): // INC (IX+o)
goto OP_INC_mIx;
// DEC
OPXY(0x05): // DEC B
OPXY(0x0d): // DEC C
OPXY(0x15): // DEC D
OPXY(0x1d): // DEC E
OPXY(0x3d): // DEC A
goto OP_DEC_R;
OPXY(0x25): // DEC HX
data->B.H--;
zF = (zF & CZ80_CF) | SZXYHV_dec[data->B.H];
RET(4)
OPXY(0x2d): // DEC LX
data->B.L--;
zF = (zF & CZ80_CF) | SZXYHV_dec[data->B.L];
RET(4)
OPXY(0x35): // DEC (IX+o)
goto OP_DEC_mIx;
// ADD
OPXY(0x80): // ADD A,B
OPXY(0x81): // ADD A,C
OPXY(0x82): // ADD A,D
OPXY(0x83): // ADD A,E
OPXY(0x87): // ADD A,A
goto OP_ADD_R;
OPXY(0x84): // ADD A,HX
goto OP_ADD_IxH;
OPXY(0x85): // ADD A,LX
goto OP_ADD_IxL;
OPXY(0xc6): // ADD A,n
goto OP_ADD_imm;
OPXY(0x86): // ADD A,(IX+o)
goto OP_ADD_mIx;
// ADC
OPXY(0x88): // ADC A,B
OPXY(0x89): // ADC A,C
OPXY(0x8a): // ADC A,D
OPXY(0x8b): // ADC A,E
OPXY(0x8f): // ADC A,A
goto OP_ADC_R;
OPXY(0xce): // ADC A,n
goto OP_ADC_imm;
OPXY(0x8c): // ADC A,HX
goto OP_ADC_IxH;
OPXY(0x8d): // ADC A,LX
goto OP_ADC_IxL;
OPXY(0x8e): // ADC A,(IX+o)
goto OP_ADC_mIx;
// SUB
OPXY(0x90): // SUB B
OPXY(0x91): // SUB C
OPXY(0x92): // SUB D
OPXY(0x93): // SUB E
OPXY(0x97): // SUB A
goto OP_SUB_R;
OPXY(0x94): // SUB HX
goto OP_SUB_IxH;
OPXY(0x95): // SUB LX
goto OP_SUB_IxL;
OPXY(0xd6): // SUB A,n
goto OP_SUB_imm;
OPXY(0x96): // SUB (IX+o)
goto OP_SUB_mIx;
// SBC
OPXY(0x98): // SBC A,B
OPXY(0x99): // SBC A,C
OPXY(0x9a): // SBC A,D
OPXY(0x9b): // SBC A,E
OPXY(0x9f): // SBC A,A
goto OP_SBC_R;
OPXY(0x9c): // SBC A,HX
goto OP_SBC_IxH;
OPXY(0x9d): // SBC A,LX
goto OP_SBC_IxL;
OPXY(0xde): // SBC A,n
goto OP_SBC_imm;
OPXY(0x9e): // SBC A,(IX+o)
goto OP_SBC_mIx;
// CP
OPXY(0xb8): // CP B
OPXY(0xb9): // CP C
OPXY(0xba): // CP D
OPXY(0xbb): // CP E
OPXY(0xbf): // CP A
goto OP_CP_R;
OPXY(0xbc): // CP HX
goto OP_CP_IxH;
OPXY(0xbd): // CP LX
goto OP_CP_IxL;
OPXY(0xfe): // CP n
goto OP_CP_imm;
OPXY(0xbe): // CP (IX+o)
goto OP_CP_mIx;
// AND
OPXY(0xa0): // AND B
OPXY(0xa1): // AND C
OPXY(0xa2): // AND D
OPXY(0xa3): // AND E
goto OP_AND_R;
OPXY(0xa7): // AND A
goto OP_AND_A;
OPXY(0xa4): // AND HX
goto OP_AND_IxH;
OPXY(0xa5): // AND LX
goto OP_AND_IxL;
OPXY(0xe6): // AND A,n
goto OP_AND_imm;
OPXY(0xa6): // AND (IX+o)
{
u32 val;
PRE_IO
{ s8 t; FETCH_BYTE_S(t); READ_BYTE(data->W + t, val); }
POST_IO
zA = zA & val;
zF = SZXYP[zA] | CZ80_HF;
RET(15)
}
// XOR
OPXY(0xa8): // XOR B
OPXY(0xa9): // XOR C
OPXY(0xaa): // XOR D
OPXY(0xab): // XOR E
goto OP_XOR_R;
OPXY(0xaf): // XOR A
goto OP_XOR_A;
OPXY(0xac): // XOR HX
goto OP_XOR_IxH;
OPXY(0xad): // XOR LX
goto OP_XOR_IxL;
OPXY(0xee): // XOR A,n
goto OP_XOR_imm;
OPXY(0xae): // XOR (IX+o)
{
u32 val;
PRE_IO
{ s8 t; FETCH_BYTE_S(t); READ_BYTE(data->W + t, val); }
POST_IO
zA = zA ^ val;
zF = SZXYP[zA];
RET(15)
}
// OR
OPXY(0xb0): // OR B
OPXY(0xb1): // OR C
OPXY(0xb2): // OR D
OPXY(0xb3): // OR E
goto OP_OR_R;
OPXY(0xb7): // OR A
goto OP_OR_A;
OPXY(0xb4): // OR HX
goto OP_OR_IxH;
OPXY(0xb5): // OR LX
goto OP_OR_IxL;
OPXY(0xf6): // OR A,n
goto OP_OR_imm;
OPXY(0xb6): // OR (IX+o)
{
u32 val;
PRE_IO
{ s8 t; FETCH_BYTE_S(t); READ_BYTE(data->W + t, val); }
POST_IO
zA = zA | val;
zF = SZXYP[zA];
RET(15)
}
// MISC ARITHMETIC & CPU CONTROL
OPXY(0x27): // DAA
goto OP_DAA;
OPXY(0x2f): // CPL
goto OP_CPL;
OPXY(0x37): // SCF
goto OP_SCF;
OPXY(0x3f): // CCF
goto OP_CCF;
OPXY(0x76): // HALT
goto OP_HALT;
OPXY(0xf3): // DI
goto OP_DI;
OPXY(0xfb): // EI
goto OP_EI;
// 16 BITS ARITHMETIC
OPXY(0x03): // INC BC
goto OP_INC_BC;
OPXY(0x13): // INC DE
goto OP_INC_DE;
OPXY(0x23): // INC IX
goto OP_INC_xx;
OPXY(0x33): // INC SP
goto OP_INC_SP;
OPXY(0x0b): // DEC BC
goto OP_DEC_BC;
OPXY(0x1b): // DEC DE
goto OP_DEC_DE;
OPXY(0x2b): // DEC IX
goto OP_DEC_xx;
OPXY(0x3b): // DEC SP
goto OP_DEC_SP;
// ADD16
OPXY(0x09): // ADD IX,BC
goto OP_ADD16_xx_BC;
OPXY(0x19): // ADD IX,DE
goto OP_ADD16_xx_DE;
OPXY(0x29): // ADD IX,IX
goto OP_ADD16_xx_xx;
OPXY(0x39): // ADD IX,SP
goto OP_ADD16_xx_SP;
// ROTATE
OPXY(0x07): // RLCA
goto OP_RLCA;
OPXY(0x0f): // RRCA
goto OP_RRCA;
OPXY(0x17): // RLA
goto OP_RLA;
OPXY(0x1f): // RRA
goto OP_RRA;
// JUMP
OPXY(0xc3): // JP nn
goto OP_JP;
OPXY(0xe9): // JP (IX)
goto OP_JP_xx;
OPXY(0xd2): // JP NC,nn
goto OP_JP_NC;
OPXY(0xda): // JP C,nn
goto OP_JP_C;
OPXY(0xe2): // JP PO,nn
goto OP_JP_PO;
OPXY(0xea): // JP PE,nn
goto OP_JP_PE;
OPXY(0xf2): // JP P,nn
goto OP_JP_P;
OPXY(0xfa): // JP M,nn
goto OP_JP_M;
OPXY(0xca): // JP Z,nn
goto OP_JP_Z;
OPXY(0xc2): // JP NZ,nn
goto OP_JP_NZ;
OPXY(0x18): // JR n
goto OP_JR;
OPXY(0x38): // JR C,n
goto OP_JR_C;
OPXY(0x30): // JR NC,n
goto OP_JR_NC;
OPXY(0x28): // JR Z,n
goto OP_JR_Z;
OPXY(0x20): // JR NZ,n
goto OP_JR_NZ;
OPXY(0x10): // DJNZ n
goto OP_DJNZ;
// CALL & RETURN
OPXY(0xcd): // CALL nn
goto OP_CALL;
OPXY(0xd4): // CALL NC,nn
goto OP_CALL_NC;
OPXY(0xdc): // CALL C,nn
goto OP_CALL_C;
OPXY(0xe4): // CALL PO,nn
goto OP_CALL_PO;
OPXY(0xec): // CALL PE,nn
goto OP_CALL_PE;
OPXY(0xf4): // CALL P,nn
goto OP_CALL_P;
OPXY(0xfc): // CALL M,nn
goto OP_CALL_M;
OPXY(0xcc): // CALL Z,nn
goto OP_CALL_Z;
OPXY(0xc4): // CALL NZ,nn
goto OP_CALL_NZ;
OPXY(0xc9): // RET
goto OP_RET;
OPXY(0xd0): // RET NC
goto OP_RET_NC;
OPXY(0xd8): // RET C
goto OP_RET_C;
OPXY(0xe0): // RET PO
goto OP_RET_PO;
OPXY(0xe8): // RET PE
goto OP_RET_PE;
OPXY(0xf0): // RET P
goto OP_RET_P;
OPXY(0xf8): // RET M
goto OP_RET_M;
OPXY(0xc0): // RET NZ
goto OP_RET_NZ;
OPXY(0xc8): // RET Z
goto OP_RET_Z;
OPXY(0xc7): // RST 0
OPXY(0xcf): // RST 1
OPXY(0xd7): // RST 2
OPXY(0xdf): // RST 3
OPXY(0xe7): // RST 4
OPXY(0xef): // RST 5
OPXY(0xf7): // RST 6
OPXY(0xff): // RST 7
goto OP_RST;
// INPUT & OUTPUT
OPXY(0xd3): // OUT (n),A
goto OP_OUT_mN_A;
OPXY(0xdb): // IN A,(n)
goto OP_IN_A_mN;
// PREFIXE
OPXY(0xcb): // XYCB PREFIXE
{
u32 adr;
u32 src;
u32 res;
{ s8 t; FETCH_BYTE_S(t); adr = data->W + t; }
FETCH_BYTE(Opcode);
#include "cz80_opXYCB.inc"
}
OPXY(0xed): // ED PREFIXE
goto ED_PREFIXE;
OPXY(0xdd): // DD PREFIXE (IX)
goto DD_PREFIXE;
OPXY(0xfd): // FD PREFIXE (IY)
goto FD_PREFIXE;
#if CZ80_USE_JUMPTABLE
#else
}
#endif

515
cz80_opXYCB.inc Normal file
View File

@ -0,0 +1,515 @@
/********************************************************************************/
/* */
/* CZ80 XYCB opcode include source file */
/* C Z80 emulator version 0.92 */
/* Copyright 2004-2005 Stéphane Dallongeville */
/* */
/********************************************************************************/
#if CZ80_USE_JUMPTABLE
goto *JumpTableXYCB[Opcode];
#else
switch (Opcode)
{
#endif
OPXYCB(0x00): // RLC (Ix+d), B
OPXYCB(0x01): // RLC (Ix+d), C
OPXYCB(0x02): // RLC (Ix+d), D
OPXYCB(0x03): // RLC (Ix+d), E
OPXYCB(0x04): // RLC (Ix+d), H
OPXYCB(0x05): // RLC (Ix+d), L
OPXYCB(0x07): // RLC (Ix+d), A
#if CZ80_EXACT
PRE_IO
READ_BYTE(adr, src)
res = ((src << 1) | (src >> 7)) & 0xFF;
zR8(Opcode) = res;
zF = SZXYP[res] | (src >> 7);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
#endif
OPXYCB(0x06): // RLC (Ix+d)
PRE_IO
READ_BYTE(adr, src)
res = ((src << 1) | (src >> 7)) & 0xFF;
zF = SZXYP[res] | (src >> 7);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
OPXYCB(0x08): // RRC (Ix+d), B
OPXYCB(0x09): // RRC (Ix+d), C
OPXYCB(0x0a): // RRC (Ix+d), D
OPXYCB(0x0b): // RRC (Ix+d), E
OPXYCB(0x0c): // RRC (Ix+d), H
OPXYCB(0x0d): // RRC (Ix+d), L
OPXYCB(0x0f): // RRC (Ix+d), A
#if CZ80_EXACT
PRE_IO
READ_BYTE(adr, src)
res = ((src >> 1) | (src << 7)) & 0xFF;
zR8(Opcode & 7) = res;
zF = SZXYP[res] | (src & CZ80_CF);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
#endif
OPXYCB(0x0e): // RRC (Ix+d)
PRE_IO
READ_BYTE(adr, src)
res = ((src >> 1) | (src << 7)) & 0xFF;
zF = SZXYP[res] | (src & CZ80_CF);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
OPXYCB(0x10): // RL (Ix+d), B
OPXYCB(0x11): // RL (Ix+d), C
OPXYCB(0x12): // RL (Ix+d), D
OPXYCB(0x13): // RL (Ix+d), E
OPXYCB(0x14): // RL (Ix+d), H
OPXYCB(0x15): // RL (Ix+d), L
OPXYCB(0x17): // RL (Ix+d), A
#if CZ80_EXACT
PRE_IO
READ_BYTE(adr, src)
res = ((src << 1) | (zF & CZ80_CF)) & 0xFF;
zR8(Opcode & 7) = res;
zF = SZXYP[res] | (src >> 7);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
#endif
OPXYCB(0x16): // RL (Ix+d)
PRE_IO
READ_BYTE(adr, src)
res = ((src << 1) | (zF & CZ80_CF)) & 0xFF;
zF = SZXYP[res] | (src >> 7);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
OPXYCB(0x18): // RR (Ix+d), B
OPXYCB(0x19): // RR (Ix+d), C
OPXYCB(0x1a): // RR (Ix+d), D
OPXYCB(0x1b): // RR (Ix+d), E
OPXYCB(0x1c): // RR (Ix+d), H
OPXYCB(0x1d): // RR (Ix+d), L
OPXYCB(0x1f): // RR (Ix+d), A
#if CZ80_EXACT
PRE_IO
READ_BYTE(adr, src)
res = ((src >> 1) | (zF << 7)) & 0xFF;
zR8(Opcode & 7) = res;
zF = SZXYP[res] | (src & CZ80_CF);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
#endif
OPXYCB(0x1e): // RR (Ix+d)
PRE_IO
READ_BYTE(adr, src)
res = ((src >> 1) | (zF << 7)) & 0xFF;
zF = SZXYP[res] | (src & CZ80_CF);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
OPXYCB(0x20): // SLA (Ix+d), B
OPXYCB(0x21): // SLA (Ix+d), C
OPXYCB(0x22): // SLA (Ix+d), D
OPXYCB(0x23): // SLA (Ix+d), E
OPXYCB(0x24): // SLA (Ix+d), H
OPXYCB(0x25): // SLA (Ix+d), L
OPXYCB(0x27): // SLA (Ix+d), A
#if CZ80_EXACT
PRE_IO
READ_BYTE(adr, src)
res = (src << 1) & 0xFF;
zR8(Opcode & 7) = res;
zF = SZXYP[res] | (src >> 7);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
#endif
OPXYCB(0x26): // SLA (Ix+d)
PRE_IO
READ_BYTE(adr, src)
res = (src << 1) & 0xFF;
zF = SZXYP[res] | (src >> 7);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
OPXYCB(0x28): // SRA (Ix+d), B
OPXYCB(0x29): // SRA (Ix+d), C
OPXYCB(0x2a): // SRA (Ix+d), D
OPXYCB(0x2b): // SRA (Ix+d), E
OPXYCB(0x2c): // SRA (Ix+d), H
OPXYCB(0x2d): // SRA (Ix+d), L
OPXYCB(0x2f): // SRA (Ix+d), A
#if CZ80_EXACT
PRE_IO
READ_BYTE(adr, src)
res = (u8)(((s8)(src)) >> 1);
zR8(Opcode & 7) = res;
zF = SZXYP[res] | (src & CZ80_CF);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
#endif
OPXYCB(0x2e): // SRA (Ix+d)
PRE_IO
READ_BYTE(adr, src)
res = (u8)(((s8)(src)) >> 1);
zF = SZXYP[res] | (src & CZ80_CF);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
OPXYCB(0x30): // SLL (Ix+d), B
OPXYCB(0x31): // SLL (Ix+d), C
OPXYCB(0x32): // SLL (Ix+d), D
OPXYCB(0x33): // SLL (Ix+d), E
OPXYCB(0x34): // SLL (Ix+d), H
OPXYCB(0x35): // SLL (Ix+d), L
OPXYCB(0x37): // SLL (Ix+d), A
#if CZ80_EXACT
PRE_IO
READ_BYTE(adr, src)
res = ((src << 1) | 1) & 0xFF;
zR8(Opcode & 7) = res;
zF = SZXYP[res] | (src >> 7);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
#endif
OPXYCB(0x36): // SLL (Ix+d)
PRE_IO
READ_BYTE(adr, src)
res = ((src << 1) | 1) & 0xFF;
zF = SZXYP[res] | (src >> 7);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
OPXYCB(0x38): // SRL (Ix+d), B
OPXYCB(0x39): // SRL (Ix+d), C
OPXYCB(0x3a): // SRL (Ix+d), D
OPXYCB(0x3b): // SRL (Ix+d), E
OPXYCB(0x3c): // SRL (Ix+d), H
OPXYCB(0x3d): // SRL (Ix+d), L
OPXYCB(0x3f): // SRL (Ix+d), A
#if CZ80_EXACT
PRE_IO
READ_BYTE(adr, src)
res = src >> 1;
zR8(Opcode & 7) = res;
zF = SZXYP[res] | (src & CZ80_CF);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
#endif
OPXYCB(0x3e): // SRL (Ix+d)
PRE_IO
READ_BYTE(adr, src)
res = src >> 1;
zF = SZXYP[res] | (src & CZ80_CF);
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
OPXYCB(0x40): // BIT 0,(Ix+d)
OPXYCB(0x41): // BIT 0,(Ix+d)
OPXYCB(0x42): // BIT 0,(Ix+d)
OPXYCB(0x43): // BIT 0,(Ix+d)
OPXYCB(0x44): // BIT 0,(Ix+d)
OPXYCB(0x45): // BIT 0,(Ix+d)
OPXYCB(0x47): // BIT 0,(Ix+d)
OPXYCB(0x48): // BIT 1,(Ix+d)
OPXYCB(0x49): // BIT 1,(Ix+d)
OPXYCB(0x4a): // BIT 1,(Ix+d)
OPXYCB(0x4b): // BIT 1,(Ix+d)
OPXYCB(0x4c): // BIT 1,(Ix+d)
OPXYCB(0x4d): // BIT 1,(Ix+d)
OPXYCB(0x4f): // BIT 1,(Ix+d)
OPXYCB(0x50): // BIT 2,(Ix+d)
OPXYCB(0x51): // BIT 2,(Ix+d)
OPXYCB(0x52): // BIT 2,(Ix+d)
OPXYCB(0x53): // BIT 2,(Ix+d)
OPXYCB(0x54): // BIT 2,(Ix+d)
OPXYCB(0x55): // BIT 2,(Ix+d)
OPXYCB(0x57): // BIT 2,(Ix+d)
OPXYCB(0x58): // BIT 3,(Ix+d)
OPXYCB(0x59): // BIT 3,(Ix+d)
OPXYCB(0x5a): // BIT 3,(Ix+d)
OPXYCB(0x5b): // BIT 3,(Ix+d)
OPXYCB(0x5c): // BIT 3,(Ix+d)
OPXYCB(0x5d): // BIT 3,(Ix+d)
OPXYCB(0x5f): // BIT 3,(Ix+d)
OPXYCB(0x60): // BIT 4,(Ix+d)
OPXYCB(0x61): // BIT 4,(Ix+d)
OPXYCB(0x62): // BIT 4,(Ix+d)
OPXYCB(0x63): // BIT 4,(Ix+d)
OPXYCB(0x64): // BIT 4,(Ix+d)
OPXYCB(0x65): // BIT 4,(Ix+d)
OPXYCB(0x67): // BIT 4,(Ix+d)
OPXYCB(0x68): // BIT 5,(Ix+d)
OPXYCB(0x69): // BIT 5,(Ix+d)
OPXYCB(0x6a): // BIT 5,(Ix+d)
OPXYCB(0x6b): // BIT 5,(Ix+d)
OPXYCB(0x6c): // BIT 5,(Ix+d)
OPXYCB(0x6d): // BIT 5,(Ix+d)
OPXYCB(0x6f): // BIT 5,(Ix+d)
OPXYCB(0x70): // BIT 6,(Ix+d)
OPXYCB(0x71): // BIT 6,(Ix+d)
OPXYCB(0x72): // BIT 6,(Ix+d)
OPXYCB(0x73): // BIT 6,(Ix+d)
OPXYCB(0x74): // BIT 6,(Ix+d)
OPXYCB(0x75): // BIT 6,(Ix+d)
OPXYCB(0x77): // BIT 6,(Ix+d)
OPXYCB(0x78): // BIT 7,(Ix+d)
OPXYCB(0x79): // BIT 7,(Ix+d)
OPXYCB(0x7a): // BIT 7,(Ix+d)
OPXYCB(0x7b): // BIT 7,(Ix+d)
OPXYCB(0x7c): // BIT 7,(Ix+d)
OPXYCB(0x7d): // BIT 7,(Ix+d)
OPXYCB(0x7f): // BIT 7,(Ix+d)
OPXYCB(0x46): // BIT 0,(Ix+d)
OPXYCB(0x4e): // BIT 1,(Ix+d)
OPXYCB(0x56): // BIT 2,(Ix+d)
OPXYCB(0x5e): // BIT 3,(Ix+d)
OPXYCB(0x66): // BIT 4,(Ix+d)
OPXYCB(0x6e): // BIT 5,(Ix+d)
OPXYCB(0x76): // BIT 6,(Ix+d)
OPXYCB(0x7e): // BIT 7,(Ix+d)
{
u32 bitm;
PRE_IO
bitm = 1 << ((Opcode >> 3) & 7);
READ_BYTE(adr, src)
zF = (zF & CZ80_CF) | CZ80_HF | // C/H flag
(SZXY_BIT[src & bitm] & ~(CZ80_XF | CZ80_YF)) | // Z/V/N flag
((adr >> 8) & (CZ80_XF | CZ80_YF)); // X/Y flag
POST_IO
RET(12 + 4)
}
OPXYCB(0x80): // RES 0,(Ix+d),B
OPXYCB(0x81): // RES 0,(Ix+d),C
OPXYCB(0x82): // RES 0,(Ix+d),D
OPXYCB(0x83): // RES 0,(Ix+d),E
OPXYCB(0x84): // RES 0,(Ix+d),H
OPXYCB(0x85): // RES 0,(Ix+d),L
OPXYCB(0x87): // RES 0,(Ix+d),A
OPXYCB(0x88): // RES 1,(Ix+d),B
OPXYCB(0x89): // RES 1,(Ix+d),C
OPXYCB(0x8a): // RES 1,(Ix+d),D
OPXYCB(0x8b): // RES 1,(Ix+d),E
OPXYCB(0x8c): // RES 1,(Ix+d),H
OPXYCB(0x8d): // RES 1,(Ix+d),L
OPXYCB(0x8f): // RES 1,(Ix+d),A
OPXYCB(0x90): // RES 2,(Ix+d),B
OPXYCB(0x91): // RES 2,(Ix+d),C
OPXYCB(0x92): // RES 2,(Ix+d),D
OPXYCB(0x93): // RES 2,(Ix+d),E
OPXYCB(0x94): // RES 2,(Ix+d),H
OPXYCB(0x95): // RES 2,(Ix+d),L
OPXYCB(0x97): // RES 2,(Ix+d),A
OPXYCB(0x98): // RES 3,(Ix+d),B
OPXYCB(0x99): // RES 3,(Ix+d),C
OPXYCB(0x9a): // RES 3,(Ix+d),D
OPXYCB(0x9b): // RES 3,(Ix+d),E
OPXYCB(0x9c): // RES 3,(Ix+d),H
OPXYCB(0x9d): // RES 3,(Ix+d),L
OPXYCB(0x9f): // RES 3,(Ix+d),A
OPXYCB(0xa0): // RES 4,(Ix+d),B
OPXYCB(0xa1): // RES 4,(Ix+d),C
OPXYCB(0xa2): // RES 4,(Ix+d),D
OPXYCB(0xa3): // RES 4,(Ix+d),E
OPXYCB(0xa4): // RES 4,(Ix+d),H
OPXYCB(0xa5): // RES 4,(Ix+d),L
OPXYCB(0xa7): // RES 4,(Ix+d),A
OPXYCB(0xa8): // RES 5,(Ix+d),B
OPXYCB(0xa9): // RES 5,(Ix+d),C
OPXYCB(0xaa): // RES 5,(Ix+d),D
OPXYCB(0xab): // RES 5,(Ix+d),E
OPXYCB(0xac): // RES 5,(Ix+d),H
OPXYCB(0xad): // RES 5,(Ix+d),L
OPXYCB(0xaf): // RES 5,(Ix+d),A
OPXYCB(0xb0): // RES 6,(Ix+d),B
OPXYCB(0xb1): // RES 6,(Ix+d),C
OPXYCB(0xb2): // RES 6,(Ix+d),D
OPXYCB(0xb3): // RES 6,(Ix+d),E
OPXYCB(0xb4): // RES 6,(Ix+d),H
OPXYCB(0xb5): // RES 6,(Ix+d),L
OPXYCB(0xb7): // RES 6,(Ix+d),A
OPXYCB(0xb8): // RES 7,(Ix+d),B
OPXYCB(0xb9): // RES 7,(Ix+d),C
OPXYCB(0xba): // RES 7,(Ix+d),D
OPXYCB(0xbb): // RES 7,(Ix+d),E
OPXYCB(0xbc): // RES 7,(Ix+d),H
OPXYCB(0xbd): // RES 7,(Ix+d),L
OPXYCB(0xbf): // RES 7,(Ix+d),A
#if CZ80_EXACT
PRE_IO
READ_BYTE(adr, res)
res &= ~(1 << ((Opcode >> 3) & 7));
zR8(Opcode & 7) = res;
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
#endif
OPXYCB(0x86): // RES 0,(Ix+d)
OPXYCB(0x8e): // RES 1,(Ix+d)
OPXYCB(0x96): // RES 2,(Ix+d)
OPXYCB(0x9e): // RES 3,(Ix+d)
OPXYCB(0xa6): // RES 4,(Ix+d)
OPXYCB(0xae): // RES 5,(Ix+d)
OPXYCB(0xb6): // RES 6,(Ix+d)
OPXYCB(0xbe): // RES 7,(Ix+d)
{
u32 bitm;
PRE_IO
bitm = ~(1 << ((Opcode >> 3) & 7));
READ_BYTE(adr, res)
res &= bitm;
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
}
OPXYCB(0xc0): // SET 0,(Ix+d),B
OPXYCB(0xc1): // SET 0,(Ix+d),C
OPXYCB(0xc2): // SET 0,(Ix+d),D
OPXYCB(0xc3): // SET 0,(Ix+d),E
OPXYCB(0xc4): // SET 0,(Ix+d),H
OPXYCB(0xc5): // SET 0,(Ix+d),L
OPXYCB(0xc7): // SET 0,(Ix+d),A
OPXYCB(0xc8): // SET 1,(Ix+d),B
OPXYCB(0xc9): // SET 1,(Ix+d),C
OPXYCB(0xca): // SET 1,(Ix+d),D
OPXYCB(0xcb): // SET 1,(Ix+d),E
OPXYCB(0xcc): // SET 1,(Ix+d),H
OPXYCB(0xcd): // SET 1,(Ix+d),L
OPXYCB(0xcf): // SET 1,(Ix+d),A
OPXYCB(0xd0): // SET 2,(Ix+d),B
OPXYCB(0xd1): // SET 2,(Ix+d),C
OPXYCB(0xd2): // SET 2,(Ix+d),D
OPXYCB(0xd3): // SET 2,(Ix+d),E
OPXYCB(0xd4): // SET 2,(Ix+d),H
OPXYCB(0xd5): // SET 2,(Ix+d),L
OPXYCB(0xd7): // SET 2,(Ix+d),A
OPXYCB(0xd8): // SET 3,(Ix+d),B
OPXYCB(0xd9): // SET 3,(Ix+d),C
OPXYCB(0xda): // SET 3,(Ix+d),D
OPXYCB(0xdb): // SET 3,(Ix+d),E
OPXYCB(0xdc): // SET 3,(Ix+d),H
OPXYCB(0xdd): // SET 3,(Ix+d),L
OPXYCB(0xdf): // SET 3,(Ix+d),A
OPXYCB(0xe0): // SET 4,(Ix+d),B
OPXYCB(0xe1): // SET 4,(Ix+d),C
OPXYCB(0xe2): // SET 4,(Ix+d),D
OPXYCB(0xe3): // SET 4,(Ix+d),E
OPXYCB(0xe4): // SET 4,(Ix+d),H
OPXYCB(0xe5): // SET 4,(Ix+d),L
OPXYCB(0xe7): // SET 4,(Ix+d),A
OPXYCB(0xe8): // SET 5,(Ix+d),B
OPXYCB(0xe9): // SET 5,(Ix+d),C
OPXYCB(0xea): // SET 5,(Ix+d),D
OPXYCB(0xeb): // SET 5,(Ix+d),E
OPXYCB(0xec): // SET 5,(Ix+d),H
OPXYCB(0xed): // SET 5,(Ix+d),L
OPXYCB(0xef): // SET 5,(Ix+d),A
OPXYCB(0xf0): // SET 6,(Ix+d),B
OPXYCB(0xf1): // SET 6,(Ix+d),C
OPXYCB(0xf2): // SET 6,(Ix+d),D
OPXYCB(0xf3): // SET 6,(Ix+d),E
OPXYCB(0xf4): // SET 6,(Ix+d),H
OPXYCB(0xf5): // SET 6,(Ix+d),L
OPXYCB(0xf7): // SET 6,(Ix+d),A
OPXYCB(0xf8): // SET 7,(Ix+d),B
OPXYCB(0xf9): // SET 7,(Ix+d),C
OPXYCB(0xfa): // SET 7,(Ix+d),D
OPXYCB(0xfb): // SET 7,(Ix+d),E
OPXYCB(0xfc): // SET 7,(Ix+d),H
OPXYCB(0xfd): // SET 7,(Ix+d),L
OPXYCB(0xff): // SET 7,(Ix+d),A
#if CZ80_EXACT
PRE_IO
READ_BYTE(adr, res)
res |= 1 << ((Opcode >> 3) & 7);
zR8(Opcode & 7) = res;
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
#endif
OPXYCB(0xc6): // SET 0,(Ix+d)
OPXYCB(0xce): // SET 1,(Ix+d)
OPXYCB(0xd6): // SET 2,(Ix+d)
OPXYCB(0xde): // SET 3,(Ix+d)
OPXYCB(0xe6): // SET 4,(Ix+d)
OPXYCB(0xee): // SET 5,(Ix+d)
OPXYCB(0xf6): // SET 6,(Ix+d)
OPXYCB(0xfe): // SET 7,(Ix+d)
{
u32 bitm;
PRE_IO
bitm = 1 << ((Opcode >> 3) & 7);
READ_BYTE(adr, res)
res |= bitm;
WRITE_BYTE(adr, res)
POST_IO
RET(15 + 4)
}
#if CZ80_USE_JUMPTABLE
#else
}
#endif

94
cz80_support.cpp Normal file
View File

@ -0,0 +1,94 @@
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//#include "driver.h"
//#include "cpuintrf.h"
#include "memory.h"
//#include "z80/z80.h"
#include "cz80.h"
// #include "hack.h"
unsigned char *mame4all_cz80_rom = &mainram[0x3000];
unsigned char *mame4all_cz80_ram = &mainram[0x3000];
cz80_struc RACE_cz80_struc_alloc;
cz80_struc *RACE_cz80_struc=&RACE_cz80_struc_alloc;
#include "memory.h"
void Z80_Init()
{
Cz80_Init(RACE_cz80_struc);
}
void Z80_Reset()
{
//unsigned *ctx=(unsigned *)(((unsigned)cpu_getcontext(cpu_getactivecpu())));
//RACE_cz80_struc=(cz80_struc *)&ctx[4];
//Cz80_Init(RACE_cz80_struc);
Cz80_Reset(RACE_cz80_struc);
//ctx[0]=(unsigned)Cz80_Get_PC(RACE_cz80_struc);
}
/*void Z80_GetRegs(Z80_Regs *Regs)
{
unsigned *ctx=(unsigned *)Regs;
ctx[0] = (unsigned)Cz80_Get_PC(RACE_cz80_struc);
}*/
/*void Z80_SetRegs (Z80_Regs *Regs)
{
unsigned *ctx=(unsigned *)Regs;
RACE_cz80_struc=(cz80_struc *)&ctx[4];
Cz80_Set_PC(RACE_cz80_struc,ctx[0]);
}*/
unsigned Z80_GetPC (void)
{
return Cz80_Get_PC(RACE_cz80_struc);
}
void Z80_Cause_Interrupt(int type)
{
if (type == Z80_NMI_INT)
Cz80_Set_NMI(RACE_cz80_struc);
else if (type >= 0)
Cz80_Set_IRQ(RACE_cz80_struc, type & 0xff);
}
void Z80_Clear_Pending_Interrupts(void)
{
Cz80_Clear_IRQ(RACE_cz80_struc);
Cz80_Clear_NMI(RACE_cz80_struc);
}
int Z80_Execute(int cycles)
{
return Cz80_Exec(RACE_cz80_struc,cycles);
}
int cpu_readmem16(int address)
{
return z80ngpMemReadB(address);
}
void cpu_writemem16(int address,int data)
{
DrZ80ngpMemWriteB(data,address);
}
int cpu_readport(int Port)
{
return DrZ80ngpPortReadB(Port);
}
void cpu_writeport(int Port,int Value)
{
DrZ80ngpPortWriteB(Port,Value);
}

48
cz80_support.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef Z80_H
#define Z80_H
#ifdef __cplusplus
extern "C" {
#endif
//#include "osd_cpu.h"
//#include "cpuintrf.h"
//#include "DrZ80.h"
/* daisy-chain link */
typedef struct {
void (*reset)(int); /* reset callback */
int (*interrupt_entry)(int); /* entry callback */
void (*interrupt_reti)(int); /* reti callback */
int irq_param; /* callback paramater */
} Z80_DaisyChain;
#define Z80_MAXDAISY 4 /* maximum of daisy chan device */
#define Z80_INT_REQ 0x01 /* interrupt request mask */
#define Z80_INT_IEO 0x02 /* interrupt disable mask(IEO) */
#define Z80_VECTOR(device,state) (((device)<<8)|(state))
#define Z80_IGNORE_INT -1 /* Ignore interrupt */
#define Z80_NMI_INT -2 /* Execute NMI */
#define Z80_IRQ_INT -1000 /* Execute IRQ */
extern unsigned Z80_GetPC (void); /* Get program counter */
extern int Z80_GetPreviousPC (void);
extern void Z80_Init(void);
extern void Z80_Reset(void);
extern int Z80_Execute(int cycles); /* Execute cycles T-States - returns number of cycles actually run */
extern int Z80_Interrupt(void);
extern void Z80_Cause_Interrupt(int type);
extern void Z80_Clear_Pending_Interrupts(void);
extern void Interrupt(void); /* required for DrZ80 int hack */
#ifdef __cplusplus
} /* End of extern "C" */
#endif
#endif

124
cz80exec.inc Normal file
View File

@ -0,0 +1,124 @@
/********************************************************************************/
/* */
/* CZ80 exec include source file */
/* C Z80 emulator version 0.92 */
/* Copyright 2004-2005 Stéphane Dallongeville */
/* */
/********************************************************************************/
s32 Z80_ICount;
s32 CZ80_FASTCALL Cz80_Exec(cz80_struc *cpu, s32 cycles)
{
#if CZ80_USE_JUMPTABLE
#include "cz80jmp.inc"
#endif
#if __x86__
register cz80_struc *CPU asm ("ebx");
register u8 *PC asm ("esi");
register u32 Opcode asm ("edx");
#else
cz80_struc *CPU;
u8 *PC;
u32 Opcode;
#endif
CPU = cpu;
PC = CPU->PC;
if (CPU->Status & (CZ80_RUNNING | CZ80_DISABLE | CZ80_FAULTED))
{
return (CPU->Status | 0x80000000);
}
CPU->CycleToDo = Z80_ICount = cycles;
CPU->CycleSup = 0;
CPU->Status |= CZ80_RUNNING;
Cz80_Check_Int:
// check for interrupt
if (CPU->Status & (zIFF1 | CZ80_HAS_NMI))
{
u32 newPC;
if (CPU->Status & CZ80_HAS_NMI)
{
// NMI
CPU->Status &= ~(CZ80_HALTED | CZ80_HAS_NMI);
zIFF1 = 0;
newPC = 0x66;
}
else
{
// INT
CPU->Status &= ~(CZ80_HALTED | CZ80_HAS_INT);
zIFF= 0;
// IM = 1
if (zIM == 1) newPC = 0x38;
else
{
u32 adr;
Opcode = CPU->IntVect & 0xFF;
// IM = 0
if (zIM == 0)
goto Cz80_Exec_direct;
// IM = 2
adr = Opcode | (zI << 8);
READ_WORD(adr, newPC)
#if CZ80_IRQ_CYCLES
Z80_ICount -= 8;
#endif
}
}
// set new PC
{
u32 src = zRealPC;
PUSH_16(src)
SET_PC(newPC);
#if CZ80_IRQ_CYCLES
Z80_ICount -= 11;
#endif
}
}
// if some cycles left
if ((Z80_ICount += CPU->CycleSup) > 0)
{
CPU->CycleSup = 0;
if (!(CPU->Status & CZ80_HALTED)) goto Cz80_Exec;
// CPU halted
Z80_ICount = 0;
}
Cz80_Exec_Really_End:
// no more cycles, end execution
CPU->Status &= ~CZ80_RUNNING;
CPU->PC = PC;
// number of executed cycles
Z80_ICount = CPU->CycleToDo - Z80_ICount;
// update R register
zR = (zR + (Z80_ICount >> 2)) & 0x7F;
return Z80_ICount;
#if CZ80_SIZE_OPT
Cz80_Exec_Check:
if (Z80_ICount <= 0) goto Cz80_Check_Int;
#endif
Cz80_Exec:
{
Opcode = REAL_FETCH_BYTE;
Cz80_Exec_direct:
union16 *data = pzHL;
#include "cz80_op.inc"
}
}

418
cz80jmp.inc Normal file
View File

@ -0,0 +1,418 @@
/********************************************************************************/
/* */
/* CZ80 JumpTable include source file */
/* C Z80 emulator version 0.91 */
/* Copyright 2004-2005 Stéphane Dallongeville */
/* */
/********************************************************************************/
static const void *JumpTable[0x100] = {
&&OP0x00, &&OP0x01, &&OP0x02, &&OP0x03,
&&OP0x04, &&OP0x05, &&OP0x06, &&OP0x07,
&&OP0x08, &&OP0x09, &&OP0x0a, &&OP0x0b,
&&OP0x0c, &&OP0x0d, &&OP0x0e, &&OP0x0f,
&&OP0x10, &&OP0x11, &&OP0x12, &&OP0x13,
&&OP0x14, &&OP0x15, &&OP0x16, &&OP0x17,
&&OP0x18, &&OP0x19, &&OP0x1a, &&OP0x1b,
&&OP0x1c, &&OP0x1d, &&OP0x1e, &&OP0x1f,
&&OP0x20, &&OP0x21, &&OP0x22, &&OP0x23,
&&OP0x24, &&OP0x25, &&OP0x26, &&OP0x27,
&&OP0x28, &&OP0x29, &&OP0x2a, &&OP0x2b,
&&OP0x2c, &&OP0x2d, &&OP0x2e, &&OP0x2f,
&&OP0x30, &&OP0x31, &&OP0x32, &&OP0x33,
&&OP0x34, &&OP0x35, &&OP0x36, &&OP0x37,
&&OP0x38, &&OP0x39, &&OP0x3a, &&OP0x3b,
&&OP0x3c, &&OP0x3d, &&OP0x3e, &&OP0x3f,
&&OP0x40, &&OP0x41, &&OP0x42, &&OP0x43,
&&OP0x44, &&OP0x45, &&OP0x46, &&OP0x47,
&&OP0x48, &&OP0x49, &&OP0x4a, &&OP0x4b,
&&OP0x4c, &&OP0x4d, &&OP0x4e, &&OP0x4f,
&&OP0x50, &&OP0x51, &&OP0x52, &&OP0x53,
&&OP0x54, &&OP0x55, &&OP0x56, &&OP0x57,
&&OP0x58, &&OP0x59, &&OP0x5a, &&OP0x5b,
&&OP0x5c, &&OP0x5d, &&OP0x5e, &&OP0x5f,
&&OP0x60, &&OP0x61, &&OP0x62, &&OP0x63,
&&OP0x64, &&OP0x65, &&OP0x66, &&OP0x67,
&&OP0x68, &&OP0x69, &&OP0x6a, &&OP0x6b,
&&OP0x6c, &&OP0x6d, &&OP0x6e, &&OP0x6f,
&&OP0x70, &&OP0x71, &&OP0x72, &&OP0x73,
&&OP0x74, &&OP0x75, &&OP0x76, &&OP0x77,
&&OP0x78, &&OP0x79, &&OP0x7a, &&OP0x7b,
&&OP0x7c, &&OP0x7d, &&OP0x7e, &&OP0x7f,
&&OP0x80, &&OP0x81, &&OP0x82, &&OP0x83,
&&OP0x84, &&OP0x85, &&OP0x86, &&OP0x87,
&&OP0x88, &&OP0x89, &&OP0x8a, &&OP0x8b,
&&OP0x8c, &&OP0x8d, &&OP0x8e, &&OP0x8f,
&&OP0x90, &&OP0x91, &&OP0x92, &&OP0x93,
&&OP0x94, &&OP0x95, &&OP0x96, &&OP0x97,
&&OP0x98, &&OP0x99, &&OP0x9a, &&OP0x9b,
&&OP0x9c, &&OP0x9d, &&OP0x9e, &&OP0x9f,
&&OP0xa0, &&OP0xa1, &&OP0xa2, &&OP0xa3,
&&OP0xa4, &&OP0xa5, &&OP0xa6, &&OP0xa7,
&&OP0xa8, &&OP0xa9, &&OP0xaa, &&OP0xab,
&&OP0xac, &&OP0xad, &&OP0xae, &&OP0xaf,
&&OP0xb0, &&OP0xb1, &&OP0xb2, &&OP0xb3,
&&OP0xb4, &&OP0xb5, &&OP0xb6, &&OP0xb7,
&&OP0xb8, &&OP0xb9, &&OP0xba, &&OP0xbb,
&&OP0xbc, &&OP0xbd, &&OP0xbe, &&OP0xbf,
&&OP0xc0, &&OP0xc1, &&OP0xc2, &&OP0xc3,
&&OP0xc4, &&OP0xc5, &&OP0xc6, &&OP0xc7,
&&OP0xc8, &&OP0xc9, &&OP0xca, &&OP0xcb,
&&OP0xcc, &&OP0xcd, &&OP0xce, &&OP0xcf,
&&OP0xd0, &&OP0xd1, &&OP0xd2, &&OP0xd3,
&&OP0xd4, &&OP0xd5, &&OP0xd6, &&OP0xd7,
&&OP0xd8, &&OP0xd9, &&OP0xda, &&OP0xdb,
&&OP0xdc, &&OP0xdd, &&OP0xde, &&OP0xdf,
&&OP0xe0, &&OP0xe1, &&OP0xe2, &&OP0xe3,
&&OP0xe4, &&OP0xe5, &&OP0xe6, &&OP0xe7,
&&OP0xe8, &&OP0xe9, &&OP0xea, &&OP0xeb,
&&OP0xec, &&OP0xed, &&OP0xee, &&OP0xef,
&&OP0xf0, &&OP0xf1, &&OP0xf2, &&OP0xf3,
&&OP0xf4, &&OP0xf5, &&OP0xf6, &&OP0xf7,
&&OP0xf8, &&OP0xf9, &&OP0xfa, &&OP0xfb,
&&OP0xfc, &&OP0xfd, &&OP0xfe, &&OP0xff
};
static const void *JumpTableCB[0x100] = {
&&OPCB0x00, &&OPCB0x01, &&OPCB0x02, &&OPCB0x03,
&&OPCB0x04, &&OPCB0x05, &&OPCB0x06, &&OPCB0x07,
&&OPCB0x08, &&OPCB0x09, &&OPCB0x0a, &&OPCB0x0b,
&&OPCB0x0c, &&OPCB0x0d, &&OPCB0x0e, &&OPCB0x0f,
&&OPCB0x10, &&OPCB0x11, &&OPCB0x12, &&OPCB0x13,
&&OPCB0x14, &&OPCB0x15, &&OPCB0x16, &&OPCB0x17,
&&OPCB0x18, &&OPCB0x19, &&OPCB0x1a, &&OPCB0x1b,
&&OPCB0x1c, &&OPCB0x1d, &&OPCB0x1e, &&OPCB0x1f,
&&OPCB0x20, &&OPCB0x21, &&OPCB0x22, &&OPCB0x23,
&&OPCB0x24, &&OPCB0x25, &&OPCB0x26, &&OPCB0x27,
&&OPCB0x28, &&OPCB0x29, &&OPCB0x2a, &&OPCB0x2b,
&&OPCB0x2c, &&OPCB0x2d, &&OPCB0x2e, &&OPCB0x2f,
&&OPCB0x30, &&OPCB0x31, &&OPCB0x32, &&OPCB0x33,
&&OPCB0x34, &&OPCB0x35, &&OPCB0x36, &&OPCB0x37,
&&OPCB0x38, &&OPCB0x39, &&OPCB0x3a, &&OPCB0x3b,
&&OPCB0x3c, &&OPCB0x3d, &&OPCB0x3e, &&OPCB0x3f,
&&OPCB0x40, &&OPCB0x41, &&OPCB0x42, &&OPCB0x43,
&&OPCB0x44, &&OPCB0x45, &&OPCB0x46, &&OPCB0x47,
&&OPCB0x48, &&OPCB0x49, &&OPCB0x4a, &&OPCB0x4b,
&&OPCB0x4c, &&OPCB0x4d, &&OPCB0x4e, &&OPCB0x4f,
&&OPCB0x50, &&OPCB0x51, &&OPCB0x52, &&OPCB0x53,
&&OPCB0x54, &&OPCB0x55, &&OPCB0x56, &&OPCB0x57,
&&OPCB0x58, &&OPCB0x59, &&OPCB0x5a, &&OPCB0x5b,
&&OPCB0x5c, &&OPCB0x5d, &&OPCB0x5e, &&OPCB0x5f,
&&OPCB0x60, &&OPCB0x61, &&OPCB0x62, &&OPCB0x63,
&&OPCB0x64, &&OPCB0x65, &&OPCB0x66, &&OPCB0x67,
&&OPCB0x68, &&OPCB0x69, &&OPCB0x6a, &&OPCB0x6b,
&&OPCB0x6c, &&OPCB0x6d, &&OPCB0x6e, &&OPCB0x6f,
&&OPCB0x70, &&OPCB0x71, &&OPCB0x72, &&OPCB0x73,
&&OPCB0x74, &&OPCB0x75, &&OPCB0x76, &&OPCB0x77,
&&OPCB0x78, &&OPCB0x79, &&OPCB0x7a, &&OPCB0x7b,
&&OPCB0x7c, &&OPCB0x7d, &&OPCB0x7e, &&OPCB0x7f,
&&OPCB0x80, &&OPCB0x81, &&OPCB0x82, &&OPCB0x83,
&&OPCB0x84, &&OPCB0x85, &&OPCB0x86, &&OPCB0x87,
&&OPCB0x88, &&OPCB0x89, &&OPCB0x8a, &&OPCB0x8b,
&&OPCB0x8c, &&OPCB0x8d, &&OPCB0x8e, &&OPCB0x8f,
&&OPCB0x90, &&OPCB0x91, &&OPCB0x92, &&OPCB0x93,
&&OPCB0x94, &&OPCB0x95, &&OPCB0x96, &&OPCB0x97,
&&OPCB0x98, &&OPCB0x99, &&OPCB0x9a, &&OPCB0x9b,
&&OPCB0x9c, &&OPCB0x9d, &&OPCB0x9e, &&OPCB0x9f,
&&OPCB0xa0, &&OPCB0xa1, &&OPCB0xa2, &&OPCB0xa3,
&&OPCB0xa4, &&OPCB0xa5, &&OPCB0xa6, &&OPCB0xa7,
&&OPCB0xa8, &&OPCB0xa9, &&OPCB0xaa, &&OPCB0xab,
&&OPCB0xac, &&OPCB0xad, &&OPCB0xae, &&OPCB0xaf,
&&OPCB0xb0, &&OPCB0xb1, &&OPCB0xb2, &&OPCB0xb3,
&&OPCB0xb4, &&OPCB0xb5, &&OPCB0xb6, &&OPCB0xb7,
&&OPCB0xb8, &&OPCB0xb9, &&OPCB0xba, &&OPCB0xbb,
&&OPCB0xbc, &&OPCB0xbd, &&OPCB0xbe, &&OPCB0xbf,
&&OPCB0xc0, &&OPCB0xc1, &&OPCB0xc2, &&OPCB0xc3,
&&OPCB0xc4, &&OPCB0xc5, &&OPCB0xc6, &&OPCB0xc7,
&&OPCB0xc8, &&OPCB0xc9, &&OPCB0xca, &&OPCB0xcb,
&&OPCB0xcc, &&OPCB0xcd, &&OPCB0xce, &&OPCB0xcf,
&&OPCB0xd0, &&OPCB0xd1, &&OPCB0xd2, &&OPCB0xd3,
&&OPCB0xd4, &&OPCB0xd5, &&OPCB0xd6, &&OPCB0xd7,
&&OPCB0xd8, &&OPCB0xd9, &&OPCB0xda, &&OPCB0xdb,
&&OPCB0xdc, &&OPCB0xdd, &&OPCB0xde, &&OPCB0xdf,
&&OPCB0xe0, &&OPCB0xe1, &&OPCB0xe2, &&OPCB0xe3,
&&OPCB0xe4, &&OPCB0xe5, &&OPCB0xe6, &&OPCB0xe7,
&&OPCB0xe8, &&OPCB0xe9, &&OPCB0xea, &&OPCB0xeb,
&&OPCB0xec, &&OPCB0xed, &&OPCB0xee, &&OPCB0xef,
&&OPCB0xf0, &&OPCB0xf1, &&OPCB0xf2, &&OPCB0xf3,
&&OPCB0xf4, &&OPCB0xf5, &&OPCB0xf6, &&OPCB0xf7,
&&OPCB0xf8, &&OPCB0xf9, &&OPCB0xfa, &&OPCB0xfb,
&&OPCB0xfc, &&OPCB0xfd, &&OPCB0xfe, &&OPCB0xff
};
static const void *JumpTableED[0x100] = {
&&OPED0x00, &&OPED0x01, &&OPED0x02, &&OPED0x03,
&&OPED0x04, &&OPED0x05, &&OPED0x06, &&OPED0x07,
&&OPED0x08, &&OPED0x09, &&OPED0x0a, &&OPED0x0b,
&&OPED0x0c, &&OPED0x0d, &&OPED0x0e, &&OPED0x0f,
&&OPED0x10, &&OPED0x11, &&OPED0x12, &&OPED0x13,
&&OPED0x14, &&OPED0x15, &&OPED0x16, &&OPED0x17,
&&OPED0x18, &&OPED0x19, &&OPED0x1a, &&OPED0x1b,
&&OPED0x1c, &&OPED0x1d, &&OPED0x1e, &&OPED0x1f,
&&OPED0x20, &&OPED0x21, &&OPED0x22, &&OPED0x23,
&&OPED0x24, &&OPED0x25, &&OPED0x26, &&OPED0x27,
&&OPED0x28, &&OPED0x29, &&OPED0x2a, &&OPED0x2b,
&&OPED0x2c, &&OPED0x2d, &&OPED0x2e, &&OPED0x2f,
&&OPED0x30, &&OPED0x31, &&OPED0x32, &&OPED0x33,
&&OPED0x34, &&OPED0x35, &&OPED0x36, &&OPED0x37,
&&OPED0x38, &&OPED0x39, &&OPED0x3a, &&OPED0x3b,
&&OPED0x3c, &&OPED0x3d, &&OPED0x3e, &&OPED0x3f,
&&OPED0x40, &&OPED0x41, &&OPED0x42, &&OPED0x43,
&&OPED0x44, &&OPED0x45, &&OPED0x46, &&OPED0x47,
&&OPED0x48, &&OPED0x49, &&OPED0x4a, &&OPED0x4b,
&&OPED0x4c, &&OPED0x4d, &&OPED0x4e, &&OPED0x4f,
&&OPED0x50, &&OPED0x51, &&OPED0x52, &&OPED0x53,
&&OPED0x54, &&OPED0x55, &&OPED0x56, &&OPED0x57,
&&OPED0x58, &&OPED0x59, &&OPED0x5a, &&OPED0x5b,
&&OPED0x5c, &&OPED0x5d, &&OPED0x5e, &&OPED0x5f,
&&OPED0x60, &&OPED0x61, &&OPED0x62, &&OPED0x63,
&&OPED0x64, &&OPED0x65, &&OPED0x66, &&OPED0x67,
&&OPED0x68, &&OPED0x69, &&OPED0x6a, &&OPED0x6b,
&&OPED0x6c, &&OPED0x6d, &&OPED0x6e, &&OPED0x6f,
&&OPED0x70, &&OPED0x71, &&OPED0x72, &&OPED0x73,
&&OPED0x74, &&OPED0x75, &&OPED0x76, &&OPED0x77,
&&OPED0x78, &&OPED0x79, &&OPED0x7a, &&OPED0x7b,
&&OPED0x7c, &&OPED0x7d, &&OPED0x7e, &&OPED0x7f,
&&OPED0x80, &&OPED0x81, &&OPED0x82, &&OPED0x83,
&&OPED0x84, &&OPED0x85, &&OPED0x86, &&OPED0x87,
&&OPED0x88, &&OPED0x89, &&OPED0x8a, &&OPED0x8b,
&&OPED0x8c, &&OPED0x8d, &&OPED0x8e, &&OPED0x8f,
&&OPED0x90, &&OPED0x91, &&OPED0x92, &&OPED0x93,
&&OPED0x94, &&OPED0x95, &&OPED0x96, &&OPED0x97,
&&OPED0x98, &&OPED0x99, &&OPED0x9a, &&OPED0x9b,
&&OPED0x9c, &&OPED0x9d, &&OPED0x9e, &&OPED0x9f,
&&OPED0xa0, &&OPED0xa1, &&OPED0xa2, &&OPED0xa3,
&&OPED0xa4, &&OPED0xa5, &&OPED0xa6, &&OPED0xa7,
&&OPED0xa8, &&OPED0xa9, &&OPED0xaa, &&OPED0xab,
&&OPED0xac, &&OPED0xad, &&OPED0xae, &&OPED0xaf,
&&OPED0xb0, &&OPED0xb1, &&OPED0xb2, &&OPED0xb3,
&&OPED0xb4, &&OPED0xb5, &&OPED0xb6, &&OPED0xb7,
&&OPED0xb8, &&OPED0xb9, &&OPED0xba, &&OPED0xbb,
&&OPED0xbc, &&OPED0xbd, &&OPED0xbe, &&OPED0xbf,
&&OPED0xc0, &&OPED0xc1, &&OPED0xc2, &&OPED0xc3,
&&OPED0xc4, &&OPED0xc5, &&OPED0xc6, &&OPED0xc7,
&&OPED0xc8, &&OPED0xc9, &&OPED0xca, &&OPED0xcb,
&&OPED0xcc, &&OPED0xcd, &&OPED0xce, &&OPED0xcf,
&&OPED0xd0, &&OPED0xd1, &&OPED0xd2, &&OPED0xd3,
&&OPED0xd4, &&OPED0xd5, &&OPED0xd6, &&OPED0xd7,
&&OPED0xd8, &&OPED0xd9, &&OPED0xda, &&OPED0xdb,
&&OPED0xdc, &&OPED0xdd, &&OPED0xde, &&OPED0xdf,
&&OPED0xe0, &&OPED0xe1, &&OPED0xe2, &&OPED0xe3,
&&OPED0xe4, &&OPED0xe5, &&OPED0xe6, &&OPED0xe7,
&&OPED0xe8, &&OPED0xe9, &&OPED0xea, &&OPED0xeb,
&&OPED0xec, &&OPED0xed, &&OPED0xee, &&OPED0xef,
&&OPED0xf0, &&OPED0xf1, &&OPED0xf2, &&OPED0xf3,
&&OPED0xf4, &&OPED0xf5, &&OPED0xf6, &&OPED0xf7,
&&OPED0xf8, &&OPED0xf9, &&OPED0xfa, &&OPED0xfb,
&&OPED0xfc, &&OPED0xfd, &&OPED0xfe, &&OPED0xff
};
static const void *JumpTableXY[0x100] = {
&&OPXY0x00, &&OPXY0x01, &&OPXY0x02, &&OPXY0x03,
&&OPXY0x04, &&OPXY0x05, &&OPXY0x06, &&OPXY0x07,
&&OPXY0x08, &&OPXY0x09, &&OPXY0x0a, &&OPXY0x0b,
&&OPXY0x0c, &&OPXY0x0d, &&OPXY0x0e, &&OPXY0x0f,
&&OPXY0x10, &&OPXY0x11, &&OPXY0x12, &&OPXY0x13,
&&OPXY0x14, &&OPXY0x15, &&OPXY0x16, &&OPXY0x17,
&&OPXY0x18, &&OPXY0x19, &&OPXY0x1a, &&OPXY0x1b,
&&OPXY0x1c, &&OPXY0x1d, &&OPXY0x1e, &&OPXY0x1f,
&&OPXY0x20, &&OPXY0x21, &&OPXY0x22, &&OPXY0x23,
&&OPXY0x24, &&OPXY0x25, &&OPXY0x26, &&OPXY0x27,
&&OPXY0x28, &&OPXY0x29, &&OPXY0x2a, &&OPXY0x2b,
&&OPXY0x2c, &&OPXY0x2d, &&OPXY0x2e, &&OPXY0x2f,
&&OPXY0x30, &&OPXY0x31, &&OPXY0x32, &&OPXY0x33,
&&OPXY0x34, &&OPXY0x35, &&OPXY0x36, &&OPXY0x37,
&&OPXY0x38, &&OPXY0x39, &&OPXY0x3a, &&OPXY0x3b,
&&OPXY0x3c, &&OPXY0x3d, &&OPXY0x3e, &&OPXY0x3f,
&&OPXY0x40, &&OPXY0x41, &&OPXY0x42, &&OPXY0x43,
&&OPXY0x44, &&OPXY0x45, &&OPXY0x46, &&OPXY0x47,
&&OPXY0x48, &&OPXY0x49, &&OPXY0x4a, &&OPXY0x4b,
&&OPXY0x4c, &&OPXY0x4d, &&OPXY0x4e, &&OPXY0x4f,
&&OPXY0x50, &&OPXY0x51, &&OPXY0x52, &&OPXY0x53,
&&OPXY0x54, &&OPXY0x55, &&OPXY0x56, &&OPXY0x57,
&&OPXY0x58, &&OPXY0x59, &&OPXY0x5a, &&OPXY0x5b,
&&OPXY0x5c, &&OPXY0x5d, &&OPXY0x5e, &&OPXY0x5f,
&&OPXY0x60, &&OPXY0x61, &&OPXY0x62, &&OPXY0x63,
&&OPXY0x64, &&OPXY0x65, &&OPXY0x66, &&OPXY0x67,
&&OPXY0x68, &&OPXY0x69, &&OPXY0x6a, &&OPXY0x6b,
&&OPXY0x6c, &&OPXY0x6d, &&OPXY0x6e, &&OPXY0x6f,
&&OPXY0x70, &&OPXY0x71, &&OPXY0x72, &&OPXY0x73,
&&OPXY0x74, &&OPXY0x75, &&OPXY0x76, &&OPXY0x77,
&&OPXY0x78, &&OPXY0x79, &&OPXY0x7a, &&OPXY0x7b,
&&OPXY0x7c, &&OPXY0x7d, &&OPXY0x7e, &&OPXY0x7f,
&&OPXY0x80, &&OPXY0x81, &&OPXY0x82, &&OPXY0x83,
&&OPXY0x84, &&OPXY0x85, &&OPXY0x86, &&OPXY0x87,
&&OPXY0x88, &&OPXY0x89, &&OPXY0x8a, &&OPXY0x8b,
&&OPXY0x8c, &&OPXY0x8d, &&OPXY0x8e, &&OPXY0x8f,
&&OPXY0x90, &&OPXY0x91, &&OPXY0x92, &&OPXY0x93,
&&OPXY0x94, &&OPXY0x95, &&OPXY0x96, &&OPXY0x97,
&&OPXY0x98, &&OPXY0x99, &&OPXY0x9a, &&OPXY0x9b,
&&OPXY0x9c, &&OPXY0x9d, &&OPXY0x9e, &&OPXY0x9f,
&&OPXY0xa0, &&OPXY0xa1, &&OPXY0xa2, &&OPXY0xa3,
&&OPXY0xa4, &&OPXY0xa5, &&OPXY0xa6, &&OPXY0xa7,
&&OPXY0xa8, &&OPXY0xa9, &&OPXY0xaa, &&OPXY0xab,
&&OPXY0xac, &&OPXY0xad, &&OPXY0xae, &&OPXY0xaf,
&&OPXY0xb0, &&OPXY0xb1, &&OPXY0xb2, &&OPXY0xb3,
&&OPXY0xb4, &&OPXY0xb5, &&OPXY0xb6, &&OPXY0xb7,
&&OPXY0xb8, &&OPXY0xb9, &&OPXY0xba, &&OPXY0xbb,
&&OPXY0xbc, &&OPXY0xbd, &&OPXY0xbe, &&OPXY0xbf,
&&OPXY0xc0, &&OPXY0xc1, &&OPXY0xc2, &&OPXY0xc3,
&&OPXY0xc4, &&OPXY0xc5, &&OPXY0xc6, &&OPXY0xc7,
&&OPXY0xc8, &&OPXY0xc9, &&OPXY0xca, &&OPXY0xcb,
&&OPXY0xcc, &&OPXY0xcd, &&OPXY0xce, &&OPXY0xcf,
&&OPXY0xd0, &&OPXY0xd1, &&OPXY0xd2, &&OPXY0xd3,
&&OPXY0xd4, &&OPXY0xd5, &&OPXY0xd6, &&OPXY0xd7,
&&OPXY0xd8, &&OPXY0xd9, &&OPXY0xda, &&OPXY0xdb,
&&OPXY0xdc, &&OPXY0xdd, &&OPXY0xde, &&OPXY0xdf,
&&OPXY0xe0, &&OPXY0xe1, &&OPXY0xe2, &&OPXY0xe3,
&&OPXY0xe4, &&OPXY0xe5, &&OPXY0xe6, &&OPXY0xe7,
&&OPXY0xe8, &&OPXY0xe9, &&OPXY0xea, &&OPXY0xeb,
&&OPXY0xec, &&OPXY0xed, &&OPXY0xee, &&OPXY0xef,
&&OPXY0xf0, &&OPXY0xf1, &&OPXY0xf2, &&OPXY0xf3,
&&OPXY0xf4, &&OPXY0xf5, &&OPXY0xf6, &&OPXY0xf7,
&&OPXY0xf8, &&OPXY0xf9, &&OPXY0xfa, &&OPXY0xfb,
&&OPXY0xfc, &&OPXY0xfd, &&OPXY0xfe, &&OPXY0xff
};
static const void *JumpTableXYCB[0x100] = {
&&OPXYCB0x00, &&OPXYCB0x01, &&OPXYCB0x02, &&OPXYCB0x03,
&&OPXYCB0x04, &&OPXYCB0x05, &&OPXYCB0x06, &&OPXYCB0x07,
&&OPXYCB0x08, &&OPXYCB0x09, &&OPXYCB0x0a, &&OPXYCB0x0b,
&&OPXYCB0x0c, &&OPXYCB0x0d, &&OPXYCB0x0e, &&OPXYCB0x0f,
&&OPXYCB0x10, &&OPXYCB0x11, &&OPXYCB0x12, &&OPXYCB0x13,
&&OPXYCB0x14, &&OPXYCB0x15, &&OPXYCB0x16, &&OPXYCB0x17,
&&OPXYCB0x18, &&OPXYCB0x19, &&OPXYCB0x1a, &&OPXYCB0x1b,
&&OPXYCB0x1c, &&OPXYCB0x1d, &&OPXYCB0x1e, &&OPXYCB0x1f,
&&OPXYCB0x20, &&OPXYCB0x21, &&OPXYCB0x22, &&OPXYCB0x23,
&&OPXYCB0x24, &&OPXYCB0x25, &&OPXYCB0x26, &&OPXYCB0x27,
&&OPXYCB0x28, &&OPXYCB0x29, &&OPXYCB0x2a, &&OPXYCB0x2b,
&&OPXYCB0x2c, &&OPXYCB0x2d, &&OPXYCB0x2e, &&OPXYCB0x2f,
&&OPXYCB0x30, &&OPXYCB0x31, &&OPXYCB0x32, &&OPXYCB0x33,
&&OPXYCB0x34, &&OPXYCB0x35, &&OPXYCB0x36, &&OPXYCB0x37,
&&OPXYCB0x38, &&OPXYCB0x39, &&OPXYCB0x3a, &&OPXYCB0x3b,
&&OPXYCB0x3c, &&OPXYCB0x3d, &&OPXYCB0x3e, &&OPXYCB0x3f,
&&OPXYCB0x40, &&OPXYCB0x41, &&OPXYCB0x42, &&OPXYCB0x43,
&&OPXYCB0x44, &&OPXYCB0x45, &&OPXYCB0x46, &&OPXYCB0x47,
&&OPXYCB0x48, &&OPXYCB0x49, &&OPXYCB0x4a, &&OPXYCB0x4b,
&&OPXYCB0x4c, &&OPXYCB0x4d, &&OPXYCB0x4e, &&OPXYCB0x4f,
&&OPXYCB0x50, &&OPXYCB0x51, &&OPXYCB0x52, &&OPXYCB0x53,
&&OPXYCB0x54, &&OPXYCB0x55, &&OPXYCB0x56, &&OPXYCB0x57,
&&OPXYCB0x58, &&OPXYCB0x59, &&OPXYCB0x5a, &&OPXYCB0x5b,
&&OPXYCB0x5c, &&OPXYCB0x5d, &&OPXYCB0x5e, &&OPXYCB0x5f,
&&OPXYCB0x60, &&OPXYCB0x61, &&OPXYCB0x62, &&OPXYCB0x63,
&&OPXYCB0x64, &&OPXYCB0x65, &&OPXYCB0x66, &&OPXYCB0x67,
&&OPXYCB0x68, &&OPXYCB0x69, &&OPXYCB0x6a, &&OPXYCB0x6b,
&&OPXYCB0x6c, &&OPXYCB0x6d, &&OPXYCB0x6e, &&OPXYCB0x6f,
&&OPXYCB0x70, &&OPXYCB0x71, &&OPXYCB0x72, &&OPXYCB0x73,
&&OPXYCB0x74, &&OPXYCB0x75, &&OPXYCB0x76, &&OPXYCB0x77,
&&OPXYCB0x78, &&OPXYCB0x79, &&OPXYCB0x7a, &&OPXYCB0x7b,
&&OPXYCB0x7c, &&OPXYCB0x7d, &&OPXYCB0x7e, &&OPXYCB0x7f,
&&OPXYCB0x80, &&OPXYCB0x81, &&OPXYCB0x82, &&OPXYCB0x83,
&&OPXYCB0x84, &&OPXYCB0x85, &&OPXYCB0x86, &&OPXYCB0x87,
&&OPXYCB0x88, &&OPXYCB0x89, &&OPXYCB0x8a, &&OPXYCB0x8b,
&&OPXYCB0x8c, &&OPXYCB0x8d, &&OPXYCB0x8e, &&OPXYCB0x8f,
&&OPXYCB0x90, &&OPXYCB0x91, &&OPXYCB0x92, &&OPXYCB0x93,
&&OPXYCB0x94, &&OPXYCB0x95, &&OPXYCB0x96, &&OPXYCB0x97,
&&OPXYCB0x98, &&OPXYCB0x99, &&OPXYCB0x9a, &&OPXYCB0x9b,
&&OPXYCB0x9c, &&OPXYCB0x9d, &&OPXYCB0x9e, &&OPXYCB0x9f,
&&OPXYCB0xa0, &&OPXYCB0xa1, &&OPXYCB0xa2, &&OPXYCB0xa3,
&&OPXYCB0xa4, &&OPXYCB0xa5, &&OPXYCB0xa6, &&OPXYCB0xa7,
&&OPXYCB0xa8, &&OPXYCB0xa9, &&OPXYCB0xaa, &&OPXYCB0xab,
&&OPXYCB0xac, &&OPXYCB0xad, &&OPXYCB0xae, &&OPXYCB0xaf,
&&OPXYCB0xb0, &&OPXYCB0xb1, &&OPXYCB0xb2, &&OPXYCB0xb3,
&&OPXYCB0xb4, &&OPXYCB0xb5, &&OPXYCB0xb6, &&OPXYCB0xb7,
&&OPXYCB0xb8, &&OPXYCB0xb9, &&OPXYCB0xba, &&OPXYCB0xbb,
&&OPXYCB0xbc, &&OPXYCB0xbd, &&OPXYCB0xbe, &&OPXYCB0xbf,
&&OPXYCB0xc0, &&OPXYCB0xc1, &&OPXYCB0xc2, &&OPXYCB0xc3,
&&OPXYCB0xc4, &&OPXYCB0xc5, &&OPXYCB0xc6, &&OPXYCB0xc7,
&&OPXYCB0xc8, &&OPXYCB0xc9, &&OPXYCB0xca, &&OPXYCB0xcb,
&&OPXYCB0xcc, &&OPXYCB0xcd, &&OPXYCB0xce, &&OPXYCB0xcf,
&&OPXYCB0xd0, &&OPXYCB0xd1, &&OPXYCB0xd2, &&OPXYCB0xd3,
&&OPXYCB0xd4, &&OPXYCB0xd5, &&OPXYCB0xd6, &&OPXYCB0xd7,
&&OPXYCB0xd8, &&OPXYCB0xd9, &&OPXYCB0xda, &&OPXYCB0xdb,
&&OPXYCB0xdc, &&OPXYCB0xdd, &&OPXYCB0xde, &&OPXYCB0xdf,
&&OPXYCB0xe0, &&OPXYCB0xe1, &&OPXYCB0xe2, &&OPXYCB0xe3,
&&OPXYCB0xe4, &&OPXYCB0xe5, &&OPXYCB0xe6, &&OPXYCB0xe7,
&&OPXYCB0xe8, &&OPXYCB0xe9, &&OPXYCB0xea, &&OPXYCB0xeb,
&&OPXYCB0xec, &&OPXYCB0xed, &&OPXYCB0xee, &&OPXYCB0xef,
&&OPXYCB0xf0, &&OPXYCB0xf1, &&OPXYCB0xf2, &&OPXYCB0xf3,
&&OPXYCB0xf4, &&OPXYCB0xf5, &&OPXYCB0xf6, &&OPXYCB0xf7,
&&OPXYCB0xf8, &&OPXYCB0xf9, &&OPXYCB0xfa, &&OPXYCB0xfb,
&&OPXYCB0xfc, &&OPXYCB0xfd, &&OPXYCB0xfe, &&OPXYCB0xff
};

3
do.cmd Normal file
View File

@ -0,0 +1,3 @@
copy /Y eboot.pbp h:\PSP\GAME\race
del racepsp.elf
del eboot.pbp

816
flash.cpp Normal file
View File

@ -0,0 +1,816 @@
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
//
// Flash chip emulation by Flavor
// with ideas from Koyote (who originally got ideas from Flavor :)
// for emulation of NGPC carts
//
#ifndef __GP32__
#include "StdAfx.h"
#endif
#include "memory.h"
#include "flash.h"
#include <string.h>
#include <unistd.h>
//#define DEBUG_FLASH
#ifdef DEBUG_FLASH
FILE *debugFile = NULL;
#define stderr debugFile
#define stdout debugFile
#endif
/* Manuf ID's
Supported
0x98 Toshiba
0xEC Samsung
0xB0 Sharp
Other
0x89 Intel
0x01 AMD
0xBF SST
*/
unsigned char manufID = 0x98; //we're always Toshiba!
unsigned char deviceID = 0x2F;
unsigned char cartSize = 32;
unsigned long bootBlockStartAddr = 0x1F0000;
unsigned char bootBlockStartNum = 31;
//unsigned long cartAddrMask = 0x3FFFFF;
//with selector, I get
//writeSaveGameFile: Couldn't open Battery//mnt/sd/Games/race/ChryMast.ngf file
#ifdef __GP32__
#define SAVEGAME_DIR "dev0:\\GPMM\\NGPC\\BATTERY\\"
#else
#define SAVEGAME_DIR "states/"
#endif
unsigned char currentWriteCycle = 1; //can be 1 through 6
unsigned char currentCommand = NO_COMMAND;
#define FLASH_VALID_ID 0x0053
typedef struct NGFheaderStruct
{
unsigned short version; //always 0x53?
unsigned short numBlocks; //how many blocks are in the file
unsigned long fileLen; //length of the file
} ;
typedef struct blockStruct
{
unsigned long NGPCaddr; //where this block starts (in NGPC memory map)
unsigned long len; // length of following data
} ;
#define MAX_BLOCKS 35 //a 16m chip has 35 blocks (SA0-SA34)
unsigned char blocksDirty[2][MAX_BLOCKS]; //max of 2 chips
unsigned char needToWriteFile = 0;
char ngfFilename[300] = {0};
#define FLASH_WRITE 0
#define FLASH_ERASE 1
void setupFlashParams()
{
switch(cartSize)
{
default:
case 32:
deviceID = 0x2F; //the upper chip will always be 16bit
bootBlockStartAddr = 0x1F0000;
bootBlockStartNum = 31;
//cartAddrMask=0x3FFFFF;
break;
case 16:
deviceID = 0x2F;
bootBlockStartAddr = 0x1F0000;
bootBlockStartNum = 31;
//cartAddrMask=0x1FFFFF;
break;
case 8:
deviceID = 0x2C;
bootBlockStartAddr = 0xF0000;
bootBlockStartNum = 15;
//cartAddrMask=0x0FFFFF;
break;
case 4:
deviceID = 0xAB;
bootBlockStartAddr = 0x70000;
bootBlockStartNum = 7;
//cartAddrMask=0x07FFFF;
break;
case 0:
manufID = 0x00;
deviceID = 0x00;
bootBlockStartAddr = 0x00000;
bootBlockStartNum = 0;
//cartAddrMask=0;
break;
}
}
unsigned char blockNumFromAddr(unsigned long addr)
{
addr &= 0x1FFFFF/* & cartAddrMask*/;
if(addr >= bootBlockStartAddr)
{
unsigned long bootAddr = addr-bootBlockStartAddr;
//boot block is 32k, 8k, 8k, 16k (0x8000,0x2000,0x2000,0x4000)
if(bootAddr < 0x8000)
return (bootBlockStartAddr / 0x10000);
else if(bootAddr < 0xA000)
return (bootBlockStartAddr / 0x10000) + 1;
else if(bootAddr < 0xC000)
return (bootBlockStartAddr / 0x10000) + 2;
else if(bootAddr < 0x10000)
return (bootBlockStartAddr / 0x10000) + 3;
}
#ifdef DEBUG_FLASH
fprintf(debugFile, "blockNumFromAddr: addr=0x%08X returning=%d\n", addr, addr / 0x10000);
#endif
return addr / 0x10000;
}
unsigned long blockNumToAddr(unsigned char chip, unsigned char blockNum)
{
unsigned long addr;
if(blockNum >= bootBlockStartNum)
{
addr = bootBlockStartNum * 0x10000;
unsigned char bootBlock = blockNum - bootBlockStartNum;
if(bootBlock>=1)
addr+= 0x8000;
if(bootBlock>=2)
addr+= 0x2000;
if(bootBlock>=3)
addr+= 0x2000;
}
else
addr = blockNum * 0x10000;
if(chip)
addr+=0x200000;
#ifdef DEBUG_FLASH
fprintf(debugFile, "blockNumToAddr: chip=%d blockNum=%d addr=0x%08X\n", chip, blockNum, addr);
#endif
return addr;
}
unsigned long blockSize(unsigned char blockNum)
{
if(blockNum >= bootBlockStartNum)
{
unsigned char bootBlock = blockNum - bootBlockStartNum;
if(bootBlock==3)
return 0x4000;
if(bootBlock==2)
return 0x2000;
if(bootBlock==1)
return 0x2000;
if(bootBlock==0)
return 0x8000;
}
return 0x10000;
}
void setupNGFfilename()
{
int dotSpot = -1, pos = 0;
int slashSpot = -1;
if(strlen(ngfFilename) != 0)
{
#ifdef DEBUG_FLASH
fprintf(debugFile, "setupNGFfilename: %s file already opened\n", ngfFilename);
return; //already set up
#endif
}
strcpy(ngfFilename, SAVEGAME_DIR);
pos = strlen(m_emuInfo.RomFileName);
while(pos>=0)
{
if(m_emuInfo.RomFileName[pos] == '/')
{
slashSpot = pos;
break;
}
pos--;
}
strcat(ngfFilename, &m_emuInfo.RomFileName[slashSpot+1]);
for(pos=strlen(ngfFilename);pos>=0 && dotSpot == -1; pos--)
{
if(ngfFilename[pos] == '.')
dotSpot = pos;
}
if(dotSpot == -1)
{
fprintf(stderr, "setupNGFfilename: Couldn't find the . in %s file\n", ngfFilename);
return;
}
strcpy(&ngfFilename[dotSpot+1], "ngf");
fprintf(stdout, "setupNGFfilename: using %s for save-game info\n", ngfFilename);
}
//write all the dirty blocks out to a file
void writeSaveGameFile()
{
//find the dirty blocks and write them to the .NGF file
int totalBlocks = bootBlockStartNum+4;
int i;
FILE *ngfFile;
int bytes;
NGFheaderStruct NGFheader;
blockStruct block;
#ifdef DEBUG_FLASH
fprintf(debugFile, "writeSaveGameFile: entry totalBlocks=%d\n", totalBlocks);
#endif
setupNGFfilename();
ngfFile = fopen(ngfFilename, "wb");
if(!ngfFile)
{
fprintf(stderr, "writeSaveGameFile: Couldn't open %s file\n", ngfFilename);
return;
}
NGFheader.version = 0x53;
NGFheader.numBlocks = 0;
NGFheader.fileLen = sizeof(NGFheaderStruct);
//add them all up, first
for(i=0;i<totalBlocks;i++)
{
if(blocksDirty[0][i])
{
#ifdef DEBUG_FLASH
fprintf(debugFile, "writeSaveGameFile: found 1st chip dirty block %d\n", i);
#endif
NGFheader.numBlocks++;
NGFheader.fileLen += blockSize(i);
}
}
if(cartSize == 32) //do the second chip, also
{
for(i=0;i<totalBlocks;i++)
{
if(blocksDirty[1][i])
{
#ifdef DEBUG_FLASH
fprintf(debugFile, "writeSaveGameFile: found 2nd chip dirty block %d\n", i);
#endif
NGFheader.numBlocks++;
NGFheader.fileLen += blockSize(i);
}
}
}
NGFheader.fileLen += NGFheader.numBlocks * sizeof(blockStruct);
bytes = fwrite(&NGFheader, 1, sizeof(NGFheaderStruct), ngfFile);
if(bytes != sizeof(NGFheaderStruct))
{
fprintf(stderr, "writeSaveGameFile: wrote %d bytes, but exptected %d bytes\n", bytes, sizeof(NGFheaderStruct));
fclose(ngfFile);
return;
}
for(i=0;i<totalBlocks;i++)
{
if(blocksDirty[0][i])
{
block.NGPCaddr = blockNumToAddr(0, i)+0x200000;
block.len = blockSize(i);
#ifdef DEBUG_FLASH
fprintf(debugFile, "writeSaveGameFile: writing 1st chip block=%d addr=0x%08X len=0x%X\n", i, block.NGPCaddr, block.len);
#endif
bytes = fwrite(&block, 1, sizeof(blockStruct), ngfFile);
if(bytes != sizeof(blockStruct))
{
fprintf(stderr, "writeSaveGameFile: wrote %d bytes, but exptected %d bytes\n", bytes, sizeof(blockStruct));
fclose(ngfFile);
return;
}
bytes = fwrite(&mainrom[blockNumToAddr(0, i)], 1, blockSize(i), ngfFile);
if(bytes != blockSize(i))
{
fprintf(stderr, "writeSaveGameFile: wrote %d bytes, but exptected %d bytes\n", bytes, blockSize(i));
fclose(ngfFile);
return;
}
}
}
if(cartSize == 32) //do the second chip, also
{
for(i=0;i<totalBlocks;i++)
{
if(blocksDirty[1][i])
{
block.NGPCaddr = blockNumToAddr(1, i)+0x600000;
block.len = blockSize(i);
#ifdef DEBUG_FLASH
fprintf(debugFile, "writeSaveGameFile: writing 2nd chip block=%d addr=0x%08X len=0x%X\n", i, block.NGPCaddr, block.len);
#endif
bytes = fwrite(&block, 1, sizeof(blockStruct), ngfFile);
if(bytes != sizeof(blockStruct))
{
fprintf(stderr, "writeSaveGameFile: wrote %d bytes, but exptected %d bytes\n", bytes, sizeof(blockStruct));
fclose(ngfFile);
return;
}
bytes = fwrite(&mainrom[blockNumToAddr(1, i)], 1, blockSize(i), ngfFile);
if(bytes != blockSize(i))
{
fprintf(stderr, "writeSaveGameFile: wrote %d bytes, but exptected %d bytes\n", bytes, blockSize(i));
fclose(ngfFile);
return;
}
}
}
}
fclose(ngfFile);
/* char msg[50];
sprintf(msg, "Saved File %s", ngfFilename);
printTTF(msg, 0, 100, yellow, 1, actualScreen, 1);*/
needToWriteFile = 0;
#ifndef __GP32__
#ifdef TARGET_GP2X
sync();
//system("sync");
#endif
#endif
#ifdef DEBUG_FLASH
fprintf(debugFile, "writeSaveGameFile: exit\n");
#endif
}
//read the save-game file and overlay it onto mainrom
void loadSaveGameFile()
{
//find the NGF file and read it in
FILE *ngfFile;
int bytes, i;
unsigned char *blocks;
void *blockMem;
NGFheaderStruct NGFheader;
blockStruct *blockHeader;
#ifdef DEBUG_FLASH
fprintf(debugFile, "loadSaveGameFile: entry\n");
#endif
setupNGFfilename();
ngfFile = fopen(ngfFilename, "rb");
if(!ngfFile)
{
printf("loadSaveGameFile: Couldn't open %s file\n", ngfFilename);
return;
}
bytes = fread(&NGFheader, 1, sizeof(NGFheaderStruct), ngfFile);
if(bytes != sizeof(NGFheaderStruct))
{
fprintf(stderr, "loadSaveGameFile: Bad NGF file %s\n", ngfFilename);
fclose(ngfFile);
return;
}
/*
unsigned short version; //always 0x53?
unsigned short numBlocks; //how many blocks are in the file
unsigned long fileLen; //length of the file
*/
if(NGFheader.version != 0x53)
{
fprintf(stderr, "loadSaveGameFile: Bad NGF file version %s 0x%X\n", ngfFilename, NGFheader.version);
fclose(ngfFile);
return;
}
blockMem = malloc(NGFheader.fileLen - sizeof(NGFheaderStruct));
//error handling?
if(!blockMem)
{
fprintf(stderr, "loadSaveGameFile: can't malloc %d bytes\n", (NGFheader.fileLen - sizeof(NGFheaderStruct)));
return;
}
blocks = (unsigned char *)blockMem;
bytes = fread(blocks, 1, NGFheader.fileLen - sizeof(NGFheaderStruct), ngfFile);
fclose(ngfFile);
if(bytes != (NGFheader.fileLen - sizeof(NGFheaderStruct)))
{
fprintf(stderr, "loadSaveGameFile: read %d bytes, but exptected %d bytes\n", bytes, (NGFheader.fileLen - sizeof(NGFheaderStruct)));
free(blockMem);
return;
}
if(NGFheader.numBlocks > MAX_BLOCKS)
{
fprintf(stderr, "loadSaveGameFile: numBlocks=%d overflow\n", NGFheader.numBlocks);
free(blockMem);
return;
}
//loop through the blocks and insert them into mainrom
for(i=0; i < NGFheader.numBlocks; i++)
{
blockHeader = (blockStruct*) blocks;
blocks += sizeof(blockStruct);
if(!((blockHeader->NGPCaddr >= 0x200000 && blockHeader->NGPCaddr < 0x400000)
||
(blockHeader->NGPCaddr >= 0x800000 && blockHeader->NGPCaddr < 0xA00000) ))
{
fprintf(stderr, "loadSaveGameFile: invalid blockHeader->NGPCaddr=0x%08X\n", blockHeader->NGPCaddr);
free(blockMem);
return;
}
if(blockHeader->NGPCaddr >= 0x800000)
{
blockHeader->NGPCaddr -= 0x600000;
blocksDirty[1][blockNumFromAddr(blockHeader->NGPCaddr-0x200000)] = 1;
}
else if(blockHeader->NGPCaddr >= 0x200000)
{
blockHeader->NGPCaddr -= 0x200000;
blocksDirty[0][blockNumFromAddr(blockHeader->NGPCaddr)] = 1;
}
memcpy(&mainrom[blockHeader->NGPCaddr], blocks, blockHeader->len);
blocks += blockHeader->len;
}
free(blockMem);
#ifdef DEBUG_FLASH
fprintf(debugFile, "loadSaveGameFile: exit\n");
#endif
}
void flashWriteByte(unsigned long addr, unsigned char data, unsigned char operation)
{
//addr &= cartAddrMask; //the stuff gets mirrored to the higher slots.
if(blockNumFromAddr(addr) == 0) //hack because DWARP writes to bank 0
return;
#ifdef DEBUG_FLASH
if(debugFile != NULL && operation == FLASH_WRITE)
{
fprintf(debugFile, "fWB: addr=0x%08X data=0x%02X\n", addr, data);
}
#endif
//set a dirty flag for the block that we are writing to
if(addr < 0x200000)
{
blocksDirty[0][blockNumFromAddr(addr)] = 1;
needToWriteFile = 1;
}
else if(addr < 0x400000)
{
blocksDirty[1][blockNumFromAddr(addr)] = 1;
needToWriteFile = 1;
}
else
return; //panic
//changed to &= because it's actually how flash works
//flash memory can be erased (changed to 0xFF)
//and when written, 1s can become 0s, but you can't turn 0s into 1s (except by erasing)
if(operation == FLASH_ERASE)
mainrom[addr] = 0xFF; //we're just erasing, so set to 0xFF
else
mainrom[addr] &= data; //actually writing data
}
unsigned char flashReadInfo(unsigned long addr)
{
currentWriteCycle = 1;
currentCommand = COMMAND_INFO_READ;
switch(addr&0x03)
{
case 0:
return manufID;
case 1:
return deviceID;
case 2:
return 0; //block not protected
case 3: //thanks Koyote
default:
return 0x80;
}
}
void flashChipWrite(unsigned long addr, unsigned char data)
{
#ifdef DEBUG_FLASH
if(debugFile != NULL)
{
fprintf(debugFile, "fCW: addr=0x%08X data=0x%02X cycle=%02d command=%02d\n", addr, data, currentWriteCycle, currentCommand);
}
#endif
if(addr >= 0x800000 && cartSize != 32)
return;
switch(currentWriteCycle)
{
case 1:
if((addr & 0xFFFF) == 0x5555 && data == 0xAA)
currentWriteCycle++;
else if(data == 0xF0)
{
currentWriteCycle=1;//this is a reset command
writeSaveGameFile();
}
else
currentWriteCycle=1;
currentCommand = NO_COMMAND;
break;
case 2:
if((addr & 0xFFFF) == 0x2AAA && data == 0x55)
currentWriteCycle++;
else
currentWriteCycle=1;
currentCommand = NO_COMMAND;
break;
case 3:
if((addr & 0xFFFF) == 0x5555 && data == 0x80)
currentWriteCycle++;//continue on
else if((addr & 0xFFFF) == 0x5555 && data == 0xF0)
{
currentWriteCycle=1;
writeSaveGameFile();
}
else if((addr & 0xFFFF) == 0x5555 && data == 0x90)
{
currentWriteCycle++;
currentCommand = COMMAND_INFO_READ;
//now, the next time we read from flash, we should return a ID value
// or a block protect value
break;
}
else if((addr & 0xFFFF) == 0x5555 && data == 0xA0)
{
currentWriteCycle++;
currentCommand = COMMAND_BYTE_PROGRAM;
break;
}
else
currentWriteCycle=1;
currentCommand = NO_COMMAND;
break;
case 4:
if(currentCommand == COMMAND_BYTE_PROGRAM)//time to write to flash memory
{
if(addr >= 0x200000 && addr < 0x400000)
addr -= 0x200000;
else if(addr >= 0x800000 && addr < 0xA00000)
addr -= 0x600000;
//should be changed to just write to mainrom
flashWriteByte(addr, data, FLASH_WRITE);
currentWriteCycle=1;
}
else if((addr & 0xFFFF) == 0x5555 && data == 0xAA)
currentWriteCycle++;
else
currentWriteCycle=1;
currentCommand = NO_COMMAND;
break;
case 5:
if((addr & 0xFFFF) == 0x2AAA && data == 0x55)
currentWriteCycle++;
else
currentWriteCycle=1;
currentCommand = NO_COMMAND;
break;
case 6:
if((addr & 0xFFFF) == 0x5555 && data == 0x10)//chip erase
{
currentWriteCycle=1;
currentCommand = COMMAND_CHIP_ERASE;
//erase the entire chip
//memset it to all 0xFF
//I think we won't implement this
break;
}
if(data == 0x30 || data == 0x50)//block erase
{
unsigned char chip=0;
currentWriteCycle=1;
currentCommand = COMMAND_BLOCK_ERASE;
//erase the entire block that contains addr
//memset it to all 0xFF
if(addr >= 0x800000)
chip = 1;
vectFlashErase(chip, blockNumFromAddr(addr));
break;
}
else
currentWriteCycle=1;
currentCommand = NO_COMMAND;
break;
default:
currentWriteCycle = 1;
currentCommand = NO_COMMAND;
break;
}
}
//this should be called when a ROM is unloaded
void flashShutdown()
{
writeSaveGameFile();
#ifdef DEBUG_FLASH
fclose(debugFile);
#endif
}
//this should be called when a ROM is loaded
void flashStartup()
{
#ifdef DEBUG_FLASH
if(debugFile == NULL)
{
debugFile = fopen("flashDebug.txt", "wt");
}
#endif
memset(blocksDirty[0], 0, MAX_BLOCKS*sizeof(blocksDirty[0][0]));
memset(blocksDirty[1], 0, MAX_BLOCKS*sizeof(blocksDirty[0][0]));
needToWriteFile = 0;
loadSaveGameFile();
}
void vectFlashWrite(unsigned char chip, unsigned int to, unsigned char *fromAddr, unsigned int numBytes)
{
#ifdef DEBUG_FLASH
if(debugFile != NULL)
{
fprintf(debugFile, "vFW: chip=%d to=0x%08X *fromAddr=%02x num=%d\n", chip, to, *fromAddr, numBytes);
}
#endif
if(chip)
to+=0x200000;
//memcpy(dest,fromAddr,numBytes);
while(numBytes--)
{
flashWriteByte(to, *fromAddr, FLASH_WRITE);
fromAddr++;
to++;
}
}
void vectFlashErase(unsigned char chip, unsigned char blockNum)
{
/*unsigned char totalBlocks = bootBlockStartNum+4;
if(blockNum >= totalBlocks)
blockNum = totalBlocks-1;*/
//this needs to be modified to take into account boot block areas (less than 64k)
unsigned long blockAddr = blockNumToAddr(chip, blockNum);
unsigned long numBytes = blockSize(blockNum);
#ifdef DEBUG_FLASH
if(debugFile != NULL)
{
fprintf(debugFile, "vectFlashErase: chip=%d blockNum=%d\n", chip, blockNum);
}
#endif
//memset block to 0xFF
//memset(&mainrom[blockAddr], 0xFF, numBytes);
while(numBytes--)
{
flashWriteByte(blockAddr, 0xFF, FLASH_ERASE);
blockAddr++;
}
}
void vectFlashChipErase(unsigned char chip)
{
#ifdef DEBUG_FLASH
if(debugFile != NULL)
{
fprintf(debugFile, "vectFlashChipErase: chip=%d\n", chip);
}
#endif
}
void setFlashSize(unsigned long romSize)
{
//add individual hacks here.
if(strncmp((const char *)&mainrom[0x24], "DELTA WARP ", 11)==0)//delta warp
{
//1 8mbit chip
cartSize = 8;
}
else if(romSize > 0x200000)
{
//2 16mbit chips
cartSize = 32;
}
else if(romSize > 0x100000)
{
//1 16mbit chip
cartSize = 16;
}
else if(romSize > 0x080000)
{
//1 8mbit chip
cartSize = 8;
}
else if(romSize > 0x040000)
{
//1 4mbit chip
cartSize = 4;
}
else if(romSize == 0) //no cart, just emu BIOS
{
cartSize = 0;
}
else
{
//we don't know. It's probablly a homebrew or something cut down
// so just pretend we're a Bung! cart
//2 16mbit chips
cartSize = 32;
}
setupFlashParams();
flashStartup();
}

37
flash.h Normal file
View File

@ -0,0 +1,37 @@
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
//
// Flash chip emulation by Flavor
// with ideas from Koyote (who originally got ideas from Flavor :)
// for emulation of NGPC carts
//
#define NO_COMMAND 0x00
#define COMMAND_BYTE_PROGRAM 0xA0
#define COMMAND_BLOCK_ERASE 0x30
#define COMMAND_CHIP_ERASE 0x10
#define COMMAND_INFO_READ 0x90
extern unsigned char currentCommand;//what command are we currently on (if any)
void flashChipWrite(unsigned long addr, unsigned char data);
void vectFlashWrite(unsigned char chip, unsigned int to, unsigned char *fromAddr, unsigned int numBytes);
void vectFlashErase(unsigned char chip, unsigned char blockNum);
void vectFlashChipErase(unsigned char chip);
void setFlashSize(unsigned long romSize);
void flashShutdown();
unsigned char flashReadInfo(unsigned long addr);
extern unsigned char needToWriteFile;
void writeSaveGameFile();
#define WRITE_SAVEGAME_IF_DIRTY if(needToWriteFile) writeSaveGameFile();//we found a dirty one, so write the file

1722
graphics.cpp Normal file

File diff suppressed because it is too large Load Diff

81
graphics.h Normal file
View File

@ -0,0 +1,81 @@
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
// graphics.h: interface for the graphics class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_GRAPHICS_H__EE4B1FE1_8EB2_11D3_8644_00A0241D2A65__INCLUDED_)
#define AFX_GRAPHICS_H__EE4B1FE1_8EB2_11D3_8644_00A0241D2A65__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//actual NGPC
#define NGPC_SIZEX 160
#define NGPC_SIZEY 152
#define ZOOM_SUPPORT
//render screen 260x152 is good for NGPC
#define SIZEX 260//480//368//320//480
#define SIZEY 152//272//207//240//272
//extern unsigned char bwPaletteDirty, spritePaletteDirty, frontPaletteDirty, backPaletteDirty;
//extern unsigned char bgoowDirty;
//extern unsigned int spritesDirty;
// graphics buffer will hold the screen transformed to full RGB colors used by the emulated system
//extern int *graphics_buffer;
//extern unsigned short *drawBuffer;
//extern unsigned short drawBuffer[SIZEX*SIZEY];
//extern unsigned char *drawBuffer;
//extern BITMAP myBitmap;
#ifndef __GP32__
BOOL graphics_init(HWND phWnd);
#else
BOOL graphics_init();
#endif
void graphics_blit(void);
void graphics_paint();
void graphics_cleanup();
void write_screenshot(FILE *f);
// new renderer (NeoGeo Pocket (Color))
void incFrameCount();
void graphicsBlitInit();
void graphicsBlitLine(unsigned char render);
void myGraphicsBlitLine(unsigned char render);
void graphicsBlitEnd();
// renderer for Gameboy Color
void gbcGraphicsBlitInit();
void gbcGraphicsBlitLine();
void setColPaletteEntry(unsigned char addr, unsigned short data);
void setBWPaletteEntry(unsigned char addr, unsigned short data);
//
// adventure vision stuff
//
void advGraphicsEnd();
void graphics_debug(FILE *f);
extern unsigned short palettes[16*4+16*4+16*4]; // placeholder for the converted palette
extern int totalpalette[32*32*32];
#define NGPC_TO_SDL16(col) totalpalette[col]
#define setColPaletteEntry(addr, data) palettes[(addr)] = NGPC_TO_SDL16(data)
#define setBWPaletteEntry(addr, data) palettes[(addr)] = NGPC_TO_SDL16(data)
extern unsigned char *scanlineY;
#endif // !defined(AFX_GRAPHICS_H__EE4B1FE1_8EB2_11D3_8644_00A0241D2A65__INCLUDED_)

48
homehook Makefile.psp Normal file
View File

@ -0,0 +1,48 @@
PSPSDK=$(shell psp-config --pspsdk-path)
PSPAPP=psp
PSPLIB=$(PSPAPP)/psplib
PSP_FW_VERSION=200
export PSP_FW_VERSION
PSP_APP_NAME=RACE! PSP
PSP_APP_VER=2.17
TARGET=racepsp
EXTRA_TARGETS=EBOOT.PBP
PSP_EBOOT_TITLE=$(PSP_APP_NAME) $(PSP_APP_VER)
PSP_EBOOT_ICON=$(PSPAPP)/race-icon.png
BUILD_EMUL=cz80.o cz80_support.o input.o neopopsound.o \
ngpBios.o tlcs900h.o memory.o flash.o graphics.o \
main.o state.o sound.o
BUILD_MZ=ioapi.o unzip.o
BUILD_PORT=$(PSPAPP)/main.o $(PSPAPP)/emulate.o $(PSPAPP)/menu.o
HOMEHOOKOBJ = $(PSPAPP)/homehook.o
OBJS=$(BUILD_EMUL) $(BUILD_MZ) $(BUILD_PORT) $(HOMEHOOKOBJ)
DEFINES=-DCZ80 -DTARGET_PSP -D_MAX_PATH=2048 -DHOST_FPS=60
BASE_DEFS=-DPSP -DPSP_APP_VER=\"$(PSP_APP_VER)\" -DPSP_APP_NAME="\"$(PSP_APP_NAME)\""
CFLAGS=-O2 -G0 -Wall -DHOME_HOOK $(BASE_DEFS) $(DEFINES)
CXXFLAGS=$(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS=$(CFLAGS)
INCDIR=$(PSPLIB) $(PSPAPP)/homehookprx
LIBDIR=$(PSPLIB)
LIBS=-lpsplib -lpng -lpspgu -lpsppower \
-lz -lm -lc -lpspaudio -lpsprtc -lpspwlan -lpspnet_adhoc \
-lpspnet_adhocctl -lpspnet_adhocmatching
all: build_libs
clean: clean_libs
include $(PSPSDK)/lib/build.mak
build_libs:
cd $(PSPLIB) ; $(MAKE)
clean_libs:
cd $(PSPLIB) ; $(MAKE) clean

8
homehook.S Normal file
View File

@ -0,0 +1,8 @@
.set noreorder
#include "pspstub.s"
STUB_START "homehook",0x40090000,0x00020005
STUB_FUNC 0xDDC19F6B,initHomeButton
STUB_FUNC 0x40DC34E4,readHomeButton
STUB_END

13
homehook.h Normal file
View File

@ -0,0 +1,13 @@
/******************************************************************************
homehook.prx
******************************************************************************/
#ifndef HOMEHOOK_PRX_H
#define HOMEHOOK_PRX_H
void initHomeButton(int devkit_version);
unsigned int readHomeButton(void);
#endif /* HOMEHOOK_PRX_H */

261
input.cpp Normal file
View File

@ -0,0 +1,261 @@
// input.cpp: implementation of the input class.
//
//////////////////////////////////////////////////////////////////////
//Flavor - Convert from DirectInput to SDL/GP2X
#ifndef __GP32__
#include "StdAfx.h"
#endif
#include "main.h"
#include "input.h"
#include "memory.h"
///#include "menu.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
// address where the state of the input device(s) is stored
//unsigned char *InputByte = get_address(0x00006F82);
unsigned char ngpInputState = 0;
unsigned char *InputByte = &ngpInputState;
#ifndef TARGET_PSP
extern SDL_Joystick *joystick;
#endif
#ifdef ZOOM_SUPPORT
extern int zoom;
#endif
#ifdef __GP32__
#define DIK_UP BUTTON_UP
#define DIK_DOWN BUTTON_DOWN
#define DIK_LEFT BUTTON_LEFT
#define DIK_RIGHT BUTTON_RIGHT
#define DIK_SPACE BUTTON_A
#define DIK_N BUTTON_B
#define DIK_S BUTTON_SELECT
#define DIK_O BUTTON_START
#else
#define DIK_UP SDLK_UP
#define DIK_DOWN SDLK_DOWN
#define DIK_LEFT SDLK_LEFT
#define DIK_RIGHT SDLK_RIGHT
#define DIK_SPACE SDLK_a
#define DIK_N SDLK_b
#define DIK_S SDLK_ESCAPE
#define DIK_O SDLK_SPACE
#endif
#define DOWN(x) keystates[x]
#ifdef __GP32__
u16 keystates = 0;
#else
Uint8 *keystates = NULL;
#endif
struct joy_range
{
int minx, maxx, miny, maxy;
} range;
#ifdef __GP32__
void InitInput()
#else
BOOL InitInput(HWND hwnd)
#endif
{
#ifndef TARGET_PSP
#ifndef __GP32__
keystates = PSP_GetKeyStateArray(NULL);
#endif
// setup standard values for input
// NGP/NGPC:
m_sysInfo[NGP].InputKeys[KEY_UP] = DIK_UP;
m_sysInfo[NGP].InputKeys[KEY_DOWN] = DIK_DOWN;
m_sysInfo[NGP].InputKeys[KEY_LEFT] = DIK_LEFT;
m_sysInfo[NGP].InputKeys[KEY_RIGHT] = DIK_RIGHT;
m_sysInfo[NGP].InputKeys[KEY_BUTTON_A] = DIK_SPACE;
m_sysInfo[NGP].InputKeys[KEY_BUTTON_B] = DIK_N;
m_sysInfo[NGP].InputKeys[KEY_SELECT] = DIK_O; // Option button
m_sysInfo[NGPC].InputKeys[KEY_UP] = DIK_UP;
m_sysInfo[NGPC].InputKeys[KEY_DOWN] = DIK_DOWN;
m_sysInfo[NGPC].InputKeys[KEY_LEFT] = DIK_LEFT;
m_sysInfo[NGPC].InputKeys[KEY_RIGHT] = DIK_RIGHT;
m_sysInfo[NGPC].InputKeys[KEY_BUTTON_A] = DIK_SPACE;
m_sysInfo[NGPC].InputKeys[KEY_BUTTON_B] = DIK_N;
m_sysInfo[NGPC].InputKeys[KEY_SELECT] = DIK_O; // Option button
range.minx = -32767;//INT_MIN;
range.maxx = 32767;//INT_MAX;
range.miny = -32767;//INT_MIN;
range.maxy = 32767;//INT_MAX;
#endif /* TARGET_PSP */
return TRUE;
}
#ifdef __GP32__
extern "C"
{
int gp_getButton();
void clearScreen();
}
int zoom=0,zoomy=16;
#endif
#ifndef TARGET_PSP
void UpdateInputState()
{
#ifdef __GP32__
int key = gp_getButton();
if ((key & BUTTON_R) && (key & BUTTON_L))
{
m_bIsActive = FALSE;//Flavor exit emulation
return;
}
if (key & BUTTON_R) {
zoom ^= 1;
while ((key=gp_getButton())&BUTTON_R);
if (!zoom)
clearScreen();
}
if (key & BUTTON_L) {
if (key & BUTTON_DOWN) {
if (zoomy<32)
zoomy+=1;
return;
}
if (key & BUTTON_UP) {
if (zoomy>0)
zoomy-=1;
return;
}
}
if(key & BUTTON_DOWN)
*InputByte = 0x02;
else if(key & BUTTON_UP)
*InputByte = 0x01;
else
*InputByte = 0;
if(key & BUTTON_RIGHT)
*InputByte |= 0x08;
else if(key & BUTTON_LEFT)
*InputByte |= 0x04;
if (key & BUTTON_A)
*InputByte|= 0x10;
if (key & BUTTON_B)
*InputByte|= 0x20;
if (key & BUTTON_SELECT)
*InputByte|= 0x40;
#else
SDL_Event event;
#ifdef TARGET_PSP
while(SDL_PollEvent(&event))
{
}
if (SDL_JoystickGetButton(joystick, PSP_BUTTON_R) && SDL_JoystickGetButton(joystick, PSP_BUTTON_L))
{
m_bIsActive = FALSE;//Flavor exit emulation
return;
}
int x_axis = SDL_JoystickGetAxis (joystick, 0);
int y_axis = SDL_JoystickGetAxis (joystick, 1);
/* if (x_axis < range.minx) range.minx = x_axis;
if (y_axis < range.miny) range.miny = y_axis;
if (x_axis > range.maxx) range.maxx = x_axis;
if (y_axis > range.maxy) range.maxy = y_axis;
*/
*InputByte = 0;
if(SDL_JoystickGetButton(joystick, PSP_BUTTON_DOWN) || (y_axis > (range.miny + 2*(range.maxy - range.miny)/3)))
{
*InputByte |= 0x02;
}
if(SDL_JoystickGetButton(joystick, PSP_BUTTON_UP) || (y_axis < (range.miny + (range.maxy - range.miny)/3)))
{
*InputByte |= 0x01;
}
if(SDL_JoystickGetButton(joystick, PSP_BUTTON_RIGHT) || (x_axis > (range.minx + 2*(range.maxx - range.minx)/3)))
{
*InputByte |= 0x08;
}
if(SDL_JoystickGetButton(joystick, PSP_BUTTON_LEFT) || (x_axis < (range.minx + (range.maxx - range.minx)/3)))
{
*InputByte |= 0x04;
}
if (SDL_JoystickGetButton(joystick, PSP_BUTTON_X))
*InputByte |= 0x10;
if (SDL_JoystickGetButton(joystick, PSP_BUTTON_O))
*InputByte |= 0x20;
if (SDL_JoystickGetButton(joystick, PSP_BUTTON_TRI))
*InputByte |= 0x40;
/* no variable zoom for now
#ifdef ZOOM_SUPPORT
if(SDL_JoystickGetButton(joystick, PSP_BUTTON_R) && zoom<60)//272-152=120/2=60
zoom++;
if(SDL_JoystickGetButton(joystick, PSP_BUTTON_L) && zoom>0)
zoom--;
#endif*/
/*if (SDL_JoystickGetButton(joystick, PSP_BUTTON_VOLUP))
increaseVolume();
else if (SDL_JoystickGetButton(joystick, PSP_BUTTON_VOLDOWN))
decreaseVolume();*/
#else
SYSTEMINFO *si;
PSP_SetKeyStates(); //make sure they're updated
while(SDL_PollEvent(&event))
{
}
if (DOWN(SDLK_r) && DOWN(SDLK_l))
m_bIsActive = FALSE;//Flavor exit emulation
si = &m_sysInfo[NGP];
*InputByte = 0;
if (DOWN(si->InputKeys[KEY_BUTTON_A]))
*InputByte|= 0x10;
if (DOWN(si->InputKeys[KEY_BUTTON_B]))
*InputByte|= 0x20;
if (DOWN(si->InputKeys[KEY_SELECT]))
*InputByte|= 0x40;
if (DOWN(si->InputKeys[KEY_UP]))
*InputByte|= 0x01;
if (DOWN(si->InputKeys[KEY_DOWN]))
*InputByte|= 0x02;
if (DOWN(si->InputKeys[KEY_LEFT]))
*InputByte|= 0x04;
if (DOWN(si->InputKeys[KEY_RIGHT]))
*InputByte|= 0x08;
if (DOWN(SDLK_KP_PLUS))
increaseVolume();
else if (DOWN(SDLK_KP_MINUS))
decreaseVolume();
#endif
#endif
}
#endif /* TARGET_PSP */
void FreeInput()
{
}

33
input.h Normal file
View File

@ -0,0 +1,33 @@
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
// input.h: interface for the input class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_INPUT_H__59701BE2_A97A_11D3_8645_00A0241D2A65__INCLUDED_)
#define AFX_INPUT_H__59701BE2_A97A_11D3_8645_00A0241D2A65__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//Flavor#define DIRECTINPUT_VERSION 0x0300
//Flavor#include <dinput.h>
extern unsigned char ngpInputState;
#ifndef __GP32__
BOOL InitInput(HWND hWnd);
#else
void InitInput();
#endif
void UpdateInputState();
void FreeInput();
#endif // !defined(AFX_INPUT_H__59701BE2_A97A_11D3_8645_00A0241D2A65__INCLUDED_)

177
ioapi.c Normal file
View File

@ -0,0 +1,177 @@
/* ioapi.c -- IO base function header for compress/uncompress .zip
files using zlib + zip or unzip API
Version 1.00, September 10th, 2003
Copyright (C) 1998-2003 Gilles Vollant
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "zlib.h"
#include "ioapi.h"
/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
#ifndef SEEK_CUR
#define SEEK_CUR 1
#endif
#ifndef SEEK_END
#define SEEK_END 2
#endif
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
voidpf ZCALLBACK fopen_file_func OF((
voidpf opaque,
const char* filename,
int mode));
uLong ZCALLBACK fread_file_func OF((
voidpf opaque,
voidpf stream,
void* buf,
uLong size));
uLong ZCALLBACK fwrite_file_func OF((
voidpf opaque,
voidpf stream,
const void* buf,
uLong size));
long ZCALLBACK ftell_file_func OF((
voidpf opaque,
voidpf stream));
long ZCALLBACK fseek_file_func OF((
voidpf opaque,
voidpf stream,
uLong offset,
int origin));
int ZCALLBACK fclose_file_func OF((
voidpf opaque,
voidpf stream));
int ZCALLBACK ferror_file_func OF((
voidpf opaque,
voidpf stream));
voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)
voidpf opaque;
const char* filename;
int mode;
{
FILE* file = NULL;
const char* mode_fopen = NULL;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
mode_fopen = "rb";
else
if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
mode_fopen = "r+b";
else
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
mode_fopen = "wb";
if ((filename!=NULL) && (mode_fopen != NULL))
file = fopen(filename, mode_fopen);
return file;
}
uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
voidpf opaque;
voidpf stream;
void* buf;
uLong size;
{
uLong ret;
ret = fread(buf, 1, (size_t)size, (FILE *)stream);
return ret;
}
uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
voidpf opaque;
voidpf stream;
const void* buf;
uLong size;
{
uLong ret;
ret = fwrite(buf, 1, (size_t)size, (FILE *)stream);
return ret;
}
long ZCALLBACK ftell_file_func (opaque, stream)
voidpf opaque;
voidpf stream;
{
long ret;
ret = ftell((FILE *)stream);
return ret;
}
long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)
voidpf opaque;
voidpf stream;
uLong offset;
int origin;
{
int fseek_origin=0;
long ret;
switch (origin)
{
case ZLIB_FILEFUNC_SEEK_CUR :
fseek_origin = SEEK_CUR;
break;
case ZLIB_FILEFUNC_SEEK_END :
fseek_origin = SEEK_END;
break;
case ZLIB_FILEFUNC_SEEK_SET :
fseek_origin = SEEK_SET;
break;
default: return -1;
}
ret = 0;
fseek((FILE *)stream, offset, fseek_origin);
return ret;
}
int ZCALLBACK fclose_file_func (opaque, stream)
voidpf opaque;
voidpf stream;
{
int ret;
ret = fclose((FILE *)stream);
return ret;
}
int ZCALLBACK ferror_file_func (opaque, stream)
voidpf opaque;
voidpf stream;
{
int ret;
ret = ferror((FILE *)stream);
return ret;
}
void fill_fopen_filefunc (pzlib_filefunc_def)
zlib_filefunc_def* pzlib_filefunc_def;
{
pzlib_filefunc_def->zopen_file = fopen_file_func;
pzlib_filefunc_def->zread_file = fread_file_func;
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
pzlib_filefunc_def->ztell_file = ftell_file_func;
pzlib_filefunc_def->zseek_file = fseek_file_func;
pzlib_filefunc_def->zclose_file = fclose_file_func;
pzlib_filefunc_def->zerror_file = ferror_file_func;
pzlib_filefunc_def->opaque = NULL;
}

75
ioapi.h Normal file
View File

@ -0,0 +1,75 @@
/* ioapi.h -- IO base function header for compress/uncompress .zip
files using zlib + zip or unzip API
Version 1.00, September 10th, 2003
Copyright (C) 1998-2003 Gilles Vollant
*/
#ifndef _ZLIBIOAPI_H
#define _ZLIBIOAPI_H
#define ZLIB_FILEFUNC_SEEK_CUR (1)
#define ZLIB_FILEFUNC_SEEK_END (2)
#define ZLIB_FILEFUNC_SEEK_SET (0)
#define ZLIB_FILEFUNC_MODE_READ (1)
#define ZLIB_FILEFUNC_MODE_WRITE (2)
#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
#define ZLIB_FILEFUNC_MODE_EXISTING (4)
#define ZLIB_FILEFUNC_MODE_CREATE (8)
#ifndef ZCALLBACK
#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
#define ZCALLBACK CALLBACK
#else
#define ZCALLBACK
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
typedef struct zlib_filefunc_def_s
{
open_file_func zopen_file;
read_file_func zread_file;
write_file_func zwrite_file;
tell_file_func ztell_file;
seek_file_func zseek_file;
close_file_func zclose_file;
testerror_file_func zerror_file;
voidpf opaque;
} zlib_filefunc_def;
void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
#ifdef __cplusplus
}
#endif
#endif

BIN
koyote.bin Normal file

Binary file not shown.

772
koyote_bin.h Normal file
View File

@ -0,0 +1,772 @@
#define KOYOTE_BIN_SIZE 12288
const unsigned char koyote_bin[KOYOTE_BIN_SIZE] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00,
0x01, 0x00, 0x03, 0x00, 0x13, 0x00, 0x07, 0x00, 0x24, 0x00, 0x30, 0x00, 0x99, 0x01, 0x03, 0x13,
0x07, 0x24, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 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, 0x20, 0x00, 0x31, 0x00,
0x3A, 0x00, 0x30, 0x00, 0x37, 0x00, 0x20, 0x00, 0x50, 0x00, 0x4D, 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, 0x11, 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, 0x7C, 0xE5, 0xFF, 0x00, 0x72, 0xE5, 0xFF, 0x00, 0x6C, 0xE5,
0xFF, 0x00, 0x66, 0xE5, 0xFF, 0x00, 0x62, 0xE5, 0xFF, 0x00, 0x5C, 0xE5, 0xFF, 0x00, 0x56, 0xE5,
0xFF, 0x00, 0x4E, 0xE5, 0xFF, 0x00, 0x44, 0xE5, 0xFF, 0x00, 0x3C, 0xE5, 0xFF, 0x00, 0x32, 0xE5,
0xFF, 0x00, 0x28, 0xE5, 0xFF, 0x00, 0xC0, 0xE7, 0xFF, 0x00, 0xB4, 0xE7, 0xFF, 0x00, 0xA8, 0xE7,
0xFF, 0x00, 0x96, 0xE7, 0xFF, 0x00, 0x8A, 0xE7, 0xFF, 0x00, 0x80, 0xE7, 0xFF, 0x00, 0x76, 0xE7,
0xFF, 0x00, 0x70, 0xE7, 0xFF, 0x00, 0x68, 0xE7, 0xFF, 0x00, 0x5E, 0xE7, 0xFF, 0x00, 0x54, 0xE7,
0xFF, 0x00, 0x4C, 0xE7, 0xFF, 0x00, 0x40, 0xE7, 0xFF, 0x00, 0x30, 0xE7, 0xFF, 0x00, 0xE4, 0xE7,
0xFF, 0x00, 0xDA, 0xE7, 0xFF, 0x00, 0xD2, 0xE7, 0xFF, 0x00, 0xFC, 0xE8, 0xFF, 0x00, 0xEE, 0xE8,
0xFF, 0x00, 0xE0, 0xE8, 0xFF, 0x00, 0xD2, 0xE8, 0xFF, 0x00, 0xC4, 0xE8, 0xFF, 0x00, 0xB6, 0xE8,
0xFF, 0x00, 0xA6, 0xE8, 0xFF, 0x00, 0x96, 0xE8, 0xFF, 0x00, 0x86, 0xE8, 0xFF, 0x00, 0x76, 0xE8,
0xFF, 0x00, 0x66, 0xE8, 0xFF, 0x00, 0x56, 0xE8, 0xFF, 0x00, 0x46, 0xE8, 0xFF, 0x00, 0x36, 0xE8,
0xFF, 0x00, 0x26, 0xE8, 0xFF, 0x00, 0x16, 0xE8, 0xFF, 0x00, 0x06, 0xE8, 0xFF, 0x00, 0xF6, 0xE7,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x86, 0xF2, 0x1A, 0xCA, 0x00, 0x0E, 0xF2, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0F, 0x00, 0x0F, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0A,
0x00, 0x09, 0x00, 0x08, 0x00, 0x08, 0x00, 0x07, 0x00, 0x06, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04,
0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0x10, 0x38, 0x00, 0x78, 0x03, 0x18, 0x10, 0x3E, 0x08, 0x00, 0x03, 0x1E, 0x10, 0x3E, 0x08, 0x00,
0x03, 0x1E, 0x10, 0x3E, 0x08, 0x00, 0x03, 0x1E, 0x11, 0x3E, 0x08, 0x00, 0x03, 0x1E, 0x12, 0x3E,
0x00, 0x00, 0x40, 0x01, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x1E,
0x12, 0x3E, 0x08, 0x00, 0x03, 0x1E, 0x12, 0x3E, 0x08, 0x00, 0x03, 0x1E, 0x12, 0x3E, 0x08, 0x00,
0x03, 0x1E, 0x12, 0x3E, 0x08, 0x00, 0x03, 0x1E, 0x12, 0x3E, 0x08, 0x00, 0x03, 0x1E, 0x12, 0x3E,
0x08, 0x00, 0x03, 0x1E, 0x12, 0x3E, 0x08, 0x00, 0x03, 0x1E, 0x12, 0x3E, 0x08, 0x00, 0x03, 0x1E,
0x12, 0x3E, 0x08, 0x00, 0x03, 0x1E, 0x12, 0x3E, 0x08, 0x00, 0x03, 0x1E, 0x12, 0x3E, 0x08, 0x00,
0x03, 0x1E, 0x12, 0x3E, 0x08, 0x00, 0x03, 0x1E, 0x13, 0x18, 0x60, 0x88, 0x04, 0x00, 0x14, 0x18,
0x68, 0x88, 0x04, 0x00, 0x15, 0x18, 0x70, 0x88, 0x04, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F,
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, 0x0F, 0x00, 0x0F, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0A,
0x00, 0x09, 0x00, 0x08, 0x00, 0x08, 0x00, 0x07, 0x00, 0x06, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04,
0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0x00, 0x07, 0x00, 0x06,
0x00, 0x06, 0x00, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x46, 0x00, 0x46, 0x00, 0x45, 0x80, 0x46, 0x80, 0x47, 0x00, 0x48, 0x00, 0x47, 0x00, 0x44,
0x80, 0x44, 0x80, 0x43, 0x00, 0x49, 0x80, 0x49, 0x80, 0x4A, 0x00, 0x4B, 0x00, 0x4A, 0x80, 0x45,
0xC0, 0x4B, 0x00, 0x4C, 0x80, 0x4B, 0x40, 0x4C, 0x80, 0x4C, 0xC0, 0x4C, 0x00, 0x4D, 0x40, 0x4D,
0x80, 0x4D, 0xC0, 0x4D, 0x00, 0x4E, 0x40, 0x4E, 0x80, 0x4E, 0xC0, 0x4E, 0x00, 0x4F, 0x40, 0x4F,
0x02, 0x00, 0x04, 0x00, 0x06, 0x00, 0x06, 0x00, 0x10, 0x01, 0x00, 0xFF, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x11, 0x00, 0x8E, 0x02, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0xA0, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x02, 0x87, 0xFC, 0x00, 0x00,
0xD6, 0x55, 0xFF, 0x00, 0x30, 0x45, 0x08, 0x08, 0x00, 0x02, 0x01, 0x90, 0xC2, 0x93, 0x01, 0x01,
0x09, 0x00, 0x01, 0x90, 0xC2, 0x93, 0x01, 0x01, 0x05, 0x00, 0x01, 0x90, 0x42, 0x94, 0x01, 0x01,
0x09, 0x00, 0x01, 0x90, 0x42, 0x94, 0x01, 0x01, 0x05, 0x00, 0x06, 0x90, 0x80, 0x93, 0x12, 0x03,
0x06, 0x00, 0x08, 0x81, 0x44, 0x9B, 0x08, 0x01, 0xA1, 0x00, 0x08, 0x81, 0xC2, 0x9B, 0x12, 0x03,
0x9F, 0x55, 0xFF, 0x00, 0xA2, 0x9C, 0x01, 0x01, 0x3A, 0x5A, 0xFF, 0x00, 0x02, 0x90, 0xC2, 0x93,
0x12, 0x01, 0x0A, 0x00, 0x02, 0x90, 0x42, 0x94, 0x12, 0x01, 0x1C, 0x00, 0xF0, 0x01, 0x06, 0x90,
0x80, 0x93, 0x12, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x28, 0x56, 0x67, 0x00, 0x18,
0x00, 0x47, 0x00, 0x18, 0x00, 0x4B, 0x00, 0x18, 0x80, 0x4B, 0x00, 0x18, 0x00, 0x4C, 0x00, 0x00,
0x00, 0x47, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xFF, 0x47, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xFE, 0x4B, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xFC, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xFB, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xFA, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xF6, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xF4, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xF3, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xF2, 0xB7, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xF1, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xF0, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xEF, 0x67, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xEE, 0x18, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xED, 0x28, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xEC, 0x28, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xEB, 0x30, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xEA, 0x30, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xE9, 0x38, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xE8, 0x38, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xE7, 0x40, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xE6, 0x40, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xE5, 0x48, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xE4, 0x48, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xE3, 0x48, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xE2, 0x50, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xE1, 0x50, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xE0, 0x58, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xDF, 0x58, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xDE, 0x78, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xDD, 0x80, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xDC, 0x80, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xDB, 0x88, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xDA, 0x88, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xD9, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xD8, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xD7, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xD6, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xD5, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xD4, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xD3, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xD2, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xD1, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xD0, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xCF, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xCE, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xCD, 0x0D, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xCC, 0x1F, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xCB, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xCA, 0x09, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xC9, 0x1F, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xC8, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xC7, 0x01, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xC6, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xC5, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xC4, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xC2, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xC0, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xBE, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xBD, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xBC, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xBA, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xB9, 0x01, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xB8, 0x01, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xB7, 0x01, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xB6, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xB5, 0x01, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xB4, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xB3, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xB2, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xB1, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xB0, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xAF, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xAE, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xAD, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xAC, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xAA, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xA9, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xA8, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xA7, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xA6, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xA5, 0x01, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xA4, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xA3, 0x01, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xA2, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0xA0, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x9F, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x9E, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x9D, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x9C, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x9B, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x9A, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x99, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x98, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x97, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x96, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x95, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x94, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x93, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x92, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x91, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x90, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x8F, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x8E, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x8C, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x8A, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x89, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x88, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x87, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x86, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x85, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x84, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x83, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x82, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x81, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x80, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x7E, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x7C, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x7B, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x7A, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x79, 0x02, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x78, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x77, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x76, 0x01, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x75, 0x65, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x74, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x73, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x72, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x71, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x70, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x6E, 0x81, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x6D, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x6C, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x6B, 0x83, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x6A, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x69, 0x81, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x68, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x67, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x66, 0x82, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x65, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x64, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x63, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x62, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x61, 0x80, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x60, 0x82, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x5E, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x5C, 0x80, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x5A, 0x81, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x59, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x58, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x57, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x56, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x55, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x54, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x53, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x52, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x51, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x50, 0x81, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x4F, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x4E, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x4C, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x4A, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x49, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x48, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x47, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x46, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x45, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x44, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x43, 0x83, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x42, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x41, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x40, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x3E, 0x83, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x3C, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x3A, 0x82, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x39, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x38, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x37, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x36, 0x10, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x35, 0x10, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x34, 0x10, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x33, 0x10, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x32, 0x10, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x31, 0x10, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x30, 0x10, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x2F, 0x11, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x2E, 0x11, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x2D, 0x11, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x2C, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x2A, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x29, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x28, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x26, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x24, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x23, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x22, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x21, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x20, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x19, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x18, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x17, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x16, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x15, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x14, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x13, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x12, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x10, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x0E, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x09, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x08, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x07, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x06, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x04, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x02, 0x00, 0x3D, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3D, 0x00, 0x3D, 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, 0x85, 0x80, 0x00, 0x00,
0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00, 0x05, 0x00, 0x98, 0x00,
0xE8, 0x00, 0xFA, 0x00, 0x74, 0x01, 0x84, 0x01, 0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00,
0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00,
0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00,
0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00,
0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00,
0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00,
0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00, 0x85, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x50, 0x00, 0x00, 0x00, 0x00, 0x64, 0x20, 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, 0x10, 0x00, 0xC0, 0x03, 0x00, 0xE7, 0x3F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7B, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0xEF, 0x01, 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, 0xC0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x00, 0x84, 0x00,
0x99, 0x01, 0x00, 0x00, 0x18, 0x00, 0x21, 0x01, 0x84, 0x01, 0x00, 0x00, 0x14, 0x00, 0x8D, 0x00,
0x65, 0x01, 0x00, 0x00, 0xB2, 0x00, 0x54, 0x01, 0x6C, 0x01, 0x00, 0x00, 0x4B, 0x00, 0xA0, 0x00,
0xEE, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0xFF, 0x05, 0x6C, 0x94, 0x85, 0x7B, 0x0F, 0x00, 0x05, 0x40, 0x0B, 0x00,
0x0F, 0x00, 0x00, 0x40, 0x05, 0x40, 0x06, 0x40, 0x07, 0x40, 0x08, 0x40, 0x0A, 0x40, 0x09, 0x40,
0x01, 0x40, 0x02, 0x40, 0x03, 0x40, 0x04, 0x40, 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, 0x05, 0x02, 0x04, 0x04, 0x05, 0x06, 0x04, 0x02, 0x0E, 0x04, 0x04, 0x05,
0x02, 0x04, 0x05, 0x06, 0x07, 0x07, 0x00, 0xFB, 0x0C, 0x00, 0xDE, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x27, 0x7D, 0x00, 0x00, 0x0F, 0x7A, 0x00, 0x00, 0xAC, 0x7F, 0x00, 0x00, 0x27, 0x7D,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xAB, 0x26, 0x00, 0x12, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 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,
0x07, 0x00, 0x18, 0x58, 0x00, 0x00, 0x80, 0x98, 0x00, 0xAC, 0x00, 0x62, 0xFF, 0x00, 0x10, 0x10,
0x10, 0x0A, 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,
0x4A, 0x61, 0x6E, 0x2E, 0x20, 0x20, 0x31, 0x20, 0x20, 0x31, 0x39, 0x39, 0x39, 0x20, 0x30, 0x20,
0x30, 0x30, 0x20, 0x41, 0x4D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
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,
0x01, 0x01, 0x19, 0x99, 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,
0x19, 0x99, 0x01, 0x01, 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, 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,
0x5E, 0x68, 0xFF, 0x00, 0x40, 0x64, 0x80, 0x64, 0x00, 0x10, 0xFF, 0x00, 0xD6, 0x35, 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,
0xC2, 0x39, 0xFF, 0x00, 0x40, 0x60, 0x00, 0x62, 0x00, 0x20, 0x00, 0x00, 0x00, 0x60, 0xFF, 0x00,
0x00, 0x00, 0x18, 0x58, 0xFC, 0x00, 0x00, 0x04, 0x06, 0x0C, 0x07, 0x01, 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, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x12, 0x44, 0xFF, 0x00, 0xC0, 0x63, 0x80, 0x64, 0x00, 0x80, 0xFF, 0x00, 0x80, 0x60, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0xE0, 0x58, 0x00,
0x44, 0x48, 0x03, 0x01, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00,
0x48, 0x44, 0xFF, 0x00, 0x40, 0x44, 0xFF, 0x00, 0x40, 0x63, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0xCF, 0x45, 0xFF, 0x00, 0x00, 0x63, 0x40, 0x61, 0x00, 0x60, 0xFF, 0x00, 0x80, 0x60, 0x00, 0x00,
0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x00, 0x02, 0x04, 0xE0, 0xC8, 0x00,
0x20, 0x50, 0x05, 0x02, 0x03, 0x01, 0x80, 0x00, 0x00, 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00,
0x71, 0x46, 0xFF, 0x00, 0x61, 0x46, 0xFF, 0x00, 0x00, 0x62, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0xCF, 0x45, 0xFF, 0x00, 0x00, 0x63, 0x80, 0x64, 0x00, 0x68, 0xFF, 0x00, 0x80, 0x60, 0x00, 0x00,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x00, 0x02, 0x04, 0xE0, 0xC8, 0x00,
0x58, 0x50, 0x05, 0x02, 0x03, 0x01, 0x80, 0x00, 0x00, 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00,
0x71, 0x46, 0xFF, 0x00, 0x61, 0x46, 0xFF, 0x00, 0x00, 0x62, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00,
0xCF, 0x45, 0xFF, 0x00, 0xC0, 0x62, 0xC0, 0x63, 0x00, 0x68, 0xFF, 0x00, 0x80, 0x60, 0x00, 0x00,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x00, 0x01, 0x06, 0xE0, 0x58, 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, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 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, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x0F,
0x00, 0x00, 0x0A, 0x00, 0xCF, 0x09, 0xFF, 0x0F, 0x00, 0x0F, 0xFF, 0x0F, 0x3F, 0x00, 0xFF, 0x0F,
0x55, 0x07, 0xF5, 0x08, 0xF5, 0x08, 0xFF, 0x0F, 0x40, 0x0D, 0x40, 0x0D, 0x40, 0x0D, 0xFF, 0x0F,
0xFF, 0x0F, 0x9F, 0x00, 0x00, 0x06, 0xFF, 0x0F, 0xFF, 0x0F, 0x22, 0x08, 0x00, 0x07, 0xFF, 0x0F,
0x90, 0x0B, 0x80, 0x0A, 0x70, 0x0A, 0xFF, 0x0F, 0x70, 0x0A, 0x60, 0x09, 0x50, 0x09, 0xFF, 0x0F,
0x50, 0x09, 0x40, 0x09, 0x31, 0x08, 0xFF, 0x0F, 0x31, 0x08, 0x22, 0x08, 0x00, 0x07, 0xFF, 0x0F,
0xFF, 0x0F, 0x88, 0x08, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0x88, 0x08, 0x00, 0x00, 0xFF, 0x0F,
0xE2, 0x0F, 0xFB, 0x0F, 0x5F, 0x0F, 0xFF, 0x0F, 0x3F, 0x00, 0xFF, 0x0F, 0x3F, 0x00, 0xFF, 0x0F,
0xFF, 0x0F, 0x88, 0x08, 0x00, 0x00, 0xFF, 0x0F, 0x10, 0x0A, 0xFF, 0x0F, 0x50, 0x0F, 0xFF, 0x0F,
0x00, 0x00, 0x0F, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x06, 0x00, 0x00, 0xFF, 0x0F,
0xFF, 0x0F, 0x9F, 0x00, 0x00, 0x06, 0xFF, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F,
0xCC, 0x0F, 0xCC, 0x0F, 0x77, 0x09, 0xFF, 0x0F, 0xCC, 0x0F, 0x68, 0x06, 0x77, 0x09, 0xFF, 0x0F,
0xCD, 0x0A, 0x68, 0x06, 0x48, 0x02, 0xFF, 0x0F, 0x77, 0x09, 0x68, 0x06, 0x48, 0x02, 0xFF, 0x0F,
0xCC, 0x0F, 0x77, 0x09, 0xC0, 0x0F, 0xFF, 0x0F, 0x6F, 0x00, 0x4F, 0x00, 0xAF, 0x00, 0xFF, 0x0F,
0xF3, 0x0F, 0x4B, 0x06, 0x16, 0x01, 0xFF, 0x0F, 0xF3, 0x0F, 0x50, 0x0E, 0x16, 0x01, 0xFF, 0x0F,
0x4B, 0x06, 0x4B, 0x06, 0x16, 0x01, 0xFF, 0x0F, 0x4B, 0x06, 0x18, 0x03, 0x16, 0x01, 0xFF, 0x0F,
0x4B, 0x06, 0x50, 0x0E, 0x16, 0x01, 0xFF, 0x0F, 0x4B, 0x06, 0x16, 0x01, 0x07, 0x02, 0xFF, 0x0F,
0xF9, 0x0D, 0x8D, 0x04, 0xAA, 0x0C, 0xFF, 0x0F, 0xB0, 0x0B, 0x20, 0x02, 0x40, 0x04, 0xFF, 0x0F,
0xFF, 0x0F, 0x50, 0x05, 0x1F, 0x08, 0xFF, 0x0F, 0x80, 0x08, 0x50, 0x05, 0x81, 0x08, 0xFF, 0x0F,
0xB0, 0x0B, 0x70, 0x07, 0x50, 0x05, 0xFF, 0x0F, 0xFF, 0x01, 0xEB, 0x0F, 0xC0, 0x0F, 0xFF, 0x0F,
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,
0xD5, 0x35, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x64, 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,
0xD6, 0x35, 0xFF, 0x00, 0x40, 0x64, 0x00, 0x00, 0xFF, 0xFF, 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, 0x60, 0x40, 0x60, 0x80, 0x60, 0xC0, 0x60, 0x00, 0x61, 0x40, 0x61, 0x80, 0x61, 0xC0, 0x61,
0x00, 0x62, 0x40, 0x62, 0x80, 0x62, 0xC0, 0x62, 0x00, 0x63, 0x40, 0x63, 0x80, 0x63, 0xC0, 0x63,
0x02, 0x00, 0x02, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x63, 0xA1,
0x4D, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x12, 0x17, 0x10, 0x42, 0x43, 0xE1, 0x1A, 0xBD, 0x7E,
0xFF, 0x06, 0xD8, 0x03, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x88, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, 0x30, 0x00, 0x00, 0x06, 0x10, 0x60, 0x36, 0x08, 0x00,
0x06, 0x16, 0x61, 0x36, 0x08, 0x00, 0x06, 0x16, 0x62, 0x36, 0x08, 0x00, 0x06, 0x16, 0x63, 0x36,
0x08, 0x00, 0x06, 0x16, 0x64, 0x36, 0x08, 0x00, 0x06, 0x16, 0x61, 0x16, 0x08, 0x00, 0x07, 0x16,
0x62, 0x16, 0x08, 0x00, 0x07, 0x16, 0x63, 0x16, 0x08, 0x00, 0x07, 0x16, 0x64, 0x16, 0x08, 0x00,
0x07, 0x16, 0x61, 0x36, 0x08, 0x00, 0x08, 0x16, 0x62, 0x36, 0x08, 0x00, 0x08, 0x16, 0x63, 0x36,
0x08, 0x00, 0x08, 0x16, 0x64, 0x36, 0x08, 0x00, 0x08, 0x16, 0x61, 0x16, 0x08, 0x00, 0x09, 0x16,
0x62, 0x16, 0x08, 0x00, 0x09, 0x16, 0x63, 0x16, 0x08, 0x00, 0x09, 0x16, 0x64, 0x16, 0x08, 0x00,
0x09, 0x16, 0x64, 0x16, 0x08, 0x00, 0x09, 0x16, 0x64, 0x16, 0x08, 0x00, 0x09, 0x16, 0x65, 0x16,
0x68, 0x08, 0x05, 0x16, 0x65, 0x16, 0x08, 0x00, 0x05, 0x16, 0x65, 0x16, 0x08, 0x00, 0x05, 0x16,
0x65, 0x16, 0x08, 0x00, 0x05, 0x16, 0x65, 0x16, 0x08, 0x00, 0x05, 0x16, 0x65, 0x16, 0x08, 0x00,
0x05, 0x16, 0x65, 0x16, 0x08, 0x00, 0x05, 0x16, 0x65, 0x16, 0x08, 0x00, 0x05, 0x16, 0x65, 0x16,
0x08, 0x00, 0x05, 0x16, 0x65, 0x16, 0x08, 0x00, 0x05, 0x16, 0x65, 0x16, 0x08, 0x00, 0x05, 0x16,
0x65, 0x16, 0x08, 0x00, 0x05, 0x16, 0x65, 0x16, 0x08, 0x00, 0x05, 0x16, 0x65, 0x16, 0x08, 0x00,
0x05, 0x16, 0x65, 0x16, 0x08, 0x00, 0x05, 0x16, 0x65, 0x16, 0x08, 0x00, 0x05, 0x16, 0x65, 0x16,
0x08, 0x00, 0x05, 0x16, 0x65, 0x16, 0x08, 0x00, 0x05, 0x16, 0x65, 0x16, 0x08, 0x00, 0x05, 0x16,
0x65, 0x16, 0x08, 0x00, 0x05, 0x16, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00,
0xEF, 0x0B, 0x60, 0x0F, 0x00, 0x01, 0x4D, 0x00, 0xFF, 0x0F, 0x97, 0x08, 0x54, 0x02, 0x4D, 0x00,
0xFF, 0x0F, 0x97, 0x08, 0x54, 0x02, 0x9B, 0x00, 0xD9, 0x0F, 0x64, 0x0B, 0x00, 0x06, 0xA5, 0x00,
0xFD, 0x0F, 0x94, 0x0B, 0x22, 0x06, 0xA5, 0x00, 0xFD, 0x0F, 0x94, 0x0B, 0x22, 0x06, 0xA5, 0x00,
0xFD, 0x0F, 0x94, 0x0B, 0x22, 0x06, 0xA5, 0x00, 0xFD, 0x0F, 0x94, 0x0B, 0x22, 0x06, 0xA5, 0x00,
0xFD, 0x0F, 0x94, 0x0B, 0x22, 0x06, 0xA5, 0x00, 0xFD, 0x0F, 0x94, 0x0B, 0x22, 0x06, 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, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x07,
0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x08, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
0x01, 0x01, 0x89, 0x00, 0x00, 0x80, 0x00, 0xA0, 0x00, 0x00, 0x05, 0x03, 0xF0, 0x20, 0x10, 0x05,
0x0A, 0x00, 0x85, 0x0D, 0xC2, 0x75, 0x00, 0x00, 0x91, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x18, 0x28, 0x00, 0x01, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0xA8, 0x93, 0x2B, 0x00, 0x9E, 0x78, 0x20, 0x00, 0x0A, 0x01, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00,
0x84, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x39, 0x26, 0x00, 0x31, 0x54, 0x45, 0x4D, 0x00, 0xFF,
0x11, 0x00, 0x05, 0x0B, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3B, 0x48, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0A, 0x08, 0x0A, 0x08, 0x12, 0x10, 0x12, 0x1A, 0x18,
0x1A, 0x18, 0x1A, 0x0A, 0x08, 0x0A, 0x01, 0x01, 0x00, 0xFC, 0x27, 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, 0x01, 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, 0x39, 0x49, 0xE6, 0x6B, 0x39, 0x49, 0xE6, 0x6B,
0x21, 0x00, 0x00, 0x98, 0x09, 0x00, 0x0F, 0x00, 0x03, 0x00, 0x12, 0x2F, 0x23, 0x00, 0x00, 0x98,
0x09, 0x00, 0x0D, 0x00, 0x03, 0x00, 0xCC, 0x2E, 0x23, 0x00, 0x39, 0x49, 0xE6, 0x6B, 0x21, 0x00,
0x00, 0x98, 0x09, 0x00, 0x0F, 0x00, 0x03, 0x00, 0x08, 0x2F, 0x23, 0x00, 0x00, 0x98, 0x4C, 0x01,
0x00, 0x00, 0x3A, 0x6F, 0x20, 0x00, 0x0A, 0xE4, 0xD4, 0xE4, 0x22, 0x00, 0x1C, 0x6F, 0x20, 0x83,
0x40, 0x83, 0x40, 0x25, 0x00, 0xA1, 0x02, 0x80, 0x00, 0xFF, 0xA7, 0x83, 0x40, 0x25, 0x00, 0xA1,
0x02, 0x83, 0x40, 0x25, 0x00, 0xA1, 0x02, 0x80, 0x00, 0xFF, 0xAA, 0x22, 0x28, 0x83, 0x40, 0x25,
0x00, 0xA1, 0x02, 0x80, 0x00, 0xFF, 0x3B, 0xEC, 0x2E, 0x00, 0x80, 0x83, 0x40, 0x25, 0x00, 0x83,
0xE5, 0x25, 0xFF, 0x00, 0x12, 0x20, 0xFF, 0x00, 0xB3, 0x1F, 0xFF, 0x00, 0x80, 0x64, 0x00, 0x00,
0x8C, 0x1F, 0xFF, 0x00, 0xC3, 0x23, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00,
0xE5, 0x34, 0xFF, 0x00, 0x40, 0x50, 0x00, 0x60, 0x00, 0x00, 0xE5, 0x25, 0xFF, 0x00, 0x12, 0x20,
0xFF, 0x00, 0xB3, 0x1F, 0xDA, 0x01, 0xE5, 0x25, 0xFF, 0x00, 0x12, 0x20, 0xFF, 0x00, 0xB3, 0x1F,
0xFF, 0x00, 0x80, 0x64, 0x00, 0x00, 0xC5, 0x50, 0xFF, 0x00, 0x58, 0x6E, 0x00, 0x00, 0x40, 0x50,
0x00, 0x00, 0x20, 0x70, 0xFF, 0x00, 0xF9, 0x70, 0xFF, 0x00, 0xDF, 0x23, 0xFF, 0x00, 0x00, 0x00,
0xC3, 0x23, 0xFF, 0x00, 0x10, 0xFB, 0x9D, 0x27, 0xFF, 0x00, 0x00, 0xF8, 0xE4, 0x00, 0x20, 0x00,
0x89, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x66, 0x4D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x20, 0x20,
0x44, 0x75, 0x6D, 0x70, 0xDD, 0x00, 0xBD, 0x01, 0xC1, 0x01, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0x00, 0xDE, 0x0A, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA, 0xAA, 0xBA,
0xAA, 0xAA, 0xAA, 0x75, 0xA5, 0xDE, 0x77, 0xF5, 0xDF, 0xFD, 0xFF, 0xF7, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x6F, 0xFF, 0x00, 0x40, 0x14, 0xFF,
0x00, 0xFF, 0x5A, 0x75, 0xD5, 0x01, 0x77, 0x00, 0x03, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0xFD, 0x77, 0x77,
0xFF, 0xFF, 0x55, 0x99, 0x55, 0x65, 0x55, 0x95, 0x55, 0x65, 0xA5, 0xA5, 0xA5, 0x5A, 0x00, 0x55,
0x00, 0x04, 0x5A, 0x04, 0xA7, 0x95, 0x55, 0x02, 0x5A, 0x04, 0xA5, 0x95, 0x53, 0x02, 0x5A, 0x04,
0xA3, 0x95, 0x51, 0x02, 0x5A, 0x04, 0xA1, 0x95, 0x4F, 0x02, 0x5A, 0x04, 0x9F, 0x95, 0x4C, 0x02,
0x5A, 0x04, 0x9D, 0x95, 0x48, 0x02, 0x5A, 0x04, 0x9C, 0x95, 0x44, 0x02, 0xAF, 0x95, 0x56, 0x02,
0x5A, 0x04, 0xAD, 0x95, 0x56, 0x02, 0x5A, 0x04, 0xAB, 0x95, 0x56, 0x02, 0x5A, 0x04, 0xA9, 0x95,
0x02, 0x5A, 0x04, 0x92, 0x97, 0x54, 0x02, 0x5A, 0x04, 0x8F, 0x97, 0x52, 0x02, 0x5A, 0x04, 0x8C,
0x97, 0x4F, 0x02, 0x5A, 0x04, 0x88, 0x97, 0x4C, 0x02, 0x5A, 0x04, 0x85, 0x97, 0x49, 0x02, 0x5A,
0x04, 0x81, 0x97, 0x45, 0x02, 0x5A, 0x04, 0x33, 0x41, 0x01, 0x90, 0x9E, 0x97, 0x57, 0x02, 0x5A,
0x04, 0x9B, 0x97, 0x57, 0x02, 0x5A, 0x04, 0x98, 0x97, 0x56, 0x02, 0x5A, 0x04, 0x95, 0x97, 0x55,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x55, 0x55, 0x66, 0x55, 0x55, 0x66, 0x66,
0x55, 0x55, 0xA5, 0x66, 0x55, 0x6A, 0xA5, 0x95, 0xA5, 0x6A, 0xA9, 0xAA, 0xA9, 0x6A, 0xA9, 0x6A,
0xAA, 0x5A, 0xA5, 0x66, 0xA5, 0x55, 0xCB, 0x04, 0xC0, 0xB2, 0x23, 0xC0, 0xB2, 0x3E, 0x01, 0x14,
0x3A, 0x1E, 0x12, 0x00, 0x5A, 0x15, 0xC1, 0x05, 0x6D, 0x3F, 0xFF, 0x66, 0x06, 0xCB, 0xCE, 0xFE,
0xC0, 0xB2, 0xCB, 0xCB, 0x05, 0x07, 0xC0, 0x51, 0x21, 0xC9, 0xCC, 0x1C, 0x66, 0x04, 0xF1, 0x06,
0x6D, 0x41, 0xC1, 0x01, 0x6D, 0x21, 0xC1, 0x01, 0x6D, 0x61, 0xC1, 0x03, 0x6D, 0x81, 0xC9, 0xCC,
0x3F, 0xF1, 0xC0, 0x6C, 0x32, 0xF3, 0x03, 0xE8, 0xE0, 0x14, 0x50, 0x00, 0xC1, 0x01, 0x6D, 0x3F,
0x37, 0x6A, 0x06, 0xF1, 0x05, 0x6D, 0x00, 0x00, 0x0E, 0xF1, 0x05, 0x6D, 0x00, 0xFF, 0x0E, 0xAA,
0x03, 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,
0x01, 0x01, 0x00, 0x00, 0xFC, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x00, 0x55, 0x55,
0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xF7, 0xFF, 0xFD, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xDD, 0x0D, 0xBB, 0x0B, 0x99, 0x09,
0x77, 0x07, 0x44, 0x04, 0x33, 0x03, 0x00, 0x00, 0xFF, 0x0F, 0xDD, 0x0D, 0xBB, 0x0B, 0x99, 0x09,
0x77, 0x07, 0x44, 0x04, 0x33, 0x03, 0x00, 0x00, 0xFF, 0x0F, 0xDD, 0x0D, 0xBB, 0x0B, 0x99, 0x09,
0x77, 0x07, 0x44, 0x04, 0x33, 0x03, 0x00, 0x00, 0xFF, 0x0F, 0xDD, 0x0D, 0xBB, 0x0B, 0x99, 0x09,
0x77, 0x07, 0x44, 0x04, 0x33, 0x03, 0x00, 0x00, 0xFF, 0x0F, 0xDD, 0x0D, 0xBB, 0x0B, 0x99, 0x09,
0x77, 0x07, 0x44, 0x04, 0x33, 0x03, 0x00, 0x00, 0xFF, 0x0F, 0xDD, 0x0D, 0xBB, 0x0B, 0x99, 0x09,
0x77, 0x07, 0x44, 0x04, 0x33, 0x03, 0x00, 0x00, 0xFF, 0x0F, 0xDD, 0x0D, 0xBB, 0x0B, 0x99, 0x09,
0x77, 0x07, 0x44, 0x04, 0x33, 0x03, 0x00, 0x00, 0xFF, 0x0F, 0xDD, 0x0D, 0xBB, 0x0B, 0x99, 0x09,
0x77, 0x07, 0x44, 0x04, 0x33, 0x03, 0x00, 0x00, 0x2A, 0x00, 0x55, 0xF3, 0xF1, 0x55, 0x55, 0x00,
0xF0, 0x0E, 0xFF, 0xFF, 0x03, 0x00, 0x66, 0x08, 0xB2, 0xCD, 0x66, 0xEE, 0x82, 0xF0, 0x66, 0x02,
0x21, 0xFF, 0x0E, 0x69, 0x55, 0x69, 0x55, 0x59, 0x95, 0x5A, 0x95, 0x5A, 0xA5, 0x5A, 0xA5, 0x5A,
0xFF, 0x5A, 0x00, 0x00, 0x00, 0x01, 0x22, 0x01, 0x01, 0x00, 0x00, 0x00, 0x22, 0xE8, 0x26, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0x50, 0x4E, 0xA9, 0x55, 0x69, 0x56, 0x69, 0x55, 0x69, 0x56, 0x6A,
0x55, 0x5A, 0xAA, 0x76, 0xAA, 0x57, 0xAA, 0x75, 0xEA, 0x55, 0x6A, 0x77, 0x5A, 0x55, 0x5E, 0x77,
0x57, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x59, 0x55,
0xCF, 0x07, 0x01, 0x01, 0x57, 0x55, 0x5F, 0x55, 0x5F, 0x55, 0xAF, 0x99, 0x7F, 0x55, 0x9A, 0x99,
0x66, 0x56, 0x7F, 0x66, 0xFF, 0x99, 0xFF, 0xA7, 0xFF, 0x9F, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x56, 0x66, 0x75, 0xDD, 0x5D, 0x57, 0x77, 0xFF, 0x5F, 0x77, 0x77,
0xDD, 0x5D, 0x69, 0xA5, 0x56, 0x65, 0x55, 0x59, 0xDD, 0x99, 0x77, 0x76, 0xD5, 0x7D, 0x75, 0x75,
0x55, 0xDD, 0xFF, 0x6B, 0xFF, 0xDD, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x99, 0xD9, 0xAA, 0xDA, 0x99, 0xD9, 0xAA, 0xDA, 0x99, 0xD9, 0xAA, 0xEA, 0x99, 0x69,
0xAA, 0x6A, 0x65, 0x65, 0x95, 0x55, 0xA5, 0x65, 0x95, 0x55, 0xA5, 0x65, 0x95, 0x55, 0xA5, 0x65,
0xDC, 0x02, 0x00, 0x40, 0x40, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x10, 0x03, 0x00, 0x00, 0x00, 0x6A, 0x66, 0x6A, 0x55, 0x5A, 0x66, 0x5A, 0x55, 0x5A, 0x66,
0x5A, 0x55, 0x69, 0x66, 0x5A, 0x55, 0x6A, 0x56, 0x56, 0x55, 0x66, 0x55, 0x56, 0x55, 0x66, 0x55,
0x55, 0x55, 0xA9, 0x56, 0xAA, 0x56, 0xAA, 0x55, 0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x20, 0x00,
0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x20, 0x00,
0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x20, 0x00,
0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x20, 0x00,
0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88, 0x00, 0x20, 0x00,
} ;

577
main.cpp Normal file
View File

@ -0,0 +1,577 @@
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
//
// This is the main program entry point
//
#ifndef TARGET_PSP
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#endif
#include "unzip.h"
#ifndef __GP32__
#include "StdAfx.h"
#endif
#include "main.h"
//#include "msounds.h"
#include "memory.h"
//#include "mainemu.h"
#include "tlcs900h.h"
#include "input.h"
#include "graphics.h"
#include "tlcs900h.h"
#ifndef __GP32__
//#include "timer.h"
#endif
#include "neopopsound.h"
#ifdef DRZ80
#include "DrZ80_support.h"
#else
#if defined(CZ80)
#include "cz80_support.h"
#else
#include "z80.h"
#endif
#endif
#ifdef __GP32__
#include "fileio.h"
#include "gfx.h"
#elif !defined(TARGET_PSP)
SDL_Surface* screen = NULL; // Main program screen
SDL_Surface* actualScreen = NULL; // Main program screen
#endif
extern int finscan;
extern int idioma;
extern int tipo_consola;
BOOL m_bIsActive;
int exitNow=0;
EMUINFO m_emuInfo;
SYSTEMINFO m_sysInfo[NR_OF_SYSTEMS];
FILE *errorLog = NULL;
FILE *outputRam = NULL;
#define numberof(a) (sizeof(a)/sizeof(*(a)))
void mainemuinit()
{
// initialize cpu memory
mem_init();
#ifndef __GP32__
graphics_init(NULL);
#else
graphics_init();
#endif
// initialize the TLCS-900H cpu
tlcs_init();
#if defined(DRZ80) || defined(CZ80)
Z80_Init();
Z80_Reset();
#else
z80Init();
#endif
// if neogeo pocket color rom, act if we are a neogeo pocket color
tlcsMemWriteB(0x6F91,tlcsMemReadB(0x00200023));
if (tipo_consola==1) tlcsMemWriteB(0x6F91,0x00);
// pretend we're running in English mode
//NOTA IDIOMA 00 Ingles - 01 Jap
if (idioma == 0){
tlcsMemWriteB(0x00006F87,0x01);}
if (idioma == 1){
tlcsMemWriteB(0x00006F87,0x00);}
// kludges & fixes
switch (tlcsMemReadW(0x00200020))
{
case 0x0059: // Sonic
case 0x0061: // Metal SLug 2nd
*get_address(0x0020001F) = 0xFF;
break;
}
ngpSoundOff();
//Flavor sound_start();
}
#if !defined(__GP32__) && !defined(TARGET_PSP)
void AfxMessageBox(char *a, int b, int c)
{
dbg_print(a);
}
void AfxMessageBox(char *a, int b)
{
dbg_print(a);
}
void AfxMessageBox(char *a)
{
dbg_print(a);
}
#endif
void SetActive(BOOL bActive)
{
m_bIsActive = bActive;
}
void SetEmu(int machine)
{
m_emuInfo.machine = machine;
m_emuInfo.drv = &m_sysInfo[machine];
}
bool initRom()
{
char *licenseInfo = " BY SNK CORPORATION";
char *ggLicenseInfo = "TMR SEGA";
BOOL romFound = TRUE;
int i, m;
finscan=198;
if (mainrom[0x000020] == 0x65 || mainrom[0x000020] == 0x93)
{
finscan=199;
}
//dbg_print("in openNgp(%s)\n", lpszPathName);
// first stop the current emulation
//dbg_print("openNgp: SetEmu(NONE)\n");
SetEmu(NGPC);
//dbg_print("openNgp: SetActive(FALSE)\n");
SetActive(FALSE);
// check NEOGEO POCKET
// check license info
for (i=0;i<19;i++)
{
if (mainrom[0x000009 + i] != licenseInfo[i])
romFound = FALSE;
}
if (romFound)
{
//dbg_print("openNgp: romFound == TRUE\n");
i = mainrom[0x000023];
if (i == 0x10 || i == 0x00)
{
// initiazlie emulation
if (i == 0x10) {
m = NGPC;
} else {
// fix for missing Mono/Color setting in Cool Coom Jam SAMPLE rom
if (mainrom[0x000020] == 0x34 && mainrom[0x000021] == 0x12)
m = NGPC;
else m = NGP;
}
if (tipo_consola==1) m = NGP;
//dbg_print("openNgp: SetEmu(%d)\n", m);
SetEmu(m);
//dbg_print("openNgp: Calling mainemuinit(%s)\n", lpszPathName);
mainemuinit();
// start running the emulation loop
//dbg_print("openNgp: SetActive(TRUE)\n");
SetActive(TRUE);
// acknowledge opening of the document went fine
//dbg_print("openNgp: returning success\n");
return TRUE;
}
fprintf(stderr, "Not a valid or unsupported rom file.\n");
return FALSE;
}
fprintf(stderr, "Not a valid or unsupported rom file. romFound==FALSE\n");
return FALSE;
}
void initSysInfo()
{
m_bIsActive = FALSE;
m_emuInfo.machine = NGPC;
m_emuInfo.drv = &m_sysInfo[m_emuInfo.machine];
m_emuInfo.romSize = 0;
/* strcpy(m_emuInfo.ProgramFolder, "");
strcpy(m_emuInfo.SavePath, "");
strcpy(m_emuInfo.DebugPath, "");
strcpy(m_emuInfo.RomPath, "");
strcpy(m_emuInfo.OpenFileName, "");
strcpy(m_emuInfo.SaveFileName, "");
strcpy(m_emuInfo.OpenFileName, "");
strcpy(m_emuInfo.DebugPath, "");;
strcpy(m_emuInfo.RomFileName, "");
strcpy(m_emuInfo.SaveFileName, "");
strcpy(m_emuInfo.ScreenPath, "");*/
strcpy(m_emuInfo.RomFileName, "");
#define NO_SOUND_OUTPUT
#ifdef NO_SOUND_OUTPUT
m_emuInfo.sample_rate = 0;
#else
m_emuInfo.sample_rate = 44100;
#endif
m_emuInfo.stereo = 1;
//m_emuInfo.fps = 60;//30;//100; //Flavor, tweak this!
/* m_sysInfo[NONE].hSize = 160;
m_sysInfo[NONE].vSize = 152;
m_sysInfo[NONE].Ticks = 0;
//m_sysInfo[NONE].sound[0].sound_type = 0;*/
m_sysInfo[NGP].hSize = 160;
m_sysInfo[NGP].vSize = 152;
m_sysInfo[NGP].Ticks = 6*1024*1024;
/* m_sysInfo[NGP].sound[0].sound_type = SOUND_SN76496;
m_sysInfo[NGP].sound[0].sound_interface = new_SN76496(1, 3*1024*1024, MIXER(50,MIXER_PAN_CENTER));
m_sysInfo[NGP].sound[1].sound_type = SOUND_DAC;
m_sysInfo[NGP].sound[1].sound_interface = new_DAC(2,MIXER(50,MIXER_PAN_LEFT),MIXER(50,MIXER_PAN_RIGHT));
m_sysInfo[NGP].sound[2].sound_type = 0;
m_sysInfo[NGP].Back0 = TRUE;
m_sysInfo[NGP].Back1 = TRUE;
m_sysInfo[NGP].Sprites = TRUE;*/
m_sysInfo[NGPC].hSize = 160;
m_sysInfo[NGPC].vSize = 152;
m_sysInfo[NGPC].Ticks = 6*1024*1024;
/* m_sysInfo[NGPC].sound[0].sound_type = SOUND_SN76496;
m_sysInfo[NGPC].sound[0].sound_interface = new_SN76496(1, 3*1024*1024, 50);
m_sysInfo[NGPC].sound[1].sound_type = SOUND_DAC;
m_sysInfo[NGPC].sound[1].sound_interface = new_DAC(2,MIXER(50,MIXER_PAN_LEFT),MIXER(50,MIXER_PAN_RIGHT));
m_sysInfo[NGPC].sound[2].sound_type = 0;
m_sysInfo[NGPC].Back0 = TRUE;
m_sysInfo[NGPC].Back1 = TRUE;
m_sysInfo[NGPC].Sprites = TRUE;*/
}
char *getFileNameExtension(char *nom_fichier) {
char *ptrPoint = nom_fichier;
while(*nom_fichier) {
if (*nom_fichier == '.')
ptrPoint = nom_fichier;
nom_fichier++;
}
return ptrPoint;
}
int loadFromZipByName(unsigned char *buffer, char *archive, char *filename, int *filesize)
{
char name[_MAX_PATH];
//unsigned char *buffer;
int i;
const char *recognizedExtensions[] = {
".ngp",
".npc",
".ngc"
};
int zerror = UNZ_OK;
unzFile zhandle;
unz_file_info zinfo;
zhandle = unzOpen(archive);
if(!zhandle) return (0);
/* Seek to first file in archive */
zerror = unzGoToFirstFile(zhandle);
if(zerror != UNZ_OK)
{
unzClose(zhandle);
return (0);
}
//On scanne tous les fichiers de l'archive et ne prend que ceux qui ont une extension valable, sinon on prend le dernier fichier trouvé...
while (zerror == UNZ_OK) {
if (unzGetCurrentFileInfo(zhandle, &zinfo, name, 0xff, NULL, 0, NULL, 0) != UNZ_OK) {
unzClose(zhandle);
return 0;
}
//Vérifions que c'est la bonne extension
char *extension = getFileNameExtension(name);
for (i=0;i<numberof(recognizedExtensions);i++) {
if (!strcmp(extension, recognizedExtensions[i]))
break;
}
if (i < numberof(recognizedExtensions))
break;
zerror = unzGoToNextFile(zhandle);
}
/* Get information about the file */
// unzGetCurrentFileInfo(zhandle, &zinfo, &name[0], 0xff, NULL, 0, NULL, 0);
*filesize = zinfo.uncompressed_size;
/* Error: file size is zero */
if(*filesize <= 0 || *filesize > (4*1024*1024))
{
unzClose(zhandle);
return (0);
}
/* Open current file */
zerror = unzOpenCurrentFile(zhandle);
if(zerror != UNZ_OK)
{
unzClose(zhandle);
return (0);
}
/* Allocate buffer and read in file */
//buffer = malloc(*filesize);
//if(!buffer) return (NULL);
zerror = unzReadCurrentFile(zhandle, buffer, *filesize);
/* Internal error: free buffer and close file */
if(zerror < 0 || zerror != *filesize)
{
//free(buffer);
//buffer = NULL;
unzCloseCurrentFile(zhandle);
unzClose(zhandle);
return (0);
}
/* Close current file and archive file */
unzCloseCurrentFile(zhandle);
unzClose(zhandle);
memcpy(filename, name, _MAX_PATH);
return 1;
}
/*
Verifies if a file is a ZIP archive or not.
Returns: 1= ZIP archive, 0= not a ZIP archive
*/
int check_zip(char *filename)
{
unsigned char buf[2];
FILE *fd = NULL;
fd = fopen(filename, "rb");
if(!fd) return (0);
fread(buf, 2, 1, fd);
fclose(fd);
if(memcmp(buf, "PK", 2) == 0) return (1);
return (0);
}
int strrchr2(const char *src, int c)
{
size_t len;
len=strlen(src);
while(len>0){
len--;
if(*(src+len) == c)
return len;
}
return 0;
}
int handleInputFile(char *romName)
{
FILE *romFile;
int iDepth = 0;
int size;
initSysInfo(); //initialize it all
//if it's a ZIP file, we need to handle that here.
iDepth = strrchr2(romName, '.');
iDepth++;
if( ( strcmp( romName + iDepth, "zip" ) == 0 ) || ( strcmp( romName + iDepth, "ZIP" ) == 0 ))
{
//get ROM from ZIP
if(check_zip(romName))
{
char name[_MAX_PATH];
if(!loadFromZipByName(mainrom, romName, name, &size))
{
fprintf(stderr, "Load failed from %s\n", romName);
return 0;
}
m_emuInfo.romSize = size;
strcpy(m_emuInfo.RomFileName, romName);
}
else
{
fprintf(stderr, "%s not PKZIP file\n", romName);
return 0;
}
}
else
{
//get ROM from binary ROM file
romFile = fopen(romName, "rb");
if(!romFile)
{
fprintf(stderr, "Couldn't open %s file\n", romName);
return 0;
}
m_emuInfo.romSize = fread(mainrom, 1, 4*1024*1024, romFile);
strcpy(m_emuInfo.RomFileName, romName);
}
if(!initRom())
{
fprintf(stderr, "initRom couldn't handle %s file\n", romName);
return 0;
}
setFlashSize(m_emuInfo.romSize);
return 1;
}
#ifndef TARGET_PSP
int main(int argc, char *argv[])
{
char romName[512];
#ifdef TARGET_PSP
SetupCallbacks();
scePowerSetClockFrequency(222, 222, 111);
scePowerSetClockFrequency(266, 266, 133);
scePowerSetClockFrequency(333, 333, 166);
#endif
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_JOYSTICK) < 0)
{
fprintf(stderr, "SDL_Init failed!\n");
#ifdef TARGET_PSP
sceKernelExitGame();
#endif
return -1;
}
// Set up quiting so that it automatically runs on exit.
atexit(SDL_Quit);
PSP_JoystickOpen();
actualScreen = SDL_SetVideoMode (SIZEX, SIZEY, 16, SDL_SWSURFACE);
if (actualScreen == NULL)
{
fprintf(stderr, "SDL_SetVideoMode failed!\n");
#ifdef TARGET_PSP
sceKernelExitGame();
#endif
return -1;
}
else
{
dbg_print("screen params: bpp=%d\n", actualScreen->format->BitsPerPixel);
}
#ifdef ZOOM_SUPPORT
screen = SDL_CreateRGBSurface (actualScreen->flags,
actualScreen->w,
actualScreen->h,
actualScreen->format->BitsPerPixel,
actualScreen->format->Rmask,
actualScreen->format->Gmask,
actualScreen->format->Bmask,
actualScreen->format->Amask);
if (screen == NULL)
{
fprintf(stderr, "SDL_CreateRGBSurface failed!\n");
#ifdef TARGET_PSP
sceKernelExitGame();
#endif
return -1;
}
#else
screen = actualScreen;
#endif
SDL_ShowCursor(0); //disable the cursor
/* Set up the SDL_TTF */
TTF_Init();
atexit(TTF_Quit);
//printTTF("calling LoadRomFromPSP", 10, TEXT_HEIGHT*1, white, 1, actualScreen, 1);
sound_system_init();
while(!exitNow)
{
#ifdef TARGET_WIN
strncpy(romName, argv[1], 500);
dbg_print("Starting emulation on file \"%s\"\n");
#endif
if(LoadRomFromPSP(romName, actualScreen)<=0)
{
break;
}
SDL_FillRect(actualScreen, NULL, SDL_MapRGB(screen->format,0,0,0));//fill black
SDL_Flip(actualScreen);
//printTTF(romName, 20, TEXT_HEIGHT*16, white, 1, actualScreen, 1);
system_sound_chipreset(); //Resets chips
handleInputFile(romName);
InitInput(NULL);
dbg_print("Running NGPC Emulation\n");
SDL_PauseAudio(0); //run audio
#ifdef TARGET_PSP
switch(options[PSP_MHZ_OPTION])
{
case PSP_MHZ_222:
scePowerSetClockFrequency(222, 222, 111);
break;
case PSP_MHZ_266:
scePowerSetClockFrequency(266, 266, 133);
break;
default:
case PSP_MHZ_333:
scePowerSetClockFrequency(333, 333, 166);
break;
}
#endif
ngpc_run();
#ifdef TARGET_PSP
scePowerSetClockFrequency(333, 333, 166);
#endif
SDL_PauseAudio(1); //pause audio
flashShutdown();
}
//printTTF("EXITING", 10, TEXT_HEIGHT*10, white, 1);
#ifdef TARGET_PSP
sceKernelExitGame(); //Exit the program when it is done.
#endif
return 0;
}
#endif

89
main.h Normal file
View File

@ -0,0 +1,89 @@
#ifndef MAIN_H
#define MAIN_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <ctype.h>
#include <math.h>
#if !defined(__GP32__) && !defined(TARGET_PSP)
#include "GP2X.h"
extern SDL_Surface* screen;
extern SDL_Surface* actualScreen;
#endif
struct SYSTEMINFO {
int hSize;
int vSize;
int Ticks;
int InputKeys[12];
//MachineSound sound[4];
// Dynamic System Info
BOOL Back0;
BOOL Back1;
BOOL Sprites;
};
struct EMUINFO {
/* char ProgramFolder[_MAX_PATH]; // place holders for filenames
char SavePath[_MAX_PATH];
char DebugPath[_MAX_PATH];
char RomPath[_MAX_PATH];
char ScreenPath[_MAX_PATH];
char OpenFileName[_MAX_PATH]; // place holders for filenames
char SaveFileName[_MAX_PATH];*/
char RomFileName[_MAX_PATH];
int machine; // what kind of machine should we emulate
int romSize; // what is the size of the currently loaded file
int sample_rate; // what is the current sample rate
int stereo; // play in stereo?
//unsigned int fps;
int samples;
SYSTEMINFO *drv;
};
#define KEY_UP 0
#define KEY_DOWN 1
#define KEY_LEFT 2
#define KEY_RIGHT 3
#define KEY_START 4
#define KEY_BUTTON_A 5
#define KEY_BUTTON_B 6
#define KEY_SELECT 7
#define KEY_UP_2 8
#define KEY_DOWN_2 9
#define KEY_LEFT_2 10
#define KEY_RIGHT_2 11
// Possible Neogeo Pocket versions
#define NGP 0x00
#define NGPC 0x01
#define NR_OF_SYSTEMS 2
extern BOOL m_bIsActive;
extern EMUINFO m_emuInfo;
extern SYSTEMINFO m_sysInfo[NR_OF_SYSTEMS];
extern int romSize;
int handleInputFile(char *romName);
void mainemuinit();
#ifdef __GP32__
#define HOST_FPS 60 //100 was what it was, originally
#else
#ifdef TARGET_PSP //to call these FPS is a bit of a misnomer
#define HOST_FPS 60 //the number of frames we want to draw to the host's screen every second
#else
#define HOST_FPS 60 //100 was what it was, originally
#endif
#endif
#endif

526
memory.cpp Normal file
View File

@ -0,0 +1,526 @@
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
// memory.cpp: implementation of the memory class.
//
// Quick & dirty implementation; no rom protection etc.
//
// TODO:
//
//////////////////////////////////////////////////////////////////////
#ifndef __GP32__
#include "StdAfx.h"
#endif
#include "main.h"
#include "memory.h"
#include "input.h" // for Gameboy Input
#include "graphics.h" // for i/o ports of the game gear
//#include "mainemu.h"
#include "sound.h"
//#include "z80.h"
#include "tlcs900h.h"
#include "koyote_bin.h"
#ifdef DRZ80
#include "DrZ80_support.h"
/*#else
#if defined(CZ80)
#include "cz80_support.h"
#else
#include "z80.h"*/
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
// define work memory for neogeo pocket color
//
// internal cpu ram and internal I/O register (2KB + 160 bytes)
//unsigned char cpuram[0x08a0];
// regular work ram (32 kbytes?)
// on the gameboy maximum of 128kbyte of RAM is possible, plus some internal ram (64KB)
unsigned char __attribute__ ((__aligned__(4))) mainram[(64+32+128)*1024];
// rom area for roms (4 Megabyte)
unsigned char __attribute__ ((__aligned__(4))) mainrom[4*1024*1024];
// cpu internal ROM including vector table starting at 0xff0000
unsigned char __attribute__ ((__aligned__(4))) cpurom[256*1024];//prob only needs 0x10000
//
unsigned char __attribute__ ((__aligned__(4))) *cpuram;
//
// preliminary address map:
//
// 0x00000000 - 0x000000ff : cpuram
// 0x00004000 - 0x0000ffff : ram
// 0x00200000 - 0x003fffff : rom (lower 16Mbit)
// 0x00800000 - 0x009fffff : rom (higher 16Mbit)
// 0x00fffe00 - 0x00ffffff : other ram/rom
//
unsigned char realBIOSloaded = 0;
///////////////////////////////////////////////////////////////////
//
//// z80 memory instructions
//
///////////////////////////////////////////////////////////////////
// function place holders
unsigned char (*z80MemReadB)(unsigned short addr);
unsigned short (*z80MemReadW)(unsigned short addr);
void (*z80MemWriteB)(unsigned short addr, unsigned char data);
void (*z80MemWriteW)(unsigned short addr, unsigned short data);
void (*z80PortWriteB)(unsigned char port, unsigned char data);
unsigned char (*z80PortReadB)(unsigned char port);
////////////////////////////////////////////////////////////////////////////////////
///
/// Neogeo Pocket z80 functions
///
////////////////////////////////////////////////////////////////////////////////////
unsigned char z80ngpMemReadB(unsigned short addr) {
unsigned char temp;
if (addr < 0x4000) {
return mainram[0x3000 + addr];
}
switch(addr) {
case 0x4000: // sound chip read
break;
case 0x4001:
break;
case 0x8000:
temp= cpuram[0xBC];
return temp;
case 0xC000:
break;
}
return 0x00;
}
unsigned short z80ngpMemReadW(unsigned short addr)
{
return (z80ngpMemReadB(addr+1) << 8) | z80ngpMemReadB(addr);
}
void z80ngpMemWriteB(unsigned short addr, unsigned char data) {
if (addr < 0x4000) {
mainram[0x3000 + addr] = data; return;
}
switch (addr)
{
case 0x4000:
Write_SoundChipNoise(data);//Flavor SN76496Write(0, data);
return;
case 0x4001:
Write_SoundChipTone(data);//Flavor SN76496Write(0, data);
return;
case 0x8000:
cpuram[0xBC] = data;
return;
case 0xC000:
tlcs_interrupt_wrapper(0x03);
return;
}
}
void z80ngpMemWriteW(unsigned short addr, unsigned short data) {
if (addr < 0x4000) {
mainram[0x3000 + addr] = data&0xFF;
mainram[0x3000 + addr+1] = data>>8;
return;
}
switch (addr)
{
case 0x4000:
Write_SoundChipNoise(data&0xFF);//Flavor SN76496Write(0, data);
Write_SoundChipNoise(data>>8);//Flavor SN76496Write(0, data);
return;
case 0x4001:
Write_SoundChipTone(data&0xFF);//Flavor SN76496Write(0, data);
Write_SoundChipTone(data>>8);//Flavor SN76496Write(0, data);
return;
case 0x8000:
cpuram[0xBC] = data&0xFF;
cpuram[0xBC] = data>>8;
return;
case 0xC000:
tlcs_interrupt_wrapper(0x03);
tlcs_interrupt_wrapper(0x03);
return;
}
}
void z80ngpPortWriteB(unsigned char port, unsigned char data) {
// acknowledge interrupt, any port works
}
unsigned char z80ngpPortReadB(unsigned char port) {
return 0xFF;
}
#if defined(DRZ80) || defined(CZ80)
void DrZ80ngpMemWriteB(unsigned char data, unsigned short addr)
{
if (addr < 0x4000) {
mainram[0x3000 + addr] = data; return;
}
switch (addr) {
case 0x4000:
Write_SoundChipNoise(data);//Flavor SN76496Write(0, data);
return;
case 0x4001:
Write_SoundChipTone(data);//Flavor SN76496Write(0, data);
return;
case 0x8000:
cpuram[0xBC] = data;
return;
case 0xC000:
tlcs_interrupt_wrapper(0x03);
return;
}
}
void DrZ80ngpMemWriteW(unsigned short data, unsigned short addr)
{
if (addr < 0x4000) {
mainram[0x3000 + addr] = data&0xFF;
mainram[0x3000 + addr+1] = data>>8;
return;
}
switch (addr)
{
case 0x4000:
Write_SoundChipNoise(data&0xFF);//Flavor SN76496Write(0, data);
Write_SoundChipNoise(data>>8);//Flavor SN76496Write(0, data);
return;
case 0x4001:
Write_SoundChipTone(data&0xFF);//Flavor SN76496Write(0, data);
Write_SoundChipTone(data>>8);//Flavor SN76496Write(0, data);
return;
case 0x8000:
cpuram[0xBC] = data&0xFF;
cpuram[0xBC] = data>>8;
return;
case 0xC000:
tlcs_interrupt_wrapper(0x03);
tlcs_interrupt_wrapper(0x03);
return;
}
}
void DrZ80ngpPortWriteB(unsigned short port, unsigned char data)
{
// acknowledge interrupt, any port works
}
unsigned char DrZ80ngpPortReadB(unsigned short port)
{
return 0xFF;
}
#endif
/////////////////////////////////////////////////////////////////////////////////////
//// General Functions ///
/////////////////////////////////////////////////////////////////////////////////////
const unsigned char ngpcpuram[256] = {
// 0x00
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0xFF, 0xFF,
// 0x10
0x34, 0x3C, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x3F, 0xFF, 0x2D, 0x01, 0xFF, 0xFF, 0x03, 0xB2,
// 0x20
0x80, 0x00, 0x01, 0x90, 0x03, 0xB0, 0x90, 0x62, 0x05, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x4C, 0x4C,
// 0x30
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x20, 0xFF, 0x80, 0x7F,
// 0x40
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x50
0x00, 0x20, 0x69, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
// 0x60
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x17, 0x03, 0x03, 0x02, 0x00, 0x00, 0x00,
// 0x70 (0x70-0x7A: interrupt level settings)
0x02, 0x32, 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
};
const unsigned char ngpInterruptCode[] = {
0x07, // RETI
0xD1, 0xBA, 0x6F, 0x04, // PUSHW (6FBA) FFF801 SWI3
0xD1, 0xB8, 0x6F, 0x04, // PUSHW (6FB8)
0x0E, // RET
0xD1, 0xBE, 0x6F, 0x04, // PUSHW (6FBE) FFF80A SWI4
0xD1, 0xBC, 0x6F, 0x04, // PUSHW (6FBC)
0x0E, // RET
0xD1, 0xC2, 0x6F, 0x04, // PUSHW (6FC2) FFF813 SWI5
0xD1, 0xC0, 0x6F, 0x04, // PUSHW (6FC0)
0x0E, // RET
0xD1, 0xC6, 0x6F, 0x04, // PUSHW (6FC6) FFF81C SWI6
0xD1, 0xC4, 0x6F, 0x04, // PUSHW (6FC4)
0x0E, // RET
0xD1, 0xCA, 0x6F, 0x04, // PUSHW (6FCA) FFF825 RTC Alarm
0xD1, 0xC8, 0x6F, 0x04, // PUSHW (6FC8)
0x0E, // RET
0xD1, 0xCE, 0x6F, 0x04, // PUSHW (6FCE) FFF82E VBlank
0xD1, 0xCC, 0x6F, 0x04, // PUSHW (6FCC)
0x0E, // RET
0xD1, 0xD2, 0x6F, 0x04, // PUSHW (6FD2) FFF837 interrupt from z80
0xD1, 0xD0, 0x6F, 0x04, // PUSHW (6FD0)
0x0E, // RET
0xD1, 0xD6, 0x6F, 0x04, // PUSHW (6FD6) FFF840 INTT0
0xD1, 0xD4, 0x6F, 0x04, // PUSHW (6FD4)
0x0E, // RET
0xD1, 0xDA, 0x6F, 0x04, // PUSHW (6FDA) FFF849 INTT1
0xD1, 0xD8, 0x6F, 0x04, // PUSHW (6FD8)
0x0E, // RET
0xD1, 0xDE, 0x6F, 0x04, // PUSHW (6FDE) FFF852 INTT2
0xD1, 0xDC, 0x6F, 0x04, // PUSHW (6FDC)
0x0E, // RET
0xD1, 0xE2, 0x6F, 0x04, // PUSHW (6FE2) FFF85B INTT3 (interrupt to z80)
0xD1, 0xE0, 0x6F, 0x04, // PUSHW (6FE0)
0x0E, // RET
0xD1, 0xE6, 0x6F, 0x04, // PUSHW (6FE6) FFF864 Serial Receive
0xD1, 0xE4, 0x6F, 0x04, // PUSHW (6FE4)
0x0E, // RET
0xD1, 0xEA, 0x6F, 0x04, // PUSHW (6FEA) FFF86D Serial Communication
0xD1, 0xE8, 0x6F, 0x04, // PUSHW (6FE8)
0x0E, // RET
0xD1, 0xEE, 0x6F, 0x04, // PUSHW (6FEE) FFF876 Reserved
0xD1, 0xEC, 0x6F, 0x04, // PUSHW (6FEC)
0x0E, // RET
0xD1, 0xF2, 0x6F, 0x04, // PUSHW (6FF2) FFF87F End DMA Channel 0
0xD1, 0xF0, 0x6F, 0x04, // PUSHW (6FF0)
0x0E, // RET
0xD1, 0xF6, 0x6F, 0x04, // PUSHW (6FF6) FFF888 End DMA Channel 1
0xD1, 0xF4, 0x6F, 0x04, // PUSHW (6FF4)
0x0E, // RET
0xD1, 0xFA, 0x6F, 0x04, // PUSHW (6FFA) FFF891 End DMA Channel 2
0xD1, 0xF8, 0x6F, 0x04, // PUSHW (6FF8)
0x0E, // RET
0xD1, 0xFE, 0x6F, 0x04, // PUSHW (6FFE) FFF89A End DMA Channel 3
0xD1, 0xFC, 0x6F, 0x04, // PUSHW (6FFC)
0x0E, // RET
};
const unsigned long ngpVectors[0x21] = {
0x00FFF800, 0x00FFF000, 0x00FFF800, 0x00FFF801, // 00, 04, 08, 0C
0x00FFF80A, 0x00FFF813, 0x00FFF81C, 0x00FFF800, // 10, 14, 18, 1C
0x00FFF800, 0x00FFF800, 0x00FFF825, 0x00FFF82E, // 20, 24, 28, 2C
0x00FFF837, 0x00FFF800, 0x00FFF800, 0x00FFF800, // 30, 34, 38, 3C
0x00FFF840, 0x00FFF849, 0x00FFF852, 0x00FFF85B, // 40, 44, 48, 4C
0x00FFF800, 0x00FFF800, 0x00FFF800, 0x00FFF800, // 50, 54, 58, 5C
0x00FFF864, 0x00FFF86D, 0x00FFF800, 0x00FFF800, // 60, 64, 68, 6C
0x00FFF800, 0x00FFF87F, 0x00FFF888, 0x00FFF891, // 70, 74, 78, 7C
0x00FFF89A // 80
};
//return 0 on fail
unsigned char loadBIOS()
{
FILE *biosFile;
int bytesRead;
biosFile = fopen("NPBIOS.BIN", "rb");
if(!biosFile)
return 0;
bytesRead = fread(cpurom, 1, 0x10000, biosFile);
fclose(biosFile);
if(bytesRead != 0x10000)
{
fprintf(stderr, "loadBIOS: Bad BIOS file %s\n", "NPBIOS.BIN");
return 0;
}
return 1;
}
void mem_init()
{
int x;
unsigned int i;
cpuram = mainram;
memset(&mainram,0,sizeof(mainram));
switch(m_emuInfo.machine) {
case NGP:
case NGPC:
cpuram = &mainram[128*1024];
if(!loadBIOS())
{
realBIOSloaded = 0;
memset(&cpurom,0,sizeof(cpurom));
//in theory, if we've loaded the BIOS, we shouldn't need much of this, but good luck with that.
// setup fake jump table for the additional bios calls
for (i=0; i<0x40; i++)
{
// using the 1A (reg) dummy instruction to emulate the bios
cpurom[0xe000 + 0x40 * i] = 0xc8;
cpurom[0xe001 + 0x40 * i] = 0x1a;
cpurom[0xe002 + 0x40 * i] = i;
cpurom[0xe003 + 0x40 * i] = 0x0e;
*((unsigned long *)(&cpurom[0xfe00 + 4*i])) = (unsigned long)0x00ffe000 + 0x40 * i;
}
// setup SWI 1 code & vector
x = 0xf000;
cpurom[x] = 0x17; x++; cpurom[x] = 0x03; x++; // ldf 3
cpurom[x] = 0x3C; x++; // push XIX
cpurom[x] = 0xC8; x++; cpurom[x] = 0xCC; x++; // and w,1F
cpurom[x] = 0x1F; x++;
cpurom[x] = 0xC8; x++; cpurom[x] = 0x80; x++; // add w,w
cpurom[x] = 0xC8; x++; cpurom[x] = 0x80; x++; // add w,w
cpurom[x] = 0x44; x++; cpurom[x] = 0x00; x++; // ld XIX,0x00FFFE00
cpurom[x] = 0xFE; x++; cpurom[x] = 0xFF; x++; //
cpurom[x] = 0x00; x++; //
cpurom[x] = 0xE3; x++; cpurom[x] = 0x03; x++; // ld XIX,(XIX+W)
cpurom[x] = 0xF0; x++; cpurom[x] = 0xE1; x++; //
cpurom[x] = 0x24; x++; //
cpurom[x] = 0xB4; x++; cpurom[x] = 0xE8; x++; // call XIX
cpurom[x] = 0x5C; x++; // pop XIX
cpurom[x] = 0x07; x++; // reti
*((unsigned long *)(&cpurom[0xff04])) = (unsigned long)0x00fff000;
// setup interrupt code
for(i=0; i<sizeof(ngpInterruptCode); i++) {
cpurom[0xf800+i] = ngpInterruptCode[i];
}
// setup interrupt vectors
for(i=0; i<sizeof(ngpVectors)/4; i++) {
*((unsigned long *)(&cpurom[0xff00+4*i])) = ngpVectors[i];
}
// setup the additional CPU ram
// interrupt priorities, timer settings, transfer settings, etc
for(i=0; i<sizeof(ngpcpuram); i++)
{
cpuram[i] = ngpcpuram[i];
}
//koyote.bin handling
memcpy(mainram,koyote_bin,KOYOTE_BIN_SIZE/*12*1024*/);
// setup interrupt vectors in RAM
for(i=0; i<18; i++) {
*((unsigned long *)(&mainram[0x2FB8+4*i])) = (unsigned long)0x00FFF800;
}
mainram[0x6F80-0x4000] = 0xFF; //Lots of battery power!
mainram[0x6F81-0x4000] = 0x03;
mainram[0x6F95-0x4000] = 0x10;
mainram[0x6F91-0x4000] = 0x10; // Colour bios
mainram[0x6F84-0x4000] = 0x40; // "Power On" startup
mainram[0x6F85-0x4000] = 0x00; // No shutdown request
mainram[0x6F86-0x4000] = 0x00; // No user answer (?)
mainram[0x6F87-0x4000] = 0x01; //English
}
else
{
//this branch doesn't seem to work for some games (Puzzle Bobble)
realBIOSloaded = 1;
printf("BIOS file loaded. This path is fairly untested!\n");
cpurom[0x3202]=0xf4;//from Koyote
cpurom[0x3203]=0x6b;//from Koyote
//koyote.bin handling
memcpy(mainram,koyote_bin,KOYOTE_BIN_SIZE/*12*1024*/);
/* FILE *fp=fopen("koyote.bin","rb");
if (fp!=NULL)
{
fread(mainram,1,12*1024,fp);
fclose(fp);
}
else
{
// setup interrupt vectors in RAM
for(i=0; i<18; i++) {
*((unsigned long *)(&mainram[0x2FB8+4*i])) = (unsigned long)0x00FFF800;
}
}*/
// setup the additional CPU ram
// interrupt priorities, timer settings, transfer settings, etc
for(i=0; i<sizeof(ngpcpuram); i++)
{
cpuram[i] = ngpcpuram[i];
}
//following from Koyote
cpuram[0x006F] = 0x4E; //Watchdog timer
cpuram[0x00B8] = 0xAA; //No z80 at boot
cpuram[0x00B9] = 0xAA;
mainram[0x6F80-0x4000] = 0xFF; //Lots of battery power!
mainram[0x6F81-0x4000] = 0x03;
mainram[0x6F95-0x4000] = 0x10;
mainram[0x6F91-0x4000] = 0x10; // Colour bios
mainram[0x6F84-0x4000] = 0x40; // "Power On" startup
mainram[0x6F85-0x4000] = 0x00; // No shutdown request
mainram[0x6F86-0x4000] = 0x00; // No user answer (?)
mainram[0x6F87-0x4000] = 0x01; //English
}
mainram[0x4000] = 0xC0; // Enable generation of VBlanks by default
mainram[0x4004] = 0xFF; mainram[0x4005] = 0xFF;
mainram[0x4006] = 0xC6;
for(i=0; i<5; i++) {
mainram[0x4101+4*i] = 0x07; mainram[0x4102+4*i] = 0x07; mainram[0x4103+4*i] = 0x07;
}
mainram[0x4118] = 0x07;
mainram[0x43E0] = mainram[0x43F0] = 0xFF; mainram[0x43E1] = mainram[0x43F1] = 0x0F;
mainram[0x43E2] = mainram[0x43F2] = 0xDD; mainram[0x43E3] = mainram[0x43F3] = 0x0D;
mainram[0x43E4] = mainram[0x43F4] = 0xBB; mainram[0x43E5] = mainram[0x43F5] = 0x0B;
mainram[0x43E6] = mainram[0x43F6] = 0x99; mainram[0x43E7] = mainram[0x43F7] = 0x09;
mainram[0x43E8] = mainram[0x43F8] = 0x77; mainram[0x43E9] = mainram[0x43F9] = 0x07;
mainram[0x43EA] = mainram[0x43FA] = 0x44; mainram[0x43EB] = mainram[0x43FB] = 0x04;
mainram[0x43EC] = mainram[0x43FC] = 0x33; mainram[0x43ED] = mainram[0x43FD] = 0x03;
mainram[0x43EE] = mainram[0x43FE] = 0x00; mainram[0x43EF] = mainram[0x43FF] = 0x00;
// Setup z80 functions
z80MemReadB = z80ngpMemReadB;
z80MemReadW = z80ngpMemReadW;
z80MemWriteB = z80ngpMemWriteB;
z80MemWriteW = z80ngpMemWriteW;
z80PortWriteB = z80ngpPortWriteB;
z80PortReadB = z80ngpPortReadB;
break;
}
}
void mem_dump_ram(FILE *output)
{
fwrite(mainram,1,sizeof(mainram),output);
}

463
memory.h Normal file
View File

@ -0,0 +1,463 @@
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
#ifndef _MEMORYH_
#define _MEMORYH_
#ifndef __GP32__
#include "StdAfx.h"
#endif
#include "neopopsound.h"
#include "sound.h"
#include "input.h"
#include "graphics.h"
#include "main.h"
#include "flash.h"
#ifdef DRZ80
#include "DrZ80_support.h"
#else
#ifdef CZ80
#include "cz80_support.h"
#else
#include "z80.h"
#endif
#endif
extern unsigned char mainram[]; // All RAM areas
extern unsigned char mainrom[]; // ROM image area
extern unsigned char cpurom[]; // Bios ROM image area
//extern unsigned long cartAddrMask; // Mask for reading/writing mainrom
/// tlcs 900h memory
//extern unsigned char cpuram[]; // 900h cpu core needs this..
extern unsigned char *cpuram;
unsigned char tlcsMemReadB(unsigned long addr);
unsigned short tlcsMemReadW(unsigned long addr);
unsigned long tlcsMemReadL(unsigned long addr);
void tlcsMemWriteB(unsigned long addr, unsigned char data);
void tlcsMemWriteW(unsigned long addr, unsigned short data);
void tlcsMemWriteL(unsigned long addr, unsigned long data);
void mem_init();
void mem_dump_ram(FILE *output);
//unsigned char *get_address(unsigned long addr);
//unsigned char *get_addressW(unsigned long addr);
/// gameboy memory
extern unsigned char (*gbMemReadB)(unsigned short addr);
extern void (*gbMemWriteB)(unsigned short addr, unsigned char data);
unsigned short gbMemReadW(unsigned short addr);
void gbMemWriteW(unsigned short addr, unsigned short data);
// z80 memory functions
extern unsigned char (*z80MemReadB)(unsigned short addr);
extern unsigned short (*z80MemReadW)(unsigned short addr);
extern void (*z80MemWriteB)(unsigned short addr, unsigned char data);
extern void (*z80MemWriteW)(unsigned short addr, unsigned short data);
extern void (*z80PortWriteB)(unsigned char port, unsigned char data);
extern unsigned char (*z80PortReadB)(unsigned char port);
#if defined(DRZ80) || defined(CZ80)
unsigned char z80ngpMemReadB(unsigned short addr);
unsigned short z80ngpMemReadW(unsigned short addr);
void DrZ80ngpMemWriteB(unsigned char data, unsigned short addr);
void DrZ80ngpMemWriteW(unsigned short data, unsigned short addr);
void DrZ80ngpPortWriteB(unsigned short port, unsigned char data);
unsigned char DrZ80ngpPortReadB(unsigned short port);
#endif
// used internally by z80 emulation for emulation of the memory
// map of the Game Gear
extern unsigned char *ggVRAM;
extern unsigned char *ggCRAM;
//
//
unsigned char z80ggMemReadB(unsigned short addr);
unsigned short z80ggMemReadW(unsigned short addr);
void z80ggMemWriteB(unsigned short addr, unsigned char data);
void z80ggMemWriteW(unsigned short addr, unsigned short data);
void z80ggPortWriteB(unsigned char port, unsigned char data);
unsigned char z80ggPortReadB(unsigned char port);
// definitions for wdc6502 emulation
extern unsigned char (*w65MemReadB)(unsigned short addr);
//extern unsigned short (*w65MemReadW)(unsigned short addr);
unsigned short w65MemReadW(unsigned short addr);
extern void (*w65MemWriteB)(unsigned short addr, unsigned char data);
//extern void (*w65MemWriteW)(unsigned short addr, unsigned short data);
void w65MemWriteW(unsigned short addr, unsigned short data);
extern unsigned char *w65GetAddress(unsigned short addr);
//
// Supervision specific
//
extern unsigned char *svVRAM;
//
// HuC specific defines & externs
//
extern unsigned char hucMMR[8];
//
// i8086 functions
//
extern unsigned char *x86Ports;
unsigned char x86MemReadB(unsigned int addr);
void x86MemWriteB(unsigned int addr, unsigned char data);
unsigned short x86MemReadW(unsigned int addr);
void x86MemWriteW(unsigned int addr, unsigned short data);
unsigned char x86PortReadB(unsigned short port);
void x86PortWriteB(unsigned short port, unsigned char data);
unsigned short x86PortReadW(unsigned short port);
void x86PortWriteW(unsigned short port, unsigned short data);
// used for Wonderswan graphics emulation
extern unsigned char *wsTileMap0;
extern unsigned char *wsTileMap1;
extern unsigned char *wsPatterns;
extern unsigned char *wsSpriteTable;
//
// i8048 functions
//
extern unsigned char *advBios;
extern unsigned char *advVidRAM;
unsigned char i8048ROMReadB(unsigned int addr);
unsigned char i8048ExtReadB(unsigned int addr);
void i8048ExtWriteB(unsigned int addr, unsigned char data);
unsigned char i8048PortReadB(unsigned char port);
void i8048PortWriteB(unsigned char port, unsigned char data);
void i8048SetT1();
unsigned char i8048GetT1();
//
// sm85xx memory functions
//
extern unsigned char (*sm85MemReadB)(unsigned short addr);
extern void (*sm85MemWriteB)(unsigned short addr, unsigned char data);
extern unsigned char realBIOSloaded;
inline unsigned char *get_address(unsigned long addr)
{
addr&= 0x00FFFFFF;
if (addr<0x00200000)
{
if (addr<0x000008a0)
{
//if(((unsigned long)&cpuram[addr] >> 24) == 0xFF)
// dbg_print("1) addr=0x%X returning=0x%X\n", addr, &cpuram[addr]);
return &cpuram[addr];
}
if (addr>0x00003fff && addr<0x00018000)
{
//if((unsigned long)&mainram[addr-0x00004000] >> 24 == 0xFF)
// dbg_print("2) addr=0x%X returning=0x%X\n", addr, &mainram[addr-0x00004000]);
switch (addr) //Thanks Koyote
{
case 0x6F80:
mainram[addr-0x00004000] = 0xFF;
break;
case 0x6F80+1:
mainram[addr-0x00004000] = 0x03;
break;
case 0x6F85:
mainram[addr-0x00004000] = 0x00;
break;
case 0x6F82:
mainram[addr-0x00004000] = ngpInputState;
break;
case 0x6DA2:
mainram[addr-0x00004000] = 0x80;
break;
}
return &mainram[addr-0x00004000];
}
}
else
{
if (addr<0x00400000)
{
return &mainrom[(addr-0x00200000)/*&cartAddrMask*/];
}
if(addr<0x00800000) //Flavor added
{
return 0;
}
if (addr<0x00A00000)
{
return &mainrom[(addr-(0x00800000-0x00200000))/*&cartAddrMask*/];
}
if(addr<0x00FF0000) //Flavor added
{
return 0;
}
//if((unsigned long)&cpurom[addr-0x00ff0000] >> 24 == 0xFF)
// dbg_print("5) addr=0x%X returning=0x%X\n", addr, &cpurom[addr-0x00ff0000]);
return &cpurom[addr-0x00ff0000];
}
//dbg_print("6) addr=0x%X returning=0\n", addr);
return 0; //Flavor ERROR
}
/*inline unsigned char *get_addressW(unsigned long addr)
{
addr&= 0x00FFFFFF;
if (addr<0x00200000)
{
if (addr<0x000008a0)
{
return &cpuram[addr];
}
if (addr>0x00003fff && addr<0x00018000)
return &mainram[addr-0x00004000];
return NULL;
}
else
{
return NULL;
}
return NULL; //Flavor ERROR
}*/
// read a byte from a memory address (addr)
inline unsigned char tlcsMemReadB(unsigned long addr)
{
addr&= 0x00FFFFFF;
if(currentCommand == COMMAND_INFO_READ)
return flashReadInfo(addr);
if (addr < 0x00200000) {
if (addr < 0x000008A0) {
if(addr == 0xBC)
{
ngpSoundExecute();
}
return cpuram[addr];
}
else if (addr > 0x00003FFF && addr < 0x00018000)
{
switch (addr) //Thanks Koyote
{
case 0x6DA2:
return 0x80;
break;
case 0x6F80:
return 0xFF;
break;
case 0x6F80+1:
return 0x03;
break;
case 0x6F85:
return 0x00;
break;
case 0x6F82:
return ngpInputState;
break;
default:
return mainram[addr-0x00004000];
}
return mainram[addr-0x00004000];
}
}
else
{
if (addr<0x00400000)
return mainrom[(addr-0x00200000)/*&cartAddrMask*/];
if (addr<0x00800000)
return 0xFF;
if (addr<0x00a00000)
return mainrom[(addr-(0x00800000-0x00200000))/*&cartAddrMask*/];
if (addr<0x00ff0000)
return 0xFF;
return cpurom[addr-0x00ff0000];
}
return 0xFF;
}
// read a word from a memory address (addr)
inline unsigned short tlcsMemReadW(unsigned long addr)
{
#ifdef TARGET_GP2X
register unsigned short i asm("r0");
register byte *gA asm("r1");
gA = get_address(addr);
if(gA == 0)
return 0;
asm volatile(
"ldrb %0, [%1]\n\t"
"ldrb r2, [%1, #1]\n\t"
"orr %0, %0, r2, asl #8"
: "=r" (i)
: "r" (gA)
: "r2");
return i;
#else
/* unsigned short i;
byte *gA = get_address(addr);
if(gA == 0)
return 0;
i = *(gA++);
i |= (*gA) << 8;
return i;
*/
return tlcsMemReadB(addr) | (tlcsMemReadB(addr+1) << 8);
#endif
}
// read a long word from a memory address (addr)
inline unsigned long tlcsMemReadL(unsigned long addr)
{
#ifdef TARGET_GP2X
register unsigned long i asm("r0");
register byte *gA asm("r4");
gA = get_address(addr);
if(gA == 0)
return 0;
asm volatile(
"bic r1,%1,#3 \n"
"ldmia r1,{r0,r3} \n"
"ands r1,%1,#3 \n"
"movne r2,r1,lsl #3 \n"
"movne r0,r0,lsr r2 \n"
"rsbne r1,r2,#32 \n"
"orrne r0,r0,r3,lsl r1"
: "=r"(i)
: "r"(gA)
: "r1","r2","r3");
return i;
#else
unsigned long i;
byte *gA = get_address(addr);
if(gA == 0)
return 0;
i = *(gA++);
i |= (*(gA++)) << 8;
i |= (*(gA++)) << 16;
i |= (*gA) << 24;
return i;
//return tlcsMemReadB(addr) | (tlcsMemReadB(addr +1) << 8) | (tlcsMemReadB(addr +2) << 16) | (tlcsMemReadB(addr +3) << 24);
#endif
}
// write a byte (data) to a memory address (addr)
inline void tlcsMemWriteB(unsigned long addr, unsigned char data)
{
addr&= 0x00FFFFFF;
if (addr<0x000008a0)
{
switch(addr) {
//case 0x80: // CPU speed
// break;
case 0xA0: // L CH Sound Source Control Register
if (cpuram[0xB8] == 0x55 && cpuram[0xB9] == 0xAA)
Write_SoundChipNoise(data);//Flavor SN76496Write(0, data);
break;
case 0xA1: // R CH Sound Source Control Register
if (cpuram[0xB8] == 0x55 && cpuram[0xB9] == 0xAA)
Write_SoundChipTone(data); //Flavor SN76496Write(0, data);
break;
case 0xA2: // L CH DAC Control Register
ngpSoundExecute();
if (cpuram[0xB8] == 0xAA)
dac_writeL(data); //Flavor DAC_data_w(0,data);
break;
/*case 0xA3: // R CH DAC Control Register //Flavor hack for mono only sound
ngpSoundExecute();
if (cpuram[0xB8] == 0xAA)
dac_writeR(data);//Flavor DAC_data_w(1,data);
break;*/
case 0xB8: // Z80 Reset
// if (data == 0x55) DAC_data_w(0,0);
case 0xB9: // Sourd Source Reset Control Register
switch(data) {
case 0x55:
ngpSoundStart();
break;
case 0xAA:
ngpSoundExecute();
ngpSoundOff();
break;
}
break;
case 0xBA:
ngpSoundExecute();
#if defined(DRZ80) || defined(CZ80)
Z80_Cause_Interrupt(Z80_NMI_INT);
#else
z80Interrupt(Z80NMI);
#endif
break;
}
cpuram[addr] = data;
return;
}
else if (addr>0x00003fff && addr<0x00018000)
{
if (addr == 0x87E2 && mainram[0x47F0] != 0xAA)
return; // disallow writes to GEMODE
/*if((addr >= 0x8800 && addr <= 0x88FF)
|| (addr >= 0x8C00 && addr <= 0x8FFF)
|| (addr >= 0xA000 && addr <= 0xBFFF)
|| addr == 0x00008020
|| addr == 0x00008021)
{
spritesDirty = true;
}*/
mainram[addr-0x00004000] = data;
return;
}
else if (addr>=0x00200000 && addr<0x00400000)
flashChipWrite(addr, data);
else if (addr>=0x00800000 && addr<0x00A00000)
flashChipWrite(addr, data);
}
#endif // _MEMORYH_

699
neopopsound.cpp Normal file
View File

@ -0,0 +1,699 @@
// Flavor modified sound.c and sound.h from NEOPOP
// which was originally based on sn76496.c from MAME
// some ideas also taken from NeoPop-SDL code
//---------------------------------------------------------------------------
// Originally from
// NEOPOP : Emulator as in Dreamland
//
// Copyright (c) 2001-2002 by neopop_uk
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
/************************************************************************
* *
* Portions, but not all of this source file are based on MAME v0.60 *
* File "sn76496.c". All copyright goes to the original author. *
* The remaining parts, including DAC processing, by neopop_uk *
* *
************************************************************************/
#ifndef __GP32__
#include "StdAfx.h"
#endif
#include "neopopsound.h"
#include "main.h"
#include "memory.h"
//#include "menu.h"
//=============================================================================
SoundChip toneChip;
SoundChip noiseChip;
//==== DAC
#ifdef TARGET_WIN
#define DAC_BUFFERSIZE (2560 * 1024) //at (256 * 1024) the PC version will crash on MS2 intro
#else
#define DAC_BUFFERSIZE (256 * 1024) //at (256 * 1024) the PC version will crash on MS2 intro
#endif
int dacLBufferRead, dacLBufferWrite, dacLBufferCount;
_u16 dacBufferL[DAC_BUFFERSIZE];
int fixsoundmahjong;
#if !defined(__GP32__) && !defined(TARGET_PSP)
int volume = SDL_MIX_MAXVOLUME;//SDL_MIX_MAXVOLUME / 2;
void increaseVolume()
{
if(volume < SDL_MIX_MAXVOLUME)
volume++;
}
void decreaseVolume()
{
if(volume > 0)
volume--;
}
#endif
//=============================================================================
#define SOUNDCHIPCLOCK (3072000) //Unverified / sounds correct
#define MAX_OUTPUT 0x7fff
#define STEP 0x10000 //Fixed point adjuster
#define MAX_OUTPUT_STEP 0x7fff0000
#define STEP_SHIFT 16
static _u32 VolTable[16];
static _u32 UpdateStep = 0; //Number of steps during one sample.
/* Formulas for noise generator */
/* bit0 = output */
/* noise feedback for white noise mode (verified on real SN76489 by John Kortink) */
#define FB_WNOISE 0x14002 /* (16bits) bit16 = bit0(out) ^ bit2 ^ bit15 */
/* noise feedback for periodic noise mode */
#define FB_PNOISE 0x08000 /* 15bit rotate */
/* noise generator start preset (for periodic noise) */
#define NG_PRESET 0x0f35
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
//=============================================================================
static _u16 sample_chip_tone(void)
{
int i;
int vol[3];
unsigned int out;
int left;
/* vol[] keeps track of how long each square wave stays */
/* in the 1 position during the sample period. */
vol[0] = vol[1] = vol[2] = /*vol[3] = */ 0;
for (i = 0; i < 3; i++)
{
if (toneChip.Output[i]) vol[i] += toneChip.Count[i];
toneChip.Count[i] -= STEP;
/* Period[i] is the half period of the square wave. Here, in each */
/* loop I add Period[i] twice, so that at the end of the loop the */
/* square wave is in the same status (0 or 1) it was at the start. */
/* vol[i] is also incremented by Period[i], since the wave has been 1 */
/* exactly half of the time, regardless of the initial position. */
/* If we exit the loop in the middle, Output[i] has to be inverted */
/* and vol[i] incremented only if the exit status of the square */
/* wave is 1. */
while (toneChip.Count[i] <= 0)
{
toneChip.Count[i] += toneChip.Period[i];
if (toneChip.Count[i] > 0)
{
toneChip.Output[i] ^= 1;
if (toneChip.Output[i]) vol[i] += toneChip.Period[i];
break;
}
toneChip.Count[i] += toneChip.Period[i];
vol[i] += toneChip.Period[i];
}
if (toneChip.Output[i]) vol[i] -= toneChip.Count[i];
}
/*
left = STEP;
do
{
int nextevent;
if (toneChip.Count[3] < left) nextevent = toneChip.Count[3];
else nextevent = left;
if (toneChip.Output[3]) vol[3] += toneChip.Count[3];
toneChip.Count[3] -= nextevent;
if (toneChip.Count[3] <= 0)
{
if (toneChip.RNG & 1) toneChip.RNG ^= toneChip.NoiseFB;
toneChip.RNG >>= 1;
toneChip.Output[3] = toneChip.RNG & 1;
toneChip.Count[3] += toneChip.Period[3];
if (toneChip.Output[3]) vol[3] += toneChip.Period[3];
}
if (toneChip.Output[3]) vol[3] -= toneChip.Count[3];
left -= nextevent;
} while (left > 0);
*/
out = vol[0] * toneChip.Volume[0] + vol[1] * toneChip.Volume[1] +
vol[2] * toneChip.Volume[2];
//if (out > MAX_OUTPUT * STEP) out = MAX_OUTPUT * STEP;
if (out > MAX_OUTPUT_STEP) out = MAX_OUTPUT_STEP;
return out>>STEP_SHIFT;//out / STEP;
}
//=============================================================================
static _u16 sample_chip_noise(void)
{
int i;
//int vol[4];
int vol3 = 0;
unsigned int out;
int left;
/* vol[] keeps track of how long each square wave stays */
/* in the 1 position during the sample period. */
/*
vol[0] = vol[1] = vol[2] = vol[3] = 0;
for (i = 0; i < 3; i++)
{
if (noiseChip.Output[i]) vol[i] += noiseChip.Count[i];
noiseChip.Count[i] -= STEP;
// Period[i] is the half period of the square wave. Here, in each
// loop I add Period[i] twice, so that at the end of the loop the
// square wave is in the same status (0 or 1) it was at the start.
// vol[i] is also incremented by Period[i], since the wave has been 1
// exactly half of the time, regardless of the initial position.
// If we exit the loop in the middle, Output[i] has to be inverted
// and vol[i] incremented only if the exit status of the square
// wave is 1.
while (noiseChip.Count[i] <= 0)
{
noiseChip.Count[i] += noiseChip.Period[i];
if (noiseChip.Count[i] > 0)
{
noiseChip.Output[i] ^= 1;
if (noiseChip.Output[i]) vol[i] += noiseChip.Period[i];
break;
}
noiseChip.Count[i] += noiseChip.Period[i];
vol[i] += noiseChip.Period[i];
}
if (noiseChip.Output[i]) vol[i] -= noiseChip.Count[i];
}
*/
if (noiseChip.Volume[3])
{
left = STEP;
do
{
int nextevent = min(noiseChip.Count[3],left);
//if (noiseChip.Count[3] < left) nextevent = noiseChip.Count[3];
//else nextevent = left;
if (noiseChip.Output[3]) vol3 += noiseChip.Count[3];
noiseChip.Count[3] -= nextevent;
if (noiseChip.Count[3] <= 0)
{
if (noiseChip.RNG & 1) noiseChip.RNG ^= noiseChip.NoiseFB;
noiseChip.RNG >>= 1;
noiseChip.Output[3] = noiseChip.RNG & 1;
noiseChip.Count[3] += noiseChip.Period[3];
if (noiseChip.Output[3]) vol3 += noiseChip.Period[3];
}
if (noiseChip.Output[3]) vol3 -= noiseChip.Count[3];
left -= nextevent;
} while (left > 0);
}
out = vol3 * noiseChip.Volume[3];
//if (out > MAX_OUTPUT * STEP) out = MAX_OUTPUT * STEP;
if (out > MAX_OUTPUT_STEP) out = MAX_OUTPUT_STEP;
return out>>STEP_SHIFT;//out / STEP;
}
//=============================================================================
void sound_update(_u16* chip_buffer, int length_bytes)
{
length_bytes >>= 1;//turn it into words
while (length_bytes)
{
//Mix a mono track out of: (Tone + Noise) >> 1
//Write it to the sound buffer
*(chip_buffer++) = (sample_chip_tone() + sample_chip_noise()) >> 1;
length_bytes--;
}
}
//=============================================================================
void WriteSoundChip(SoundChip* chip, _u8 data)
{
#if !defined(__GP32__) && !defined(TARGET_PSP)
SDL_LockAudio();
#endif
//Command
if (data & 0x80)
{
int r = (data & 0x70) >> 4;
int c = r>>1;//r/2;
chip->LastRegister = r;
chip->Register[r] = (chip->Register[r] & 0x3f0) | (data & 0x0f);
switch(r)
{
case 0: /* tone 0 : frequency */
case 2: /* tone 1 : frequency */
case 4: /* tone 2 : frequency */
chip->Period[c] = UpdateStep * chip->Register[r];
if (chip->Period[c] == 0) chip->Period[c] = UpdateStep;
if (r == 4)
{
/* update noise shift frequency */
if ((chip->Register[6] & 0x03) == 0x03)
chip->Period[3] = chip->Period[2]<<1;
}
break;
case 1: /* tone 0 : volume */
case 3: /* tone 1 : volume */
case 5: /* tone 2 : volume */
case 7: /* noise : volume */
#ifdef NEOPOP_DEBUG
if (filter_sound)
{
if (chip == &toneChip)
system_debug_message("sound (T): Set Tone %d Volume to %d (0 = min, 15 = max)", c, 15 - (data & 0xF));
else
system_debug_message("sound (N): Set Tone %d Volume to %d (0 = min, 15 = max)", c, 15 - (data & 0xF));
}
#endif
chip->Volume[c] = VolTable[data & 0xF];
break;
case 6: /* noise : frequency, mode */
{
int n = chip->Register[6];
#ifdef NEOPOP_DEBUG
if (filter_sound)
{
char *pm, *nm = "White";
if ((n & 4)) nm = "Periodic";
switch(n & 3)
{
case 0: pm = "N/512"; break;
case 1: pm = "N/1024"; break;
case 2: pm = "N/2048"; break;
case 3: pm = "Tone#2"; break;
}
if (chip == &toneChip)
system_debug_message("sound (T): Set Noise Mode to %s, Period = %s", nm, pm);
else
system_debug_message("sound (N): Set Noise Mode to %s, Period = %s", nm, pm);
}
#endif
chip->NoiseFB = (n & 4) ? FB_WNOISE : FB_PNOISE;
n &= 3;
/* N/512,N/1024,N/2048,Tone #2 output */
chip->Period[3] = (n == 3) ? 2 * chip->Period[2] : (UpdateStep << (5+n));
/* reset noise shifter */
chip->RNG = NG_PRESET;
chip->Output[3] = chip->RNG & 1;
}
break;
}
}
else
{
int r = chip->LastRegister;
int c = r/2;
switch (r)
{
case 0: /* tone 0 : frequency */
case 2: /* tone 1 : frequency */
case 4: /* tone 2 : frequency */
chip->Register[r] = (chip->Register[r] & 0x0f) | ((data & 0x3f) << 4);
chip->Period[c] = UpdateStep * chip->Register[r];
if (chip->Period[c] == 0) chip->Period[c] = UpdateStep;
if (r == 4)
{
/* update noise shift frequency */
if ((chip->Register[6] & 0x03) == 0x03)
chip->Period[3] = chip->Period[2]<<1;
}
#ifdef NEOPOP_DEBUG
if (filter_sound)
{
if (chip == &toneChip)
system_debug_message("sound (T): Set Tone %d Frequency to %d", c, chip->Register[r]);
else
system_debug_message("sound (N): Set Tone %d Frequency to %d", c, chip->Register[r]);
}
#endif
break;
}
}
#if !defined(__GP32__) && !defined(TARGET_PSP)
SDL_UnlockAudio();
#endif
}
//=============================================================================
//#ifdef TARGET_PSP
void dac_writeL(unsigned char data)
{
static int conv=5;
#if !defined(__GP32__) && !defined(TARGET_PSP)
SDL_LockAudio();
#endif
#ifdef TARGET_PSP
//pretend that conv=5.5 (44100/8000) conversion factor
if(conv==5)
conv=6;
else
{
conv=5;
//Arregla el sonido del Super Real Mahjong
if (fixsoundmahjong>500)
conv=3;
}
#else
conv=1;
#endif
for(int i=0;i<conv;i++)
{
//Write to buffer
dacBufferL[dacLBufferWrite++] = (data-0x80)<<8;
//dacLBufferWrite++;
if (dacLBufferWrite == DAC_BUFFERSIZE)
dacLBufferWrite = 0;
//Overflow?
dacLBufferCount++;
if (dacLBufferCount == DAC_BUFFERSIZE)
{
//dbg_printf("dac_write: DAC buffer overflow\nPlease report this to the author.");
dacLBufferCount = 0;
}
}
#if !defined(__GP32__) && !defined(TARGET_PSP)
SDL_UnlockAudio();
#endif
}
//#endif
/*void dac_writeR(unsigned char data)
{
SDL_LockAudio();
//Write to buffer
dacBufferR[dacRBufferWrite] = data;
dacRBufferWrite++;
if (dacRBufferWrite == DAC_BUFFERSIZE)
dacRBufferWrite = 0;
//Overflow?
dacRBufferCount++;
if (dacRBufferCount == DAC_BUFFERSIZE)
{
dbg_printf("dac_write: DAC buffer overflow\nPlease report this to the author.");
dacRBufferCount = 0;
}
SDL_UnlockAudio();
}*/
void dac_mixer(_u16* stream, int length_bytes)
{
#if !defined(__GP32__) && !defined(TARGET_PSP)
int length_words = length_bytes>>1;
length_bytes &= 0xFFFFFFFE; //make sure it's 16bit safe
if(dacLBufferRead+length_words >= DAC_BUFFERSIZE)
{
SDL_MixAudio((Uint8*)stream, (Uint8*)&dacBufferL[dacLBufferRead], (DAC_BUFFERSIZE-dacLBufferRead)*2, volume); //mix it to the buffer
SDL_MixAudio((Uint8*)&stream[DAC_BUFFERSIZE-dacLBufferRead], (Uint8*)dacBufferL, length_bytes-((DAC_BUFFERSIZE-dacLBufferRead)*2), volume); //mix it to the buffer
dacLBufferRead = length_words-(DAC_BUFFERSIZE-dacLBufferRead);
}
else
{
SDL_MixAudio((Uint8*)stream, (Uint8*)&dacBufferL[dacLBufferRead], length_bytes, volume); //mix it to the buffer
dacLBufferRead += length_words;
}
dacLBufferCount -= length_words; //need it in 16bits
#endif
}
void dac_update(_u16* dac_buffer, int length_bytes)
{
while (length_bytes > 1)
{
//Copy then clear DAC data
#ifdef TARGET_PSP
*(dac_buffer++) |= dacBufferL[dacLBufferRead];
#else
*(dac_buffer++) = dacBufferL[dacLBufferRead];
#endif
dacBufferL[dacLBufferRead] = 0; //silence?
length_bytes -= 2; // 1 byte = 8 bits
if (dacLBufferCount > 0)
{
dacLBufferCount--;
//Advance the DAC read
// dacLBufferRead++;
if (++dacLBufferRead == DAC_BUFFERSIZE)
dacLBufferRead = 0;
}
}
}
//=============================================================================
#ifdef __GP32__
volatile int soundON = 0;
#endif
//Resets the sound chips, also used whenever sound options are changed
void sound_init(int SampleRate)
{
int i;
double out;
/* the base clock for the tone generators is the chip clock divided by 16; */
/* for the noise generator, it is clock / 256. */
/* Here we calculate the number of steps which happen during one sample */
/* at the given sample rate. No. of events = sample rate / (clock/16). */
/* STEP is a multiplier used to turn the fraction into a fixed point */
/* number. */
UpdateStep = (_u32)(((double)STEP * SampleRate * 16) / SOUNDCHIPCLOCK);
//Initialise Left Chip
memset(&toneChip, 0, sizeof(SoundChip));
//Initialise Right Chip
memset(&noiseChip, 0, sizeof(SoundChip));
//Default register settings
for (i = 0;i < 8;i+=2)
{
toneChip.Register[i] = 0;
toneChip.Register[i + 1] = 0x0f; /* volume = 0 */
noiseChip.Register[i] = 0;
noiseChip.Register[i + 1] = 0x0f; /* volume = 0 */
}
for (i = 0;i < 4;i++)
{
toneChip.Output[i] = 0;
toneChip.Period[i] = toneChip.Count[i] = UpdateStep;
noiseChip.Output[i] = 0;
noiseChip.Period[i] = noiseChip.Count[i] = UpdateStep;
}
//Build the volume table
out = MAX_OUTPUT / 3;
/* build volume table (2dB per step) */
for (i = 0;i < 15;i++)
{
VolTable[i] = (_u32)out;
out /= 1.258925412; /* = 10 ^ (2/20) = 2dB */
}
VolTable[15] = 0;
//Clear the DAC buffer
for (i = 0; i < DAC_BUFFERSIZE; i++)
dacBufferL[i] = 0;
dacLBufferCount = 0;
dacLBufferRead = 0;
dacLBufferWrite = 0;
#ifdef __GP32__
soundON = 1;
#endif
}
//=============================================================================
#ifdef TARGET_PSP
#define NGPC_CHIP_FREQUENCY 44100
#else
#define NGPC_CHIP_FREQUENCY 8000
#endif
int chip_freq=NGPC_CHIP_FREQUENCY;//what we'd prefer
#define CHIPBUFFERLENGTH 35280
#define UNDEFINED 0xFFFFFF
// ====== Chip sound =========
//static LPDIRECTSOUNDBUFFER chipBuffer = NULL; // Chip Buffer
static int lastChipWrite = 0, chipWrite = UNDEFINED; //Write Cursor
// ====== DAC sound =========
//static LPDIRECTSOUNDBUFFER dacBuffer = NULL; // DAC Buffer
static int lastDacWrite = 0, dacWrite = UNDEFINED; //Write Cursor
_u8 blockSound[CHIPBUFFERLENGTH], blockDAC[CHIPBUFFERLENGTH]; // Gets filled with sound data.
unsigned int blockSoundWritePtr = 0;
unsigned int blockSoundReadPtr = 0;
void system_sound_chipreset(void)
{
//Initialises sound chips, matching frequncies
sound_init(chip_freq);
}
#ifdef __GP32__
int audioCallback(unsigned short* sndBuf,int len) {
int i,smp;
if (soundON==0)
return 0;
for (i=0;i<len;i++)
{
smp = (sample_chip_tone() + sample_chip_noise()) >> 1;
smp = (smp + dacBufferL[dacLBufferRead]) >> 1;
*(sndBuf++) = smp;
*(sndBuf++) = smp; // stereo ?
dacBufferL[dacLBufferRead] = 0; //silence?
if (dacLBufferCount > 0)
{
dacLBufferCount--;
if (++dacLBufferRead == DAC_BUFFERSIZE)
dacLBufferRead = 0;
}
}
return 1;
}
#endif
#ifndef TARGET_PSP
void mixaudioCallback(void *userdata, Uint8 *stream, int len)
{
#ifndef __GP32__
sound_update((_u16*)blockSound, len); //Get sound data
// memcpy(stream, blockSound, len); //put it in the buffer
SDL_MixAudio(stream, blockSound, len, volume); //mix it to the buffer
if(dacLBufferCount >= len)
{
//dac_update((_u16*)blockDAC, len); //Get DAC data
//SDL_MixAudio(stream, blockDAC, len, volume); //mix it to the buffer
dac_mixer((_u16*)stream, len); //Get DAC data
}
#endif
}
#endif /* TARGET_PSP */
int sound_system_init()
{
#if !defined(__GP32__) && !defined(TARGET_PSP)
//set up SDL sound here?
SDL_AudioSpec fmt, retFmt;
fmt.freq = chip_freq; //11025 is good for dac_ sound
fmt.format = AUDIO_S16;
fmt.channels = 1;
#ifdef TARGET_PSP
fmt.samples = 512;
#else
fmt.samples = 512;
#endif
fmt.callback = mixaudioCallback;
fmt.userdata = NULL;
/* Open the audio device and start playing sound! */
if ( SDL_OpenAudio(&fmt, &retFmt) < 0 ) {
fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
exit(1);
}
chip_freq = retFmt.freq;
system_sound_chipreset(); //Resets chips
SDL_PauseAudio(0);
#else
system_sound_chipreset(); //Resets chips
#endif
return 1;
}
//call this every so often to update the sound output
void system_sound_update(void)
{
}

88
neopopsound.h Normal file
View File

@ -0,0 +1,88 @@
// Flavor modified sound.c and sound.h from NEOPOP
// which was originally based on sn76496.c from MAME
// some ideas also taken from NeoPop-SDL code
//---------------------------------------------------------------------------
// Originally from
// NEOPOP : Emulator as in Dreamland
//
// Copyright (c) 2001-2002 by neopop_uk
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
#ifndef __NEOPOPSOUND__
#define __NEOPOPSOUND__
//=============================================================================
#ifdef __GP32__
#include "main.h"
#endif
#include "StdAfx.h"
typedef struct
{
int LastRegister; /* last register written */
int Register[8]; /* registers */
int Volume[4];
int Period[4];
int Count[4];
int Output[4];
unsigned int RNG; /* noise generator */
int NoiseFB; /* noise feedback mask */
} SoundChip;
//=============================================================================
extern SoundChip toneChip;
extern SoundChip noiseChip;
void WriteSoundChip(SoundChip* chip, _u8 data);
int sound_system_init();
BOOL system_sound_init(void);
void system_sound_chipreset(void);
//void system_sound_update(void);
void system_sound_update(int nframes);
void system_VBL(void);
#define Write_SoundChipTone(VALUE) (WriteSoundChip(&toneChip, VALUE))
#define Write_SoundChipNoise(VALUE) (WriteSoundChip(&noiseChip, VALUE))
//=============================================================================
//void dac_writeL(unsigned char);
//void dac_writeR(unsigned char);
void sound_init(int SampleRate);
extern BOOL mute;
void dac_update(_u16* dac_buffer, int length_bytes);
void sound_update(_u16* chip_buffer, int length_bytes);
#ifndef __GP32__
void increaseVolume();
void decreaseVolume();
#endif
//#define dac_writeL dac_write
//#define dac_writeR dac_write
void dac_writeL(unsigned char);
//void dac_writeR(unsigned char);
void dac_write(unsigned char);
//=============================================================================
#endif

214
ngpBios.cpp Normal file
View File

@ -0,0 +1,214 @@
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
// ngpBios.cpp: implementation of the ngpBios class.
//
//////////////////////////////////////////////////////////////////////
#ifndef __GP32__
#include "StdAfx.h"
#endif
#include "main.h"
#include "ngpBios.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
unsigned char sysfont[8*256] =
{
// 0x00 - 0x07
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x08 - 0x0F
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
// 0x10 - 0x17
0x20, 0x30, 0x38, 0x3c, 0x38, 0x30, 0x20, 0x00, 0x04, 0x0c, 0x1c, 0x3c, 0x1c, 0x0c, 0x04, 0x00,
0x00, 0x00, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x00, 0x00,
0x20, 0x3c, 0x08, 0x3c, 0x28, 0x7e, 0x08, 0x00, 0x3c, 0x24, 0x3c, 0x24, 0x3c, 0x24, 0x24, 0x00,
0x3c, 0x24, 0x24, 0x3c, 0x24, 0x24, 0x3c, 0x00, 0x10, 0x10, 0x54, 0x54, 0x10, 0x28, 0xc6, 0x00,
// 0x18 - 0x1F
0x10, 0x12, 0xd4, 0x58, 0x54, 0x92, 0x10, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x38, 0x54, 0x92, 0x00,
0x10, 0x28, 0x7c, 0x92, 0x38, 0x54, 0xfe, 0x00, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0xfe, 0x00,
0x7f, 0xff, 0xe0, 0xff, 0x7f, 0x01, 0xff, 0xff, 0xdc, 0xde, 0x1f, 0x9f, 0xdf, 0xdd, 0xdc, 0x9c,
0x3b, 0x3b, 0x3b, 0xbb, 0xfb, 0xfb, 0xfb, 0x7b, 0x8f, 0x9e, 0xbc, 0xf8, 0xf8, 0xbc, 0x9e, 0x8f,
// 0x20 - 0x27
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x08, 0x10, 0x00, 0x18, 0x00,
0x6c, 0x6c, 0x24, 0x48, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0xfe, 0x28, 0xfe, 0x50, 0x50, 0x00,
0x10, 0x7c, 0x90, 0x7c, 0x12, 0xfc, 0x10, 0x00, 0x42, 0xa4, 0xa8, 0x54, 0x2a, 0x4a, 0x84, 0x00,
0x30, 0x48, 0x38, 0x62, 0x94, 0x88, 0x76, 0x00, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00,
// 0x28 - 0x2F
0x08, 0x10, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, 0x20, 0x10, 0x08, 0x08, 0x08, 0x10, 0x20, 0x00,
0x10, 0x92, 0x54, 0x38, 0x38, 0x54, 0x92, 0x00, 0x10, 0x10, 0x10, 0xfe, 0x10, 0x10, 0x10, 0x00,
0x00, 0x00, 0x00, 0x30, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00,
// 0x30 - 0x37
0x3c, 0x42, 0x46, 0x5a, 0x62, 0x42, 0x3c, 0x00, 0x08, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
0x3c, 0x42, 0x42, 0x0c, 0x30, 0x40, 0x7e, 0x00, 0x3c, 0x42, 0x02, 0x1c, 0x02, 0x42, 0x3c, 0x00,
0x0c, 0x14, 0x24, 0x44, 0x7e, 0x04, 0x04, 0x00, 0x7e, 0x40, 0x7c, 0x02, 0x02, 0x42, 0x3c, 0x00,
0x3c, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x7e, 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x00,
// 0x38 - 0x3F
0x3c, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x3c, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x3c, 0x00,
0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x08, 0x10, 0x00,
0x00, 0x08, 0x10, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x00, 0x00,
0x00, 0x10, 0x08, 0x04, 0x08, 0x10, 0x00, 0x00, 0x3c, 0x62, 0x62, 0x0c, 0x18, 0x00, 0x18, 0x00,
// 0x40 - 0x47
0x7c, 0x82, 0xba, 0xa2, 0xba, 0x82, 0x7c, 0x00, 0x10, 0x28, 0x28, 0x44, 0x7c, 0x82, 0x82, 0x00,
0x7c, 0x42, 0x42, 0x7c, 0x42, 0x42, 0x7c, 0x00, 0x1c, 0x22, 0x40, 0x40, 0x40, 0x22, 0x1c, 0x00,
0x78, 0x44, 0x42, 0x42, 0x42, 0x44, 0x78, 0x00, 0x7e, 0x40, 0x40, 0x7e, 0x40, 0x40, 0x7e, 0x00,
0x7e, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x00, 0x3c, 0x42, 0x80, 0x9e, 0x82, 0x46, 0x3a, 0x00,
//
0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00,
0x02, 0x02, 0x02, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x42, 0x44, 0x48, 0x50, 0x68, 0x44, 0x42, 0x00,
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x82, 0xc6, 0xaa, 0x92, 0x82, 0x82, 0x82, 0x00,
0x42, 0x62, 0x52, 0x4a, 0x46, 0x42, 0x42, 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x44, 0x38, 0x00,
// 0x50
0x7c, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40, 0x00, 0x38, 0x44, 0x82, 0x82, 0x8a, 0x44, 0x3a, 0x00,
0x7c, 0x42, 0x42, 0x7c, 0x48, 0x44, 0x42, 0x00, 0x3c, 0x42, 0x40, 0x3c, 0x02, 0x42, 0x3c, 0x00,
0xfe, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00,
0x82, 0x82, 0x44, 0x44, 0x28, 0x28, 0x10, 0x00, 0x82, 0x92, 0x92, 0xaa, 0xaa, 0x44, 0x44, 0x00,
//
0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82, 0x00, 0x82, 0x44, 0x28, 0x10, 0x10, 0x10, 0x10, 0x00,
0x7e, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7e, 0x00, 0x18, 0x10, 0x10, 0x10, 0x10, 0x10, 0x18, 0x00,
0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00,
0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00,
// 0x60
0x08, 0x10, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x04, 0x7c, 0x84, 0x84, 0x7e, 0x00,
0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x42, 0x3c, 0x00,
0x02, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x7e, 0x40, 0x3e, 0x00,
0x0c, 0x10, 0x3e, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x3e, 0x02, 0x7c, 0x00,
//
0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x00, 0x18, 0x18, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00,
0x06, 0x06, 0x00, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x20, 0x20, 0x26, 0x28, 0x30, 0x28, 0x26, 0x00,
0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x80, 0xec, 0x92, 0x92, 0x92, 0x92, 0x00,
0x00, 0x40, 0x78, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x00,
// 0x70
0x00, 0x3c, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x00, 0x00, 0x78, 0x84, 0x84, 0x7c, 0x04, 0x06, 0x00,
0x00, 0x00, 0x5c, 0x62, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3e, 0x40, 0x3c, 0x02, 0x7c, 0x00,
0x00, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x0e, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x3f, 0x00,
0x00, 0x00, 0x42, 0x42, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x92, 0x92, 0x92, 0x92, 0x6c, 0x00,
//
0x00, 0x00, 0x42, 0x24, 0x18, 0x24, 0x42, 0x00, 0x00, 0x00, 0x42, 0x42, 0x3e, 0x02, 0x7c, 0x00,
0x00, 0x00, 0x7e, 0x02, 0x3c, 0x40, 0x7e, 0x00, 0x08, 0x10, 0x10, 0x20, 0x10, 0x10, 0x08, 0x00,
0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x10, 0x00, 0x20, 0x10, 0x10, 0x08, 0x10, 0x10, 0x20, 0x00,
0x00, 0x00, 0x60, 0x92, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x80
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x90, 0x90, 0x60, 0x00,
0x1e, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xf0, 0x00,
0x00, 0x00, 0x00, 0x80, 0x40, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x30, 0x00, 0x00,
0x20, 0xf8, 0x26, 0x78, 0xd0, 0x80, 0x7c, 0x00, 0x00, 0x10, 0x3a, 0x1c, 0x36, 0x5a, 0x36, 0x00,
//
0x00, 0x00, 0x44, 0x42, 0x42, 0x42, 0x30, 0x00, 0x00, 0x3c, 0x00, 0x3c, 0x42, 0x02, 0x3c, 0x00,
0x00, 0x3c, 0x00, 0x7c, 0x08, 0x38, 0x66, 0x00, 0x00, 0x14, 0x72, 0x1c, 0x32, 0x52, 0x34, 0x00,
0x00, 0x28, 0x2c, 0x3a, 0x62, 0x16, 0x10, 0x00, 0x00, 0x08, 0x5c, 0x6a, 0x4a, 0x0c, 0x18, 0x00,
0x00, 0x08, 0x0c, 0x38, 0x4c, 0x4a, 0x38, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x02, 0x1c, 0x00,
// 0x90
0x00, 0x00, 0x80, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x28, 0xf2, 0x3c, 0x6a, 0xaa, 0xb6, 0xec, 0x00,
0x80, 0x88, 0x84, 0x84, 0x82, 0x92, 0x70, 0x00, 0x78, 0x00, 0x3c, 0xc2, 0x02, 0x04, 0x78, 0x00,
0x78, 0x00, 0xfc, 0x08, 0x30, 0x50, 0x9e, 0x00, 0x2c, 0xf2, 0x20, 0x7c, 0xa2, 0xa2, 0xe4, 0x00,
0x28, 0xf4, 0x2a, 0x4a, 0x4a, 0x88, 0xb0, 0x00, 0x20, 0xfc, 0x12, 0xfc, 0x08, 0xc2, 0x7c, 0x00,
//
0x04, 0x18, 0x60, 0x80, 0xc0, 0x30, 0x0e, 0x00, 0x84, 0xbe, 0x84, 0x84, 0x84, 0x84, 0x58, 0x00,
0x00, 0x7c, 0x02, 0x00, 0x80, 0x82, 0x7e, 0x00, 0x20, 0xfe, 0x10, 0x78, 0x8c, 0xc0, 0x7c, 0x00,
0x80, 0x80, 0x80, 0x80, 0x82, 0x84, 0x78, 0x00, 0x04, 0xfe, 0x3c, 0x44, 0x7c, 0x04, 0x78, 0x00,
0x44, 0x5e, 0xf4, 0x44, 0x48, 0x40, 0x3e, 0x00, 0x44, 0x58, 0xe0, 0x3e, 0xc0, 0x40, 0x3c, 0x00,
// 0xA0
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x90, 0x90, 0x60, 0x00,
0x1e, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xf0, 0x00,
0x00, 0x00, 0x00, 0x80, 0x40, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x30, 0x00, 0x00,
0x1e, 0x62, 0x1e, 0x62, 0x04, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x1e, 0x6a, 0x0e, 0x08, 0x18, 0x00,
// 0xA8
0x00, 0x00, 0x06, 0x18, 0x68, 0x08, 0x08, 0x00, 0x00, 0x10, 0x1c, 0x72, 0x42, 0x04, 0x38, 0x00,
0x00, 0x00, 0x0c, 0x78, 0x10, 0x10, 0x7e, 0x00, 0x00, 0x08, 0x08, 0x7c, 0x18, 0x28, 0x48, 0x00,
0x00, 0x00, 0x26, 0x1a, 0x72, 0x10, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x34, 0x04, 0x08, 0x7e, 0x00,
0x00, 0x00, 0x78, 0x04, 0x3c, 0x04, 0x78, 0x00, 0x00, 0x00, 0x52, 0x4a, 0x22, 0x04, 0x38, 0x00,
// 0xB0
0x00, 0x00, 0x80, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xc2, 0x14, 0x1c, 0x10, 0x30, 0x60, 0x00,
0x02, 0x0c, 0x38, 0xc8, 0x08, 0x08, 0x08, 0x00, 0x60, 0x3c, 0xe2, 0x82, 0x82, 0x04, 0x38, 0x00,
0x00, 0x1c, 0x70, 0x10, 0x10, 0x1c, 0xe2, 0x00, 0x08, 0xfe, 0x18, 0x38, 0x68, 0xc8, 0x18, 0x00,
0x10, 0x3e, 0xd2, 0x12, 0x22, 0x62, 0xcc, 0x00, 0x20, 0x3c, 0xf0, 0x1e, 0xf0, 0x08, 0x08, 0x00,
//
0x10, 0x3e, 0x62, 0xc2, 0x04, 0x0c, 0x70, 0x00, 0x40, 0x7e, 0x44, 0x84, 0x84, 0x08, 0x30, 0x00,
0x3e, 0xc2, 0x02, 0x02, 0x02, 0x02, 0xfc, 0x00, 0x44, 0x5e, 0xe4, 0x44, 0x44, 0x08, 0xf0, 0x00,
0x60, 0x12, 0xc2, 0x22, 0x04, 0x04, 0xf8, 0x00, 0x3c, 0xc6, 0x0c, 0x08, 0x38, 0x6c, 0xc6, 0x00,
0x40, 0x4e, 0x72, 0xc4, 0x4c, 0x40, 0x3e, 0x00, 0x82, 0x42, 0x62, 0x04, 0x04, 0x08, 0x70, 0x00,
// 0xC0
0x3c, 0x42, 0x72, 0x8a, 0x04, 0x0c, 0x70, 0x00, 0x0c, 0xf8, 0x10, 0xfe, 0x10, 0x10, 0x60, 0x00,
0x22, 0xa2, 0x92, 0x42, 0x04, 0x08, 0x70, 0x00, 0x3c, 0x40, 0x1e, 0xe8, 0x08, 0x10, 0x60, 0x00,
0x40, 0x40, 0x70, 0x4c, 0x42, 0x40, 0x40, 0x00, 0x08, 0x3e, 0xc8, 0x08, 0x08, 0x18, 0x70, 0x00,
0x00, 0x1c, 0x60, 0x00, 0x00, 0x3c, 0xc2, 0x00, 0x3c, 0xc2, 0x26, 0x38, 0x1c, 0x36, 0xe2, 0x00,
//
0x10, 0x3c, 0xc6, 0x1c, 0x38, 0xd6, 0x12, 0x00, 0x02, 0x02, 0x02, 0x06, 0x04, 0x1c, 0xf0, 0x00,
0x18, 0x4c, 0x44, 0x46, 0x42, 0x82, 0x82, 0x00, 0x80, 0x86, 0xbc, 0xe0, 0x80, 0x80, 0x7e, 0x00,
0x3c, 0xc2, 0x02, 0x02, 0x04, 0x08, 0x30, 0x00, 0x30, 0x48, 0x4c, 0x84, 0x86, 0x02, 0x02, 0x00,
0x10, 0xfe, 0x10, 0x54, 0x52, 0x92, 0x92, 0x00, 0x3c, 0xc2, 0x02, 0x44, 0x28, 0x10, 0x0c, 0x00,
// 0xD0
0x70, 0x0c, 0x60, 0x18, 0xc4, 0x30, 0x0e, 0x00, 0x30, 0x40, 0x4c, 0x84, 0x8e, 0xba, 0x62, 0x00,
0x04, 0x04, 0x64, 0x18, 0x0c, 0x16, 0xe2, 0x00, 0x1c, 0xe0, 0x3e, 0xe0, 0x20, 0x20, 0x1e, 0x00,
0x4e, 0x52, 0x62, 0xe4, 0x20, 0x10, 0x18, 0x00, 0x1c, 0x64, 0x04, 0x08, 0x08, 0x10, 0xfe, 0x00,
0x1c, 0x62, 0x02, 0x3e, 0x02, 0x02, 0x7c, 0x00, 0x3c, 0xc0, 0x3e, 0xc2, 0x02, 0x04, 0x78, 0x00,
//
0x44, 0x42, 0x42, 0x42, 0x22, 0x04, 0x78, 0x00, 0x50, 0x50, 0x52, 0x52, 0x52, 0x54, 0x88, 0x00,
0x80, 0x80, 0x82, 0x82, 0x84, 0x88, 0xf0, 0x00, 0x1c, 0xe2, 0x82, 0x82, 0x82, 0x4c, 0x74, 0x00,
0x3c, 0xc2, 0x82, 0x82, 0x02, 0x04, 0x38, 0x00, 0xc0, 0x62, 0x22, 0x02, 0x04, 0x08, 0xf0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x02, 0x00,
// 0xE0
0x20, 0xf8, 0x40, 0x5e, 0x80, 0xa0, 0x9e, 0x00, 0x20, 0xfe, 0x40, 0x7c, 0xc2, 0x86, 0x3c, 0x00,
0x00, 0x3c, 0xc6, 0x02, 0x02, 0x0c, 0x38, 0x00, 0x0e, 0xf8, 0x10, 0x20, 0x20, 0x10, 0x0e, 0x00,
0x40, 0x4c, 0x30, 0x40, 0x80, 0x80, 0x7e, 0x00, 0x44, 0xf2, 0x4a, 0x9c, 0xa4, 0xa6, 0x3a, 0x00,
0x40, 0x5c, 0x82, 0x80, 0xa0, 0xa0, 0x9e, 0x00, 0x48, 0x7c, 0x52, 0xb2, 0xbe, 0xaa, 0x4c, 0x00,
//
0x20, 0xfc, 0x32, 0x62, 0xee, 0xaa, 0x2c, 0x00, 0x38, 0x54, 0x92, 0x92, 0xb2, 0xa2, 0x4c, 0x00,
0x44, 0x5e, 0x84, 0x9c, 0xa4, 0xa6, 0x9c, 0x00, 0x28, 0xee, 0x44, 0x84, 0x84, 0x44, 0x38, 0x00,
0x78, 0x10, 0x64, 0x34, 0x8a, 0x8a, 0x30, 0x00, 0x30, 0x58, 0x48, 0x84, 0x84, 0x02, 0x02, 0x00,
0xbc, 0x88, 0xbe, 0x84, 0xbc, 0xa6, 0x9c, 0x00, 0x68, 0x1e, 0x68, 0x1e, 0x78, 0x8c, 0x7a, 0x00,
// 0xF0
0x70, 0x14, 0x7c, 0x96, 0x94, 0x94, 0x68, 0x00, 0x2c, 0xf2, 0x60, 0xa0, 0xa2, 0xc2, 0x7c, 0x00,
0x48, 0x7c, 0x6a, 0xaa, 0xb2, 0xb2, 0x6c, 0x00, 0x10, 0xf8, 0x20, 0xf8, 0x22, 0x22, 0x1c, 0x00,
0x48, 0x5c, 0x6a, 0xc2, 0x64, 0x20, 0x18, 0x00, 0x10, 0xbc, 0xd6, 0xca, 0xaa, 0x1c, 0x70, 0x00,
0x10, 0x1c, 0x12, 0x70, 0x9c, 0x92, 0x70, 0x00, 0xe0, 0x18, 0x40, 0x7c, 0xc2, 0x82, 0x3c, 0x00,
//
0x44, 0x42, 0x82, 0xa2, 0x62, 0x04, 0x78, 0x00, 0x7c, 0x38, 0x7c, 0xc2, 0xba, 0x26, 0x3c, 0x00,
0x48, 0xd4, 0x64, 0x64, 0xc4, 0xc4, 0x46, 0x00, 0x7c, 0x30, 0x7c, 0xc2, 0x82, 0x06, 0x3c, 0x00,
0x20, 0xfc, 0x32, 0x62, 0xe2, 0xa2, 0x2c, 0x00, 0x10, 0x30, 0x60, 0x72, 0xd2, 0x92, 0x9c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0a, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x02, 0x00,
};
// set system font
void ngpBiosSYSFONTSET(unsigned char *pt, char trans, char font)
{
int i,j;
unsigned char data, line;
for(i = 0; i < 8*256; i++) {
data = 0;
line = sysfont[i];
for(j = 0; j < 4; j++) {
data = data<<2;
data|= ((line&0x80) ? font : trans);
line = line<<1;
}
pt[1] = data;
data = 0;
for(j = 0; j < 4; j++) {
data = data<<2;
data|= ((line&0x80) ? font : trans);
line = line<<1;
}
pt[0] = data;
pt+= 2;
}
}

22
ngpBios.h Normal file
View File

@ -0,0 +1,22 @@
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
// ngpBios.h: interface for the ngpBios class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_NGPBIOS_H__96457662_3A01_11D4_8645_0050DA4EEEA0__INCLUDED_)
#define AFX_NGPBIOS_H__96457662_3A01_11D4_8645_0050DA4EEEA0__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
void ngpBiosSYSFONTSET(unsigned char *pt, char i, char j);
#endif // !defined(AFX_NGPBIOS_H__96457662_3A01_11D4_8645_0050DA4EEEA0__INCLUDED_)

1369
psp/-menu.cpp Normal file

File diff suppressed because it is too large Load Diff

465
psp/emulate.cpp Normal file
View File

@ -0,0 +1,465 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pspgu.h>
#include <psptypes.h>
#include <psprtc.h>
#include <pspdisplay.h>
#include "emulate.h"
#include "pl_psp.h"
#include "pl_snd.h"
#include "image.h"
#include "video.h"
#include "pl_perf.h"
#include "pl_file.h"
#include "ctrl.h"
#include "pl_util.h"
#include "pl_rewind.h"
#include <pspctrl.h>
#include "StdAfx.h"
#include "state.h"
#include "neopopsound.h"
#include "input.h"
#include "flash.h"
#include "tlcs900h.h"
#include "memory.h"
psp_ctrl_mask_to_index_map_t physical_to_emulated_button_map[] =
{
{ PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER, 16 },
{ PSP_CTRL_START | PSP_CTRL_SELECT, 17 },
{ PSP_CTRL_SELECT | PSP_CTRL_LTRIGGER, 18 },
{ PSP_CTRL_SELECT | PSP_CTRL_RTRIGGER, 19 },
{ PSP_CTRL_ANALUP, 0 }, { PSP_CTRL_ANALDOWN, 1 },
{ PSP_CTRL_ANALLEFT, 2 }, { PSP_CTRL_ANALRIGHT, 3 },
{ PSP_CTRL_UP, 4 }, { PSP_CTRL_DOWN, 5 },
{ PSP_CTRL_LEFT, 6 }, { PSP_CTRL_RIGHT, 7 },
{ PSP_CTRL_SQUARE, 8 }, { PSP_CTRL_CROSS, 9 },
{ PSP_CTRL_CIRCLE, 10 }, { PSP_CTRL_TRIANGLE, 11 },
{ PSP_CTRL_LTRIGGER, 12 }, { PSP_CTRL_RTRIGGER, 13 },
{ PSP_CTRL_SELECT, 14 }, { PSP_CTRL_START, 15 },
{ 0, -1 }
};
PspImage *Screen;
pl_rewind Rewinder;
extern int m_bIsActive;
extern psp_ctrl_map_t current_map;
extern pl_file_path ScreenshotPath;
extern int changeborder;
extern int gameonram;
extern int primerjuego;
extern int customborder;
int borderc;
/*NOTA*/
extern int res2x;
extern PspImage *borderimg;
extern int vertical;
extern int bilinear;
int diferencia;
extern char *bordername;
extern int sinborde;
const char *border_back;
extern int save_name;
static int fondo;
extern int bordernull;
int tmp1;
int tmp2;
/*NOTA*/
static pl_perf_counter FpsCounter;
static int ScreenX, ScreenY, ScreenW, ScreenH;
static int ClearScreen;
static int Rewinding;
static int frames_until_save;
static u32 TicksPerUpdate;
static u64 LastTick;
static u64 CurrentTick;
static u8 RewindEnabled;
static void AudioCallback(pl_snd_sample* buf,
unsigned int samples,
void *userdata);
/* Initialize emulation */
int InitEmulation()
{
if (!(Screen = pspImageCreateVram(256, 152, PSP_IMAGE_16BPP)))
return 0;
Screen->Viewport.Width = 160;
Screen->Viewport.Height = 152;
sound_system_init();
/* Initialize rewinder */
pl_rewind_init(&Rewinder,
state_store_mem,
state_restore_mem,
state_get_size);
pl_snd_set_callback(0, AudioCallback, NULL);
return 1;
}
void graphics_paint()
{
pspVideoBegin();
/* Clear the buffer first, if necessary */
if (ClearScreen >= 0)
{
ClearScreen--;
pspVideoClearScreen();
}
/* Blit screen */
sceGuDisable(GU_BLEND);
pspVideoPutImage(Screen, ScreenX, ScreenY, ScreenW, ScreenH);
/*vertical=0;
Screen->Viewport.Height = 24;
pspVideoPutImage(Screen, ScreenX, 0, ScreenW, 24);
vertical=48;
Screen->Viewport.Height = 136;
pspVideoPutImage(Screen, ScreenX, 24, ScreenW,224);
vertical=136;
Screen->Viewport.Height = 152;
pspVideoPutImage(Screen, ScreenX, 256, ScreenW,16);*/
SceCtrlData pad;
sceCtrlReadBufferPositive(&pad, 1);
if (psp_options.display_mode==SIMPLE_2X){
if (pad.Buttons & PSP_CTRL_START)
{
tmp1 = vertical;
tmp2 = Screen->Viewport.Height;
vertical=0;
//bilinear = 1;
Screen->Viewport.Height = 152;
pspVideoPutImage(Screen, ScreenX, ScreenY, 320, 272);
bilinear = 0;
vertical = tmp1 ;
Screen->Viewport.Height = tmp2;
}}
sceGuEnable(GU_BLEND);
if (fondo<10) {
if (psp_options.border==1) pspVideoPutImage1(borderimg, 0, 0, 480, 272);
else pspVideoPutImage1(borderimg, 0, 0, 0, 0);
fondo++;
}
//sceDisplayWaitVblankStart();
/* Wait if needed
if (psp_options.pvsync == 0) {
if (psp_options.update_freq)
{
do { sceRtcGetCurrentTick(&CurrentTick); }
while (CurrentTick - LastTick < TicksPerUpdate);
LastTick = CurrentTick;
}
}
*/
if (psp_options.pvsync == 1)
{
sceDisplayWaitVblankStart();
}
else {
do { sceRtcGetCurrentTick(&CurrentTick); }
while (CurrentTick - LastTick < TicksPerUpdate);
LastTick = CurrentTick;}
/* Show FPS counter */
if (psp_options.show_fps)
{
static char fps_display[64];
sprintf(fps_display, " %3.02f ", pl_perf_update_counter(&FpsCounter));
int width = pspFontGetTextWidth(&PspStockFont, fps_display);
int height = pspFontGetLineHeight(&PspStockFont);
pspVideoFillRect(SCR_WIDTH - width, 0, SCR_WIDTH, height, PSP_COLOR_BLACK);
pspVideoPrint(&PspStockFont, SCR_WIDTH - width, 0, fps_display, PSP_COLOR_WHITE);
}
pspVideoEnd();
pspVideoSwapBuffers();
}
/* Run emulation */
void RunEmulation()
{
//pl_psp_set_clock_freq(psp_options.clock_freq);
float ratio;
res2x = 0;
/* Recompute screen size/position */
switch (psp_options.display_mode)
{
default:
case DISPLAY_MODE_UNSCALED:
if (borderc==0){
borderimg = pspImageLoadPng("border.png");
borderc=1;
}
fondo=0;
res2x = 0;
bilinear = 0;
ScreenW = Screen->Viewport.Width;
ScreenH = Screen->Viewport.Height;
break;
case DISPLAY_MODE_FIT_HEIGHT:
if (borderc==0){
borderimg = pspImageLoadPng("border.png");
borderc=1;
}
fondo=0;
bilinear = 1;
res2x = 0;
ratio = (float)SCR_HEIGHT / (float)Screen->Viewport.Height;
ScreenW = (int)((float)Screen->Viewport.Width * ratio);
ScreenH = SCR_HEIGHT;
break;
case DISPLAY_MODE_FILL_SCREEN:
if (borderc==0){
borderimg = pspImageLoadPng("border.png");
borderc=1;
}
fondo=20;
bilinear = 1;
ScreenW = SCR_WIDTH;
ScreenH = SCR_HEIGHT;
break;
case SIMPLE_2X:
res2x = 1;
bilinear = 0;
if (borderc==0){
borderimg = pspImageLoadPng("border.png");
borderc=1;
}
fondo=0;
vertical = psp_options.pos_vert;
diferencia = (32 - vertical)/2;
Screen->Viewport.Height = 152-(diferencia);
ScreenW = (SCR_WIDTH/3)*2;
ScreenH = SCR_HEIGHT;
break;
case SIMPLE_W:
if (borderc==0){
borderimg = pspImageLoadPng("border.png");
borderc=1;
}
fondo=20;
res2x = 1;
bilinear = 0;
vertical = psp_options.pos_vert;
diferencia = (32 - vertical)/2;
Screen->Viewport.Height = 152-(diferencia);
ScreenW = SCR_WIDTH;
ScreenH = SCR_HEIGHT;
break;
}
ScreenX = (SCR_WIDTH / 2) - (ScreenW / 2);
ScreenY = (SCR_HEIGHT / 2) - (ScreenH / 2);
/* Initialize performance counter */
pl_perf_init_counter(&FpsCounter);
ClearScreen = 1;
frames_until_save = 0;
Rewinding = 0;
/* Determine if at least 1 button is mapped to 'rewind' */
RewindEnabled = 0;
psp_ctrl_mask_to_index_map_t *current_mapping = physical_to_emulated_button_map;
for (; current_mapping->mask; current_mapping++)
{
u32 code = current_map.button_map[current_mapping->index];
if ((code & SPC) && (CODE_MASK(code) == SPC_REWIND))
{
RewindEnabled = 1; /* Rewind button is mapped */
break;
}
}
/* Recompute update frequency*/
u32 TicksPerSecond = sceRtcGetTickResolution();
if (psp_options.update_freq)
{
TicksPerUpdate = TicksPerSecond
/ (psp_options.update_freq / (psp_options.frame_skip + 1));
sceRtcGetCurrentTick(&LastTick);
}
/* Resume sound */
pl_snd_resume(0);
/* Resume emulation */
m_bIsActive = 1;
ngpc_run();
/* Pause sound */
pl_snd_pause(0);
}
void SetVideoMode()
{
res2x = 0;
Screen->Viewport.Height = 152;
ScreenW = Screen->Viewport.Width;
ScreenH = Screen->Viewport.Height;
ScreenX = (SCR_WIDTH / 2) - (ScreenW / 2);
ScreenY = (SCR_HEIGHT / 2) - (ScreenH / 2);
ClearScreen = 1;
}
void UpdateInputState()
{
ngpInputState = 0;
/* Parse input */
static int autofire_status = 0;
static SceCtrlData pad;
if (pspCtrlPollControls(&pad))
{
if (--autofire_status < 0)
autofire_status = psp_options.autofire;
psp_ctrl_mask_to_index_map_t *current_mapping = physical_to_emulated_button_map;
for (; current_mapping->mask; current_mapping++)
{
u32 code = current_map.button_map[current_mapping->index];
u8 on = (pad.Buttons & current_mapping->mask) == current_mapping->mask;
/* Check to see if a button set is pressed. If so, unset it, so it */
/* doesn't trigger any other combination presses. */
if (on) pad.Buttons &= ~current_mapping->mask;
if (!Rewinding)
{
if (code & AFI)
{
if (on && (autofire_status == 0))
ngpInputState |= CODE_MASK(code);
continue;
}
else if (code & JST)
{
if (on) ngpInputState |= CODE_MASK(code);
continue;
}
}
if (code & SPC)
{
switch (CODE_MASK(code))
{
case SPC_MENU:
if (on) m_bIsActive = 0;
break;
case SPC_REWIND:
Rewinding = on;
break;
}
}
}
}
}
void HandleStateSaving()
{
if (!RewindEnabled)
return;
/* Rewind/save state */
if (!Rewinding)
{
if (--frames_until_save <= 0)
{
frames_until_save = psp_options.rewind_save_rate;
pl_rewind_save(&Rewinder);
}
}
else
{
frames_until_save = psp_options.rewind_save_rate;
pl_rewind_restore(&Rewinder);
}
}
static void AudioCallback(pl_snd_sample* buf,
unsigned int samples,
void *userdata)
{
int length_bytes = samples << 1; /* 2 bytes per sample */
if (!Rewinding)
{
sound_update((_u16*)buf, length_bytes); //Get sound data
dac_update((_u16*)buf, length_bytes);
}
else /* Render silence */
{
memset(buf, 0, length_bytes);
}
}
/* Release emulation resources */
void TrashEmulation()
{
pl_rewind_destroy(&Rewinder);
flashShutdown();
pspImageDestroy(Screen);
}

55
psp/emulate.h Normal file
View File

@ -0,0 +1,55 @@
#ifndef PSP_EMULATE_H
#define PSP_EMULATE_H
int InitEmulation();
void RunEmulation();
void TrashEmulation();
void SetVideoMode();
#define DISPLAY_MODE_UNSCALED 0
#define DISPLAY_MODE_FIT_HEIGHT 1
#define DISPLAY_MODE_FILL_SCREEN 2
#define SIMPLE_2X 3
#define SIMPLE_W 4
#define MAP_BUTTONS 20
#define JST 0x100
#define AFI 0x200
#define SPC 0x400
#define SPC_MENU 1
#define SPC_REWIND 2
#define CODE_MASK(x) (x & 0xff)
typedef struct psp_ctrl_map_t
{
uint32_t button_map[MAP_BUTTONS];
} psp_ctrl_map_t;
typedef struct psp_ctrl_mask_to_index_map_t
{
uint64_t mask;
uint8_t index;
} psp_ctrl_mask_to_index_map_t;
typedef struct psp_options_t
{
uint8_t display_mode;
uint8_t show_fps;
uint8_t frame_skip;
uint16_t clock_freq;
uint8_t autofire;
uint8_t pos_vert;
uint8_t pvsync;
int OF;
uint8_t border;
uint8_t language;
int rewind_save_rate;
uint8_t update_freq;
} psp_options_t;
extern psp_options_t psp_options;
#endif

27
psp/homehookprx/Makefile Normal file
View File

@ -0,0 +1,27 @@
TARGET = homehook
OBJS = main.o sceCtrl_driver.o
INCDIR =
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
BUILD_PRX = 1
PRX_EXPORTS = $(TARGET).exp
USE_KERNEL_LIBC=1
USE_KERNEL_LIBS=1
LIBDIR =
LDFLAGS = -mno-crt0 -nostartfiles
LIBS = -lpspsdk
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
all:
psp-build-exports -s $(PRX_EXPORTS)
@cp $(TARGET).prx ../../
@cp $(TARGET).S ../
@rm -f $(TARGET).prx
@rm -f $(TARGET).S

View File

@ -0,0 +1,16 @@
# Define the exports for the prx
PSP_BEGIN_EXPORTS
# These four lines are mandatory (although you can add other functions like module_stop)
# syslib is a psynonym for the single mandatory export.
PSP_EXPORT_START(syslib, 0, 0x8000)
PSP_EXPORT_FUNC_HASH(module_start)
PSP_EXPORT_VAR_HASH(module_info)
PSP_EXPORT_END
PSP_EXPORT_START(homehook, 0, 0x4001)
PSP_EXPORT_FUNC(initHomeButton)
PSP_EXPORT_FUNC(readHomeButton)
PSP_EXPORT_END
PSP_END_EXPORTS

View File

@ -0,0 +1,21 @@
/******************************************************************************
homehook.prx
******************************************************************************/
#ifndef HOMEHOOK_PRX_H
#define HOMEHOOK_PRX_H
#ifdef __cplusplus
extern "C" {
#endif
void initHomeButton(int devkit_version);
u32 readHomeButton(void);
#ifdef __cplusplus
}
#endif
#endif /* HOMEHOOK_PRX_H */

106
psp/homehookprx/main.c Normal file
View File

@ -0,0 +1,106 @@
/******************************************************************************
homehook371.prx
******************************************************************************/
#include <pspsdk.h>
#include <pspctrl.h>
PSP_MODULE_INFO("homehook", PSP_MODULE_KERNEL, 0, 0);
PSP_MAIN_THREAD_ATTR(0);
/******************************************************************************
prototypes
******************************************************************************/
int sceCtrl_driver_3A622550(SceCtrlData *pad_data, int count);
int sceCtrl_driver_C4AAD55F(SceCtrlData *pad_data, int count);
#define sceCtrlPeekBufferPositive sceCtrl_driver_3A622550
#define sceCtrlPeekBufferPositive371 sceCtrl_driver_C4AAD55F
/******************************************************************************
local variables
******************************************************************************/
static volatile int home_active;
static u32 home_button;
static SceUID home_thread;
static int (*__sceCtrlPeekBufferPositive)(SceCtrlData *pad_data, int count);
/******************************************************************************
functions
******************************************************************************/
static int home_button_thread(SceSize args, void *argp)
{
SceCtrlData paddata;
home_active = 1;
while (home_active)
{
if (__sceCtrlPeekBufferPositive)
{
(*__sceCtrlPeekBufferPositive)(&paddata, 1);
home_button = paddata.Buttons & PSP_CTRL_HOME;
}
sceKernelDelayThread(10 * 1000);
}
sceKernelExitDeleteThread(0);
return 0;
}
void initHomeButton(int devkit_version)
{
if (devkit_version < 0x03060010)
__sceCtrlPeekBufferPositive = sceCtrlPeekBufferPositive;
else
__sceCtrlPeekBufferPositive = sceCtrlPeekBufferPositive371;
}
u32 readHomeButton(void)
{
return home_button;
}
int module_start(SceSize args, void *argp)
{
__sceCtrlPeekBufferPositive = NULL;
home_button = 0;
home_active = 0;
home_thread = sceKernelCreateThread("Home Button Thread",
home_button_thread,
0x11,
0x200,
0,
NULL);
if (home_thread >= 0)
sceKernelStartThread(home_thread, 0, 0);
return 0;
}
int module_stop(void)
{
if (home_thread >= 0)
{
home_active = 0;
sceKernelDelayThread(20 * 1000);
}
return 0;
}

View File

@ -0,0 +1,7 @@
.set noreorder
#include "pspimport.s"
IMPORT_START "sceCtrl_driver",0x00010000
IMPORT_FUNC "sceCtrl_driver",0x3A622550,sceCtrl_driver_3A622550
IMPORT_FUNC "sceCtrl_driver",0xC4AAD55F,sceCtrl_driver_C4AAD55F

51
psp/main.cpp Normal file
View File

@ -0,0 +1,51 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pspkernel.h>
#include "pl_snd.h"
#include "video.h"
#include "pl_psp.h"
#include "ctrl.h"
#include "./menu.h"
PSP_MODULE_INFO(PSP_APP_NAME, 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);
extern int m_bIsActive;
static void ExitCallback(void* arg)
{
m_bIsActive = 0;
ExitPSP = 1;
}
int main(int argc, char **argv)
{
/* Initialize PSP */
pl_psp_init(argv[0]);
pl_snd_init(512, 0);
pspCtrlInit();
pspVideoInit();
/* Initialize callbacks */
pl_psp_register_callback(PSP_EXIT_CALLBACK,
ExitCallback,
NULL);
pl_psp_start_callback_thread();
if (InitMenu())
{
DisplayMenu();
TrashMenu();
}
/* Release PSP resources */
pl_snd_shutdown();
pspVideoShutdown();
pl_psp_shutdown();
return(0);
}

1527
psp/menu.cpp Normal file

File diff suppressed because it is too large Load Diff

8
psp/menu.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef PSP_MENU_H
#define PSP_MENU_H
int InitMenu();
void DisplayMenu();
void TrashMenu();
#endif

674
psp/psplib/COPYING Normal file
View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. 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
them 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 prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. 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.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey 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;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If 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 convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU 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 that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
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.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
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.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
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
state 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) <year> <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 3 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, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program 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, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU 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 Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

102
psp/psplib/Makefile Normal file
View File

@ -0,0 +1,102 @@
## Makefile for psplib library
## Copyright (C) 2008-2009 Akop Karapetyan
## 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 3 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, see <http://www.gnu.org/licenses/>.
## Author contact information: dev@psp.akop.org
ifndef PSP_FW_VERSION
PSP_FW_VERSION=200
endif
CC=psp-gcc
AR=psp-ar
RANLIB=psp-ranlib
RM=rm -rf
PSPSDK=$(shell psp-config --pspsdk-path)
CFLAGS=-G0 -Wall -I$(PSPSDK)/include
DEFINES=-DPSP -D_PSP_FW_VERSION=$(PSP_FW_VERSION)
all: libpsplib.a
libpsplib.a: \
adhoc.o font.o image.o ctrl.o video.o ui.o \
pl_ini.o pl_perf.o pl_vk.o pl_util.o pl_image.o \
pl_psp.o pl_menu.o pl_file.o pl_snd.o pl_gfx.o \
pl_rewind.o
$(AR) cru $@ $?
$(RANLIB) $@
@echo Compiled for firmware $(PSP_FW_VERSION)
clean:
$(RM) *.o genfont stockfont.h *.a
font.o: font.c font.h stockfont.h
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
video.o: video.c video.h
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
ctrl.o: ctrl.c ctrl.h
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
adhoc.o: adhoc.c adhoc.h
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
ui.o: ui.c ui.h pl_file.o pl_psp.o \
ctrl.o font.o pl_menu.o video.o \
adhoc.o
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
pl_snd.o: pl_snd.c pl_snd.h
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
pl_psp.o: pl_psp.c pl_psp.h
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
pl_ini.o: pl_ini.c pl_ini.h
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
pl_vk.o: pl_vk.c pl_vk.h video.o font.o \
ctrl.o
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
pl_util.o: pl_util.c pl_util.h image.o \
pl_file.o video.o
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
pl_perf.o: pl_perf.c pl_perf.h
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
pl_menu.o: pl_menu.c pl_menu.h
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
pl_file.o: pl_file.c pl_file.h
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
pl_image.o: pl_image.c pl_image.h
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
pl_gfx.o: pl_gfx.c pl_gfx.h
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
pl_rewind.o: pl_rewind.c pl_rewind.h
$(CC) $(DEFINES) $(CFLAGS) -O2 -c -o $@ $<
stockfont.h: stockfont.fd genfont
./genfont < $< > $@
genfont: genfont.c
cc $< -o $@

499
psp/psplib/adhoc.c Normal file
View File

@ -0,0 +1,499 @@
/* psplib/adhoc.c
Adhoc Wi-fi matching and communication
Copyright (C) 2007-2008 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: pspdev@akop.org
*/
#include "adhoc.h"
#include <pspnet_adhoc.h>
#include <pspnet_adhocmatching.h>
#include <pspnet_adhocctl.h>
#include <string.h>
#include <stdio.h>
#include <pspkernel.h>
#include <pspsdk.h>
#include <pspwlan.h>
#include <pspnet.h>
#include <psputility_netmodules.h>
#include <psputility_sysparam.h>
#include <psputilsforkernel.h>
#include <malloc.h>
#define ADHOC_TIMEOUT (10 * 1000000)
#define ADHOC_BLOCKSIZE 0x400
int _net_adhoc_ctl_connect = 0;
int _net_adhoc_pdp_create = 0;
int _net_adhoc_matching_start = 0;
int _net_adhoc_matching_create = 0;
int _net_adhoc_matching_init = 0;
int _net_adhoc_ctl_init = 0;
int _net_adhoc_init = 0;
int _net_init = 0;
char _matching_data[128];
int _pdp_id, _matching_id;
PspMAC _own_mac;
int pspAdhocRecvBlockingMAC(void *buffer, int length, PspMAC mac);
int pspAdhocInit(const char *product_name,
PspMatchingCallback callback)
{
/* Shut down adhoc, if currently enabled */
pspAdhocShutdown();
struct productStruct product;
char mac[20];
int err, state = 0;
strncpy(product.product, product_name, 9);
product.unknown = 0;
if (sceUtilityGetSystemParamString(PSP_SYSTEMPARAM_ID_STRING_NICKNAME,
_matching_data, 128) != 0)
return 0;
if ((err = sceNetInit(0x20000, 0x2A, 0x1000, 0x2A, 0x1000)) == 0)
{
_net_init = 1;
if ((err = sceNetAdhocInit()) == 0)
{
_net_adhoc_init = 1;
if ((err = sceNetAdhocctlInit(0x2000, 0x20, &product)) == 0)
{
_net_adhoc_ctl_init = 1;
if ((err = sceNetAdhocctlConnect((void*)"")) == 0)
{
_net_adhoc_ctl_connect = 1;
do
{
if ((err = sceNetAdhocctlGetState(&state)) != 0) break;
sceKernelDelayThread(1000000/60);
} while (state != 1);
/* Get WLAN MAC */
unsigned char own_mac[8];
sceWlanGetEtherAddr(own_mac);
memcpy(_own_mac, own_mac, sizeof(unsigned char) * 6);
if (err == 0)
{
sceWlanGetEtherAddr((unsigned char*)mac);
if ((_pdp_id = sceNetAdhocPdpCreate((unsigned char*)mac, 0x309, 0x400, 0)) > 0)
{
_net_adhoc_pdp_create = 1;
if ((err = sceNetAdhocMatchingInit(0x20000)) == 0)
{
_net_adhoc_matching_init = 1;
_matching_id = sceNetAdhocMatchingCreate(3,
0xa,
0x22b,
0x800,
0x2dc6c0,
0x5b8d80,
3,
0x7a120,
callback);
if (_matching_id >= 0)
{
_net_adhoc_matching_create = 1;
err = sceNetAdhocMatchingStart(_matching_id,
0x10,
0x2000,
0x10,
0x2000,
strlen(_matching_data) + 1,
_matching_data);
if (err == 0)
{
_net_adhoc_matching_start = 1;
/* Everything checked out */
return 1;
}
sceNetAdhocMatchingDelete(_matching_id);
_net_adhoc_matching_create = 0;
}
sceNetAdhocMatchingTerm();
_net_adhoc_matching_init = 0;
}
sceNetAdhocPdpDelete(_pdp_id, 0);
_net_adhoc_pdp_create = 0;
}
}
sceNetAdhocctlDisconnect();
_net_adhoc_ctl_connect = 0;
}
sceNetAdhocctlTerm();
_net_adhoc_ctl_init = 0;
}
sceNetAdhocTerm();
_net_adhoc_init = 0;
}
sceNetTerm();
_net_init = 0;
}
return 0;
}
void pspAdhocCancelTarget(const PspMAC mac)
{
sceNetAdhocMatchingCancelTarget(_matching_id, (unsigned char*)mac);
}
void pspAdhocSelectTarget(const PspMAC mac)
{
sceNetAdhocMatchingSelectTarget(_matching_id, (unsigned char*)mac, 0, 0);
}
int pspAdhocIsMACEqual(const PspMAC mac1, const PspMAC mac2)
{
int i;
for (i = 0; i < 6; i++)
if (mac1[i] != mac2[i])
return 0;
return 1;
}
int pspAdhocShutdown()
{
if (_net_init)
{
if (_net_adhoc_init)
{
if (_net_adhoc_ctl_init)
{
if (_net_adhoc_ctl_connect)
{
if (_net_adhoc_pdp_create)
{
if (_net_adhoc_matching_init)
{
if (_net_adhoc_matching_create)
{
if (_net_adhoc_matching_start)
{
sceNetAdhocMatchingStop(_matching_id);
_net_adhoc_matching_start = 0;
}
sceNetAdhocMatchingDelete(_matching_id);
_net_adhoc_matching_create = 0;
}
sceNetAdhocMatchingTerm();
_net_adhoc_matching_init = 0;
}
sceNetAdhocPdpDelete(_pdp_id, 0);
_net_adhoc_pdp_create = 0;
}
sceNetAdhocctlDisconnect();
_net_adhoc_ctl_connect = 0;
}
sceNetAdhocctlTerm();
_net_adhoc_ctl_init = 0;
}
sceNetAdhocTerm();
_net_adhoc_init = 0;
}
sceNetTerm();
_net_init = 0;
}
return 1;
}
/* Must be called from KERNEL thread */
int pspAdhocLoadDrivers()
{
_net_adhoc_matching_start = 0;
_net_adhoc_matching_create = 0;
_net_adhoc_matching_init = 0;
_net_adhoc_pdp_create = 0;
_net_adhoc_ctl_connect = 0;
_net_adhoc_ctl_init = 0;
_net_adhoc_init = 0;
_net_init = 0;
#if (_PSP_FW_VERSION < 200)
int modID;
modID = pspSdkLoadStartModule("flash0:/kd/ifhandle.prx",
PSP_MEMORY_PARTITION_KERNEL);
if (modID < 0) return modID;
modID = pspSdkLoadStartModule("flash0:/kd/memab.prx",
PSP_MEMORY_PARTITION_KERNEL);
if (modID < 0) return modID;
modID = pspSdkLoadStartModule("flash0:/kd/pspnet_adhoc_auth.prx",
PSP_MEMORY_PARTITION_KERNEL);
if (modID < 0) return modID;
modID = pspSdkLoadStartModule("flash0:/kd/pspnet.prx",
PSP_MEMORY_PARTITION_USER);
if (modID < 0) return modID;
else pspSdkFixupImports(modID);
modID = pspSdkLoadStartModule("flash0:/kd/pspnet_adhoc.prx",
PSP_MEMORY_PARTITION_USER);
if (modID < 0) return modID;
else pspSdkFixupImports(modID);
modID = pspSdkLoadStartModule("flash0:/kd/pspnet_adhocctl.prx",
PSP_MEMORY_PARTITION_USER);
if (modID < 0) return modID;
else pspSdkFixupImports(modID);
modID = pspSdkLoadStartModule("flash0:/kd/pspnet_adhoc_matching.prx",
PSP_MEMORY_PARTITION_USER);
if (modID < 0) return modID;
else pspSdkFixupImports(modID);
sceKernelDcacheWritebackAll();
sceKernelIcacheInvalidateAll();
#else
sceUtilityLoadNetModule(PSP_NET_MODULE_COMMON);
sceUtilityLoadNetModule(PSP_NET_MODULE_ADHOC);
#endif
return 1;
}
int pspAdhocConnect(const PspMAC mac)
{
int err, state = 0;
char temp[64];
char ssid[10];
sceNetEtherNtostr((unsigned char*)mac, temp);
ssid[0] = temp[9];
ssid[1] = temp[10];
ssid[2] = temp[12];
ssid[3] = temp[13];
ssid[4] = temp[15];
ssid[5] = temp[16];
ssid[6] = '\0';
if (_net_adhoc_ctl_connect)
{
if (_net_adhoc_pdp_create)
{
if (_net_adhoc_matching_init)
{
if (_net_adhoc_matching_create)
{
if (_net_adhoc_matching_start)
{
sceNetAdhocMatchingStop(_matching_id);
_net_adhoc_matching_start = 0;
}
sceNetAdhocMatchingDelete(_matching_id);
_net_adhoc_matching_create = 0;
}
sceNetAdhocMatchingTerm();
_net_adhoc_matching_init = 0;
}
sceNetAdhocPdpDelete(_pdp_id, 0);
_net_adhoc_pdp_create = 0;
}
sceNetAdhocctlDisconnect();
_net_adhoc_ctl_connect = 0;
}
do
{
if ((err = sceNetAdhocctlGetState(&state)) != 0) break;
sceKernelDelayThread(1000000/60);
} while (state == 1);
if ((err = sceNetAdhocctlConnect((void*)ssid)) == 0)
{
do
{
if ((err = sceNetAdhocctlGetState(&state)) != 0) break;
sceKernelDelayThread(1000000/60);
} while (state != 1);
if (!err)
{
if ((_pdp_id = sceNetAdhocPdpCreate(_own_mac, 0x309, 0x800, 0)) > 0)
{
if (pspAdhocIsMACEqual(mac, _own_mac))
sceKernelDelayThread(1000000);
return 1;
}
}
if (_net_adhoc_ctl_connect)
{
sceNetAdhocctlDisconnect();
_net_adhoc_ctl_connect = 0;
}
if (state == 1)
{
do
{
if ((err = sceNetAdhocctlGetState(&state)) != 0)
break;
sceKernelDelayThread(1000000/60);
} while (state == 1);
}
}
if (_net_init)
{
if (_net_adhoc_init)
{
if (_net_adhoc_ctl_init)
{
sceNetAdhocctlTerm();
_net_adhoc_ctl_init = 0;
}
sceNetAdhocTerm();
_net_adhoc_init = 0;
}
sceNetTerm();
_net_init = 0;
}
return 0;
}
int pspAdhocGetOwnMAC(PspMAC mac)
{
memcpy(mac, _own_mac, sizeof(unsigned char) * 6);
return 1;
}
int pspAdhocIsWLANEnabled()
{
return sceWlanGetSwitchState();
}
int pspAdhocSendBlocking(const PspMAC mac, const void *buffer, int length)
{
if (sceNetAdhocPdpSend(_pdp_id, (unsigned char*)mac, 0x309,
(void*)buffer, length, ADHOC_TIMEOUT, 0) < 0)
return 0;
return length;
}
int pspAdhocRecvBlockingMAC(void *buffer, int length, PspMAC mac)
{
unsigned short port = 0;
if (sceNetAdhocPdpRecv(_pdp_id, mac, &port, buffer, &length, ADHOC_TIMEOUT, 0) < 0)
return 0;
return length;
}
int pspAdhocRecvBlocking(void *buffer, int length)
{
PspMAC mac;
return pspAdhocRecvBlockingMAC(buffer, length, mac);
}
int pspAdhocSendWithAck(const PspMAC mac, const void *buffer, int length)
{
int ack_data = 0;
int chunk_size = length;
int bytes_sent = 0;
do
{
if (chunk_size > ADHOC_BLOCKSIZE)
chunk_size = ADHOC_BLOCKSIZE;
pspAdhocSendBlocking(mac, buffer, chunk_size);
if (pspAdhocRecvBlocking(&ack_data, sizeof(int)) == 0)
return 0;
if (ack_data != chunk_size)
return 0;
buffer += ADHOC_BLOCKSIZE;
bytes_sent += ADHOC_BLOCKSIZE;
chunk_size = length - bytes_sent;
} while (bytes_sent < length);
return length;
}
int pspAdhocRecvWithAck(void *buffer, int length)
{
int chunk_size = length;
int bytes_rcvd = 0;
PspMAC source_mac;
do
{
if (chunk_size > ADHOC_BLOCKSIZE)
chunk_size = ADHOC_BLOCKSIZE;
if (pspAdhocRecvBlockingMAC(buffer, chunk_size, source_mac) == 0)
return 0;
pspAdhocSendBlocking(source_mac, &chunk_size, sizeof(int));
buffer += ADHOC_BLOCKSIZE;
bytes_rcvd += ADHOC_BLOCKSIZE;
chunk_size = length - bytes_rcvd;
} while (bytes_rcvd < length);
return length;
}
int pspAdhocSendBlob(const PspMAC mac, const void *buffer, int length)
{
if (!pspAdhocSendWithAck(mac, &length, sizeof(int)))
return 0;
if (!pspAdhocSendWithAck(mac, buffer, length))
return 0;
return 1;
}
int pspAdhocRecvBlob(void **buffer, int *length)
{
if (!pspAdhocRecvWithAck(length, sizeof(int)))
return 0;
if (!(*buffer = malloc(*length)))
return 0;
if (!pspAdhocRecvWithAck(*buffer, *length))
{
free(*buffer);
return 0;
}
return 1;
}
int pspAdhocSend(const PspMAC mac, const void *buffer, int length)
{
if (sceNetAdhocPdpSend(_pdp_id, (unsigned char*)mac, 0x309, (void*)buffer, length, 0, 1) < 0)
return 0;
return length;
}
int pspAdhocRecv(void *buffer, int length)
{
unsigned short port = 0;
unsigned char mac[6];
if (sceNetAdhocPdpRecv(_pdp_id, mac, &port, buffer, &length, 0, 1) < 0)
return 0;
return length;
}

63
psp/psplib/adhoc.h Normal file
View File

@ -0,0 +1,63 @@
/* psplib/adhoc.h
Adhoc Wi-fi matching and communication
Copyright (C) 2007-2008 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: pspdev@akop.org
*/
#ifndef _PSP_ADHOC_H
#define _PSP_ADHOC_H
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned char PspMAC[6];
typedef void(*PspMatchingCallback)(int unk1,
int event,
unsigned char *mac2,
int opt_len,
void *opt_data);
int pspAdhocLoadDrivers();
int pspAdhocInit(const char *product_name,
PspMatchingCallback callback);
int pspAdhocConnect(const PspMAC mac);
int pspAdhocShutdown();
void pspAdhocSelectTarget(const PspMAC mac);
void pspAdhocCancelTarget(const PspMAC mac);
int pspAdhocGetOwnMAC(PspMAC mac);
int pspAdhocIsMACEqual(const PspMAC mac1, const PspMAC mac2);
int pspAdhocIsWLANEnabled();
int pspAdhocSend(const PspMAC mac, const void *buffer, int length);
int pspAdhocRecv(void *buffer, int length);
int pspAdhocSendBlocking(const PspMAC mac, const void *buffer, int length);
int pspAdhocRecvBlocking(void *buffer, int length);
int pspAdhocSendWithAck(const PspMAC mac, const void *buffer, int length);
int pspAdhocRecvWithAck(void *buffer, int length);
int pspAdhocRecvBlob(void **buffer, int *length);
int pspAdhocSendBlob(const PspMAC mac, const void *buffer, int length);
#ifdef __cplusplus
}
#endif
#endif /* _PSP_ADHOC_H */

201
psp/psplib/ctrl.c Normal file
View File

@ -0,0 +1,201 @@
/* psplib/ctrl.c
Controller routines
Copyright (C) 2007-2008 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: pspdev@akop.org
*/
#include <time.h>
#include <psptypes.h>
#include <psprtc.h>
#include "ctrl.h"
#define PSP_CTRL_DELAY 400
#define PSP_CTRL_THRESHOLD 50
#define PSP_CTRL_BUTTONS 12
static int PollingMode;
static u64 PushTime[PSP_CTRL_BUTTONS];
static const int ButtonMap[PSP_CTRL_BUTTONS] =
{
PSP_CTRL_UP,
PSP_CTRL_DOWN,
PSP_CTRL_LEFT,
PSP_CTRL_RIGHT,
PSP_CTRL_CROSS,
PSP_CTRL_CIRCLE,
PSP_CTRL_SQUARE,
PSP_CTRL_TRIANGLE,
PSP_CTRL_LTRIGGER,
PSP_CTRL_RTRIGGER,
PSP_CTRL_SELECT,
PSP_CTRL_START,
};
void pspCtrlInit()
{
/* Init PSP controller */
sceCtrlSetSamplingCycle(0);
//sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
PollingMode = PSP_CTRL_NORMAL;
}
int pspCtrlGetPollingMode()
{
return PollingMode;
}
void pspCtrlSetPollingMode(int mode)
{
/* If autorepeat is being shut off, wait until it's "safe" */
if (PollingMode == PSP_CTRL_AUTOREPEAT)
{
int i;
SceCtrlData p;
u64 tick;
int wait;
do
{
wait = 0;
if (!sceCtrlPeekBufferPositive(&p, 1))
break;
/* Get current tick count */
sceRtcGetCurrentTick(&tick);
/* If at least one button is being held, wait until */
/* next autorepeat interval, or until it's released */
for (i = 0; i < PSP_CTRL_BUTTONS; i++)
if (tick < PushTime[i] && (p.Buttons & ButtonMap[i]))
{ wait = 1; break; }
}
while (wait);
}
PollingMode = mode;
/* If autorepeat is being turned on, initialize autorepeat data */
if (mode == PSP_CTRL_AUTOREPEAT)
{
SceCtrlData p;
int i;
u64 tick;
u32 tick_res;
/* Poll the controls */
if (sceCtrlPeekBufferPositive(&p, 1))
{
/* Get current tick count */
sceRtcGetCurrentTick(&tick);
tick_res = sceRtcGetTickResolution();
/* Check each button */
for (i = 0; i < PSP_CTRL_BUTTONS; i++)
PushTime[i] = (p.Buttons & ButtonMap[i]) ? tick + PSP_CTRL_DELAY * (tick_res / 1000) : 0;
}
}
}
int pspCtrlPollControls(SceCtrlData *pad)
{
int stat;
/* Simulate button autorepeat */
if (PollingMode == PSP_CTRL_AUTOREPEAT)
{
SceCtrlData p;
int stat, i;
u64 tick;
u32 tick_res;
/* Poll the controls */
if (!(stat = sceCtrlPeekBufferPositive(&p, 1)))
return stat;
/* Get current tick count */
sceRtcGetCurrentTick(&tick);
tick_res = sceRtcGetTickResolution();
/* Check each button */
for (i = 0; i < PSP_CTRL_BUTTONS; i++)
{
if (p.Buttons & ButtonMap[i])
{
if (!PushTime[i] || tick >= PushTime[i])
{
/* Button was pushed for the first time, or time to repeat */
pad->Buttons |= ButtonMap[i];
/* Compute next press time */
PushTime[i] = tick + ((PushTime[i]) ? PSP_CTRL_THRESHOLD : PSP_CTRL_DELAY)
* (tick_res / 1000);
}
else
{
/* No need to repeat yet */
pad->Buttons &= ~ButtonMap[i];
}
}
else
{
/* Button was released */
pad->Buttons &= ~ButtonMap[i];
PushTime[i] = 0;
}
}
/* Copy analog stick status */
pad->Lx = p.Lx;
pad->Ly = p.Ly;
/* Unset the analog stick bits */
pad->Buttons &= ~(PSP_CTRL_ANALUP
| PSP_CTRL_ANALDOWN
| PSP_CTRL_ANALLEFT
| PSP_CTRL_ANALRIGHT);
/* Set the bits based on analog stick status */
if (pad->Ly < 32) pad->Buttons |= PSP_CTRL_ANALUP;
else if (pad->Ly >= 224) pad->Buttons |= PSP_CTRL_ANALDOWN;
if (pad->Lx < 32) pad->Buttons |= PSP_CTRL_ANALLEFT;
else if (pad->Lx >= 224) pad->Buttons |= PSP_CTRL_ANALRIGHT;
return stat;
}
/* Default is normal behavior */
if (!(stat = sceCtrlPeekBufferPositive(pad, 1)))
return stat;
/* Unset the analog stick bits */
pad->Buttons &= ~(PSP_CTRL_ANALUP
| PSP_CTRL_ANALDOWN
| PSP_CTRL_ANALLEFT
| PSP_CTRL_ANALRIGHT);
/* Set the bits based on analog stick status */
if (pad->Ly < 32) pad->Buttons |= PSP_CTRL_ANALUP;
else if (pad->Ly >= 224) pad->Buttons |= PSP_CTRL_ANALDOWN;
if (pad->Lx < 32) pad->Buttons |= PSP_CTRL_ANALLEFT;
else if (pad->Lx >= 224) pad->Buttons |= PSP_CTRL_ANALRIGHT;
return stat;
}

49
psp/psplib/ctrl.h Normal file
View File

@ -0,0 +1,49 @@
/* psplib/ctrl.h
Controller routines
Copyright (C) 2007-2008 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: pspdev@akop.org
*/
#ifndef _PSP_CTRL_H
#define _PSP_CTRL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <pspctrl.h>
/* These bits are currently unused */
#define PSP_CTRL_ANALUP 0x00000002
#define PSP_CTRL_ANALDOWN 0x00000004
#define PSP_CTRL_ANALLEFT 0x00000400
#define PSP_CTRL_ANALRIGHT 0x00000800
#define PSP_CTRL_NORMAL 0
#define PSP_CTRL_AUTOREPEAT 1
void pspCtrlInit();
int pspCtrlGetPollingMode();
void pspCtrlSetPollingMode(int mode);
int pspCtrlPollControls(SceCtrlData *pad);
#ifdef __cplusplus
}
#endif
#endif // _PSP_FILEIO_H

63
psp/psplib/font.c Normal file
View File

@ -0,0 +1,63 @@
/* psplib/font.c
Rudimentary bitmap font implementation
Copyright (C) 2007-2008 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: pspdev@akop.org
*/
#include "font.h"
#include "stockfont.h"
int pspFontGetLineHeight(const PspFont *font)
{
return font->Height;
}
int pspFontGetTextWidth(const PspFont *font, const char *string)
{
const unsigned char *ch;
int width, max, w;
for (ch = (unsigned char*)string, width = 0, max = 0; *ch; ch++)
{
/* Tab = 4 spaces (TODO) */
if (*ch == '\t') w = font->Chars[(unsigned char)' '].Width * 4;
/* Newline */
else if (*ch == '\n') width = w = 0;
/* Special char */
else if (*ch < 32) w = 0;
/* Normal char */
else w = font->Chars[(unsigned char)(*ch)].Width;
width += w;
if (width > max) max = width;
}
return max;
}
int pspFontGetTextHeight(const PspFont *font, const char *string)
{
const char *ch;
int lines;
for (ch = string, lines = 1; *ch; ch++)
if (*ch == '\n') lines++;
return lines * font->Height;
}

90
psp/psplib/font.h Normal file
View File

@ -0,0 +1,90 @@
/* psplib/font.h
Rudimentary bitmap font implementation
Copyright (C) 2007-2008 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: pspdev@akop.org
*/
#ifndef _PSP_FONT_H
#define _PSP_FONT_H
#ifdef __cplusplus
extern "C" {
#endif
#define PSP_CHAR_ANALUP "\251"
#define PSP_CHAR_ANALDOWN "\252"
#define PSP_CHAR_ANALLEFT "\253"
#define PSP_CHAR_ANALRIGHT "\254"
#define PSP_CHAR_UP "\245"
#define PSP_CHAR_DOWN "\246"
#define PSP_CHAR_LEFT "\247"
#define PSP_CHAR_RIGHT "\250"
#define PSP_CHAR_SQUARE "\244"
#define PSP_CHAR_CROSS "\241"
#define PSP_CHAR_CIRCLE "\242"
#define PSP_CHAR_TRIANGLE "\243"
#define PSP_CHAR_LTRIGGER "\255"
#define PSP_CHAR_RTRIGGER "\256"
#define PSP_CHAR_SELECT "\257\260"
#define PSP_CHAR_START "\261\262"
#define PSP_CHAR_UP_ARROW "\272"
#define PSP_CHAR_DOWN_ARROW "\273"
#define PSP_CHAR_POWER "\267"
#define PSP_CHAR_EMPTY_BATT "\266"
#define PSP_CHAR_FULL_BATT "\263"
#define PSP_CHAR_FLOPPY "\274"
#define PSP_CHAR_MS "\271"
#define PSP_FONT_RESTORE 020
#define PSP_FONT_BLACK 021
#define PSP_FONT_RED 022
#define PSP_FONT_GREEN 023
#define PSP_FONT_BLUE 024
#define PSP_FONT_GRAY 025
#define PSP_FONT_YELLOW 026
#define PSP_FONT_MAGENTA 027
#define PSP_FONT_WHITE 030
struct PspFont
{
unsigned char Height;
unsigned char Ascent;
struct
{
unsigned char Width;
unsigned short *Char;
} Chars[256];
};
typedef struct PspFont PspFont;
extern const PspFont PspStockFont;
int pspFontGetLineHeight(const PspFont *font);
int pspFontGetTextWidth(const PspFont *font, const char *string);
int pspFontGetTextHeight(const PspFont *font, const char *string);
#ifdef __cplusplus
}
#endif
#endif // _PSP_FONT_H

76
psp/psplib/genfont.c Normal file
View File

@ -0,0 +1,76 @@
/* psplib/genfont.c
This file contains a simple font converter. It converts
'fd' format fonts (by Simon Tatham) into array
used by the font rendering library
Copyright (C) 2007-2008 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: pspdev@akop.org
*/
#include <stdio.h>
int main(int argc, char* argv)
{
char line[256];
int widths[256];
int i,j,c;
int ascent = 0;
int height = 0;
int ascii = 0;
int chars = 0;
scanf("height %i\n", &height);
scanf("ascent %i\n", &ascent);
printf("unsigned short _ch[][%i] = {\n", height);
while (!feof(stdin))
{
if (scanf("\nchar %d\n", &ascii) < 1 || chars > 255)
break;
scanf("width %d\n", &widths[chars]);
printf(" { ");
for (i=0;i<height;i++)
{
scanf("%s", line);
c=0;
for (j=widths[chars];j>=0;j--)
if (line[j]=='1')
c|=1<<(widths[chars]-j-1);
printf("0x%04x%s", c, (i<height-1) ? "," : "");
}
printf(" }, /* %i */\n", chars);
chars++;
}
printf("};\n\nconst PspFont PspStockFont = \n{ %i, %i,\n {\n", height, ascent);
for (i = 0; i < 256; i++)
{
if (i % 4 == 0) printf(" ");
printf("{ 0x%02x,_ch[0x%02x] },%s", widths[i], i, (i % 4 == 3) ? "\n" : "");
}
printf(" }\n};\n");
return 0;
}

BIN
psp/psplib/genfont.exe Normal file

Binary file not shown.

587
psp/psplib/image.c Normal file
View File

@ -0,0 +1,587 @@
/* psplib/image.h
Image manipulation/saving/loading
Copyright (C) 2007-2008 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: pspdev@akop.org
*/
#include <malloc.h>
#include <string.h>
#include <png.h>
#include <pspgu.h>
#include "video.h"
#include "image.h"
typedef unsigned char byte;
int FindPowerOfTwoLargerThan(int n);
int FindPowerOfTwoLargerThan2(int n);
/* Creates an image in memory */
PspImage* pspImageCreate(int width, int height, int bpp)
{
if (bpp != PSP_IMAGE_INDEXED && bpp != PSP_IMAGE_16BPP) return NULL;
int size = width * height * (bpp / 8);
void *pixels = memalign(16, size);
if (!pixels) return NULL;
PspImage *image = (PspImage*)malloc(sizeof(PspImage));
if (!image)
{
free(pixels);
return NULL;
}
memset(pixels, 0, size);
image->Width = width;
image->Height = height;
image->Pixels = pixels;
image->Viewport.X = 0;
image->Viewport.Y = 0;
image->Viewport.Width = width;
image->Viewport.Height = height;
int i;
for (i = 1; i < width; i *= 2);
image->PowerOfTwo = (i == width);
image->BytesPerPixel = bpp / 8;
image->FreeBuffer = 1;
image->Depth = bpp;
memset(image->Palette, 0, sizeof(image->Palette));
image->PalSize = (unsigned short)256;
switch (image->Depth)
{
case PSP_IMAGE_INDEXED:
image->TextureFormat = GU_PSM_T8;
break;
case PSP_IMAGE_16BPP:
image->TextureFormat = GU_PSM_5551;
break;
}
return image;
}
/* Creates an image using portion of VRAM */
PspImage* pspImageCreateVram(int width, int height, int bpp)
{
if (bpp != PSP_IMAGE_INDEXED && bpp != PSP_IMAGE_16BPP) return NULL;
int i, size = width * height * (bpp / 8);
void *pixels = pspVideoAllocateVramChunk(size);
if (!pixels) return NULL;
PspImage *image = (PspImage*)malloc(sizeof(PspImage));
if (!image) return NULL;
memset(pixels, 0, size);
image->Width = width;
image->Height = height;
image->Pixels = pixels;
image->Viewport.X = 0;
image->Viewport.Y = 0;
image->Viewport.Width = width;
image->Viewport.Height = height;
for (i = 1; i < width; i *= 2);
image->PowerOfTwo = (i == width);
image->BytesPerPixel = bpp >> 3;
image->FreeBuffer = 0;
image->Depth = bpp;
memset(image->Palette, 0, sizeof(image->Palette));
image->PalSize = (unsigned short)256;
switch (image->Depth)
{
case PSP_IMAGE_INDEXED: image->TextureFormat = GU_PSM_T8; break;
case PSP_IMAGE_16BPP: image->TextureFormat = GU_PSM_5551; break;
}
return image;
}
PspImage* pspImageCreateOptimized(int width, int height, int bpp)
{
PspImage *image = pspImageCreate(FindPowerOfTwoLargerThan(width), height, bpp);
if (image) image->Viewport.Width = width;
return image;
}
/* Destroys image */
void pspImageDestroy(PspImage *image)
{
if (image->FreeBuffer) free(image->Pixels);
free(image);
}
PspImage* pspImageRotate(const PspImage *orig, int angle_cw)
{
PspImage *final;
/* Create image of appropriate size */
switch(angle_cw)
{
case 0:
return pspImageCreateCopy(orig);
case 90:
final = pspImageCreate(orig->Viewport.Height,
orig->Viewport.Width, orig->Depth);
break;
case 180:
final = pspImageCreate(orig->Viewport.Width,
orig->Viewport.Height, orig->Depth);
break;
case 270:
final = pspImageCreate(orig->Viewport.Height,
orig->Viewport.Width, orig->Depth);
break;
default:
return NULL;
}
int i, j, k, di = 0;
int width = final->Width;
int height = final->Height;
int l_shift = orig->BytesPerPixel >> 1;
const unsigned char *source = (unsigned char*)orig->Pixels;
unsigned char *dest = (unsigned char*)final->Pixels;
/* Skip to Y viewport starting point */
source += (orig->Viewport.Y * orig->Width) << l_shift;
/* Copy image contents */
for (i = 0, k = 0; i < orig->Viewport.Height; i++)
{
/* Skip to the start of the X viewport */
source += orig->Viewport.X << l_shift;
for (j = 0; j < orig->Viewport.Width; j++, source += 1 << l_shift, k++)
{
switch(angle_cw)
{
case 90:
di = (width - (k / height) - 1) + (k % height) * width;
break;
case 180:
di = (height - i - 1) * width + (width - j - 1);
break;
case 270:
di = (k / height) + (height - (k % height) - 1) * width;
break;
}
/* Write to destination */
if (orig->Depth == PSP_IMAGE_INDEXED) dest[di] = *source;
else ((unsigned short*)dest)[di] = *(unsigned short*)source; /* 16 bpp */
}
/* Skip to the end of the line */
source += (orig->Width - (orig->Viewport.X + orig->Viewport.Width)) << l_shift;
}
if (orig->Depth == PSP_IMAGE_INDEXED)
{
memcpy(final->Palette, orig->Palette, sizeof(orig->Palette));
final->PalSize = orig->PalSize;
}
return final;
}
/* Creates a half-sized thumbnail of an image */
PspImage* pspImageCreateThumbnail(const PspImage *image)
{
PspImage *thumb;
int i, j, p;
if (!(thumb = pspImageCreate(image->Viewport.Width >> 1,
image->Viewport.Height >> 1, image->Depth)))
return NULL;
int dy = image->Viewport.Y + image->Viewport.Height;
int dx = image->Viewport.X + image->Viewport.Width;
for (i = image->Viewport.Y, p = 0; i < dy; i += 2)
for (j = image->Viewport.X; j < dx; j += 2)
if (image->Depth == PSP_IMAGE_INDEXED)
((unsigned char*)thumb->Pixels)[p++]
= ((unsigned char*)image->Pixels)[(image->Width * i) + j];
else
((unsigned short*)thumb->Pixels)[p++]
= ((unsigned short*)image->Pixels)[(image->Width * i) + j];
if (image->Depth == PSP_IMAGE_INDEXED)
{
memcpy(thumb->Palette, image->Palette, sizeof(image->Palette));
thumb->PalSize = image->PalSize;
}
return thumb;
}
int pspImageDiscardColors(const PspImage *original)
{
if (original->Depth != PSP_IMAGE_16BPP) return 0;
int y, x, gray;
unsigned short *p;
for (y = 0, p = (unsigned short*)original->Pixels; y < original->Height; y++)
for (x = 0; x < original->Width; x++, p++)
{
gray = (RED(*p) * 3 + GREEN(*p) * 4 + BLUE(*p) * 2) / 9;
*p = RGB(gray, gray, gray);
}
return 1;
}
int pspImageBlur(const PspImage *original, PspImage *blurred)
{
if (original->Width != blurred->Width
|| original->Height != blurred->Height
|| original->Depth != blurred->Depth
|| original->Depth != PSP_IMAGE_16BPP) return 0;
int r, g, b, n, i, y, x, dy, dx;
unsigned short p;
for (y = 0, i = 0; y < original->Height; y++)
{
for (x = 0; x < original->Width; x++, i++)
{
r = g = b = n = 0;
for (dy = y - 1; dy <= y + 1; dy++)
{
if (dy < 0 || dy >= original->Height) continue;
for (dx = x - 1; dx <= x + 1; dx++)
{
if (dx < 0 || dx >= original->Width) continue;
p = ((unsigned short*)original->Pixels)[dx + dy * original->Width];
r += RED(p);
g += GREEN(p);
b += BLUE(p);
n++;
}
r /= n;
g /= n;
b /= n;
((unsigned short*)blurred->Pixels)[i] = RGB(r, g, b);
}
}
}
return 1;
}
/* Creates an exact copy of the image */
PspImage* pspImageCreateCopy(const PspImage *image)
{
PspImage *copy;
/* Create image */
if (!(copy = pspImageCreate(image->Width, image->Height, image->Depth)))
return NULL;
/* Copy pixels */
int size = image->Width * image->Height * image->BytesPerPixel;
memcpy(copy->Pixels, image->Pixels, size);
memcpy(&copy->Viewport, &image->Viewport, sizeof(PspViewport));
memcpy(copy->Palette, image->Palette, sizeof(image->Palette));
copy->PalSize = image->PalSize;
return copy;
}
/* Clears an image */
void pspImageClear(PspImage *image, unsigned int color)
{
if (image->Depth == PSP_IMAGE_INDEXED)
{
memset(image->Pixels, color & 0xff, image->Width * image->Height);
}
else if (image->Depth == PSP_IMAGE_16BPP)
{
int i;
unsigned short *pixel = image->Pixels;
for (i = image->Width * image->Height - 1; i >= 0; i--, pixel++)
*pixel = color & 0xffff;
}
}
/* Loads an image from a file */
PspImage* pspImageLoadPng(const char *path)
{
FILE *fp = fopen(path,"rb");
if(!fp) return NULL;
PspImage *image = pspImageLoadPngFd(fp);
fclose(fp);
return image;
}
/* Saves an image to a file */
int pspImageSavePng(const char *path, const PspImage* image)
{
FILE *fp = fopen( path, "wb" );
if (!fp) return 0;
int stat = pspImageSavePngFd(fp, image);
fclose(fp);
return stat;
}
#define IRGB(r,g,b,a) (((((b)>>3)&0x1F)<<10)|((((g)>>3)&0x1F)<<5)|\
(((r)>>3)&0x1F)|(a?0x8000:0))
/* Loads an image from an open file descriptor (16-bit PNG)*/
PspImage* pspImageLoadPngFd(FILE *fp)
{
const size_t nSigSize = 8;
byte signature[nSigSize];
if (fread(signature, sizeof(byte), nSigSize, fp) != nSigSize)
return 0;
if (!png_check_sig(signature, nSigSize))
return 0;
png_struct *pPngStruct = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!pPngStruct)
return 0;
png_info *pPngInfo = png_create_info_struct(pPngStruct);
if(!pPngInfo)
{
png_destroy_read_struct(&pPngStruct, NULL, NULL);
return 0;
}
if (setjmp(pPngStruct->jmpbuf))
{
png_destroy_read_struct(&pPngStruct, NULL, NULL);
return 0;
}
png_init_io(pPngStruct, fp);
png_set_sig_bytes(pPngStruct, nSigSize);
png_read_png(pPngStruct, pPngInfo,
PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING |
PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_BGR , NULL);
png_uint_32 width = pPngInfo->width;
png_uint_32 height = pPngInfo->height;
int color_type = pPngInfo->color_type;
PspImage *image;
int mod_width = FindPowerOfTwoLargerThan2(width);
if (!(image = pspImageCreate(mod_width, height, PSP_IMAGE_16BPP)))
{
png_destroy_read_struct(&pPngStruct, &pPngInfo, NULL);
return 0;
}
image->Viewport.Width = width;
png_byte **pRowTable = pPngInfo->row_pointers;
unsigned int x, y;
byte r, g, b, a;
unsigned short *out = image->Pixels;
for (y=0; y<height; y++)
{
png_byte *pRow = pRowTable[y];
for (x=0; x<width; x++)
{
switch(color_type)
{
case PNG_COLOR_TYPE_GRAY:
r = g = b = *pRow++;
a = 1;
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
r = g = b = pRow[0];
a = pRow[1];
pRow += 2;
break;
case PNG_COLOR_TYPE_RGB:
b = pRow[0];
g = pRow[1];
r = pRow[2];
a = 1;
pRow += 3;
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
b = pRow[0];
g = pRow[1];
r = pRow[2];
a = pRow[3];
pRow += 4;
break;
default:
r = g = b = a = 0;
break;
}
// *out++ = IRGB(r,g,b,a);
*out++ = IRGB(r,g,b,a);
}
out += (mod_width - width);
}
png_destroy_read_struct(&pPngStruct, &pPngInfo, NULL);
return image;
}
/* Saves an image to an open file descriptor (16-bit PNG)*/
int pspImageSavePngFd(FILE *fp, const PspImage* image)
{
unsigned char *bitmap;
int i, j, width, height;
width = image->Viewport.Width;
height = image->Viewport.Height;
if (!(bitmap = (u8*)malloc(sizeof(u8) * width * height * 3)))
return 0;
if (image->Depth == PSP_IMAGE_INDEXED)
{
const unsigned char *pixel;
pixel = (unsigned char*)image->Pixels + (image->Viewport.Y * image->Width);
for (i = 0; i < height; i++)
{
/* Skip to the start of the viewport */
pixel += image->Viewport.X;
for (j = 0; j < width; j++, pixel++)
{
bitmap[i * width * 3 + j * 3 + 0] = RED(image->Palette[*pixel]);
bitmap[i * width * 3 + j * 3 + 1] = GREEN(image->Palette[*pixel]);
bitmap[i * width * 3 + j * 3 + 2] = BLUE(image->Palette[*pixel]);
}
/* Skip to the end of the line */
pixel += image->Width - (image->Viewport.X + width);
}
}
else
{
const unsigned short *pixel;
pixel = (unsigned short*)image->Pixels + (image->Viewport.Y * image->Width);
for (i = 0; i < height; i++)
{
/* Skip to the start of the viewport */
pixel += image->Viewport.X;
for (j = 0; j < width; j++, pixel++)
{
bitmap[i * width * 3 + j * 3 + 0] = RED(*pixel);
bitmap[i * width * 3 + j * 3 + 1] = GREEN(*pixel);
bitmap[i * width * 3 + j * 3 + 2] = BLUE(*pixel);
}
/* Skip to the end of the line */
pixel += image->Width - (image->Viewport.X + width);
}
}
png_struct *pPngStruct = png_create_write_struct( PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL );
if (!pPngStruct)
{
free(bitmap);
return 0;
}
png_info *pPngInfo = png_create_info_struct( pPngStruct );
if (!pPngInfo)
{
png_destroy_write_struct( &pPngStruct, NULL );
free(bitmap);
return 0;
}
png_byte **buf = (png_byte**)malloc(height * sizeof(png_byte*));
if (!buf)
{
png_destroy_write_struct( &pPngStruct, &pPngInfo );
free(bitmap);
return 0;
}
unsigned int y;
for (y = 0; y < height; y++)
buf[y] = (byte*)&bitmap[y * width * 3];
if (setjmp( pPngStruct->jmpbuf ))
{
free(buf);
free(bitmap);
png_destroy_write_struct( &pPngStruct, &pPngInfo );
return 0;
}
png_init_io( pPngStruct, fp );
png_set_IHDR( pPngStruct, pPngInfo, width, height, 8,
PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
png_write_info( pPngStruct, pPngInfo );
png_write_image( pPngStruct, buf );
png_write_end( pPngStruct, pPngInfo );
png_destroy_write_struct( &pPngStruct, &pPngInfo );
free(buf);
free(bitmap);
return 1;
}
int FindPowerOfTwoLargerThan(int n)
{
int i;
for (i = n; i < n; i *= 2);
return i;
}
int FindPowerOfTwoLargerThan2(int n)
{
int i;
for (i = 1; i < n; i *= 2);
return i;
}

81
psp/psplib/image.h Normal file
View File

@ -0,0 +1,81 @@
/* psplib/image.h
Image manipulation/saving/loading
Copyright (C) 2007-2008 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: pspdev@akop.org
*/
#ifndef _PSP_IMAGE_H
#define _PSP_IMAGE_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#define PSP_IMAGE_INDEXED 8
#define PSP_IMAGE_16BPP 16
typedef struct
{
int X;
int Y;
int Width;
int Height;
} PspViewport;
typedef struct
{
int Width;
int Height;
void *Pixels;
PspViewport Viewport;
char FreeBuffer;
char BytesPerPixel;
char Depth;
char PowerOfTwo;
unsigned int TextureFormat;
/* TODO: don't allocate if not necessary */
unsigned short __attribute__((aligned(16))) Palette[256];
unsigned short PalSize;
} PspImage;
/* Create/destroy */
PspImage* pspImageCreate(int width, int height, int bits_per_pixel);
PspImage* pspImageCreateVram(int width, int height, int bits_per_pixel);
PspImage* pspImageCreateOptimized(int width, int height, int bpp);
void pspImageDestroy(PspImage *image);
PspImage* pspImageRotate(const PspImage *orig, int angle_cw);
PspImage* pspImageCreateThumbnail(const PspImage *image);
PspImage* pspImageCreateCopy(const PspImage *image);
void pspImageClear(PspImage *image, unsigned int color);
PspImage* pspImageLoadPng(const char *path);
int pspImageSavePng(const char *path, const PspImage* image);
PspImage* pspImageLoadPngFd(FILE *fp);
int pspImageSavePngFd(FILE *fp, const PspImage* image);
int pspImageBlur(const PspImage *original, PspImage *blurred);
int pspImageDiscardColors(const PspImage *original);
#ifdef __cplusplus
}
#endif
#endif // _PSP_IMAGE_H

BIN
psp/psplib/libpsplib.a Normal file

Binary file not shown.

332
psp/psplib/pl_file.c Normal file
View File

@ -0,0 +1,332 @@
/* psplib/pl_file.c
File and directory query routines
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#include <pspkernel.h>
#include <psptypes.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "pl_file.h"
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
static void
sort_file_list(pl_file_list *list,
int count);
static int
compare_files_by_name(const void *s1,
const void *s2);
static int
mkdir_recursive(const char *path);
void pl_file_get_parent_directory(const char *path,
char *parent,
int length)
{
int pos = strlen(path) - 1,
len;
for (; pos >= 0 && path[pos] == '/'; pos--);
for (; pos >= 0 && path[pos] != '/'; pos--);
if (pos < 0)
{
len = MIN(strlen(path), length - 1);
strncpy(parent, path, len);
parent[len] = '\0';
return;
}
len = MIN(pos + 1, length - 1);
strncpy(parent, path, len);
parent[len] = '\0';
}
const char* pl_file_get_filename(const char *path)
{
const char *filename;
if (!(filename = strrchr(path, '/')))
return path;
return filename + 1;
}
const char* pl_file_get_extension(const char *path)
{
const char *filename = pl_file_get_filename(path);
const char *ext;
if (!(ext = strrchr(filename, '.')))
return filename + strlen(filename);
return ext + 1;
}
int pl_file_rm(const char *path)
{
return sceIoRemove(path) >= 0;
}
/* Returns size of file in bytes or <0 if error */
int pl_file_get_file_size(const char *path)
{
SceIoStat stat;
memset(&stat, 0, sizeof(stat));
if (sceIoGetstat(path, &stat) < 0)
return -1;
return (int)stat.st_size;
}
int pl_file_is_root_directory(const char *path)
{
const char *pos = strchr(path, '/');
return !pos || !(*(pos + 1));
}
int pl_file_exists(const char *path)
{
SceIoStat stat;
return sceIoGetstat(path, &stat) == 0;
}
int pl_file_is_of_type(const char *path,
const char *extension)
{
int fn_len, ext_len;
const char *file_ext;
fn_len = strlen(path);
ext_len = strlen(extension);
/* Filename must be at least 2 chars longer (period + a char) */
if (fn_len < ext_len + 2)
return 0;
file_ext = path + (fn_len - ext_len);
if (*(file_ext - 1) == '.' && strcasecmp(file_ext, extension) == 0)
return 1;
return 0;
}
void pl_file_destroy_file_list(pl_file_list *list)
{
pl_file *file, *next;
for (file = list->files; file; file = next)
{
next = file->next;
free(file->name);
free(file);
}
}
static int mkdir_recursive(const char *path)
{
int exit_status = 1;
SceIoStat stat;
if (sceIoGetstat(path, &stat) == 0)
/* If not a directory, cannot continue; otherwise success */
return (stat.st_attr & FIO_SO_IFDIR);
/* First, try creating its parent directory */
char *slash_pos = strrchr(path, '/');
if (!slash_pos); /* Top level */
else if (slash_pos != path && slash_pos[-1] == ':'); /* Top level */
else
{
char *parent = strdup(path);
parent[slash_pos - path] = '\0';
exit_status = mkdir_recursive(parent);
free(parent);
}
if (exit_status && slash_pos[1] != '\0')
{
if (sceIoMkdir(path, 0777) != 0)
exit_status = 0;
}
return exit_status;
}
int pl_file_mkdir_recursive(const char *path)
{
return mkdir_recursive(path);
}
int pl_file_get_file_list_count(const pl_file_list *list)
{
int count = 0;
pl_file *file;
for (file = list->files; file; file = file->next)
count++;
return count;
}
/* Returns number of files successfully read; negative number if error */
int pl_file_get_file_list(pl_file_list *list,
const char *path,
const char **filter)
{
SceUID fd = sceIoDopen(path);
if (fd < 0) return -1;
SceIoDirent dir;
memset(&dir, 0, sizeof(dir));
pl_file *file, *last = NULL;
list->files = NULL;
const char **pext;
int loop;
int count = 0;
while (sceIoDread(fd, &dir) > 0)
{
if (filter && !(dir.d_stat.st_attr & FIO_SO_IFDIR))
{
/* Loop through the list of allowed extensions and compare */
for (pext = filter, loop = 1; *pext; pext++)
{
if (pl_file_is_of_type(dir.d_name, *pext))
{
loop = 0;
break;
}
}
if (loop) continue;
}
/* Create a new file entry */
if (!(file = (pl_file*)malloc(sizeof(pl_file))))
{
pl_file_destroy_file_list(list);
return -1;
}
file->name = strdup(dir.d_name);
file->next = NULL;
file->attrs = (dir.d_stat.st_attr & FIO_SO_IFDIR)
? PL_FILE_DIRECTORY : 0;
/* Update preceding element */
if (last) last->next = file;
else list->files = file;
last = file;
count++;
}
sceIoDclose(fd);
/* Sort the files by name */
sort_file_list(list, count);
return count;
}
static void sort_file_list(pl_file_list *list,
int count)
{
pl_file **files, *file, **fp;
int i;
if (count < 1)
return;
/* Copy the file entries to an array */
files = (pl_file**)malloc(sizeof(pl_file*) * count);
for (file = list->files, fp = files; file; file = file->next, i++, fp++)
*fp = file;
/* Sort the array */
qsort((void*)files, count, sizeof(pl_file*), compare_files_by_name);
/* Rearrange the file entries in the list */
list->files = files[0];
list->files->next = NULL;
for (i = 1; i < count; i++)
files[i - 1]->next = files[i];
pl_file *last = files[count - 1];
last->next = NULL;
free(files);
}
static int compare_files_by_name(const void *s1, const void *s2)
{
pl_file *f1 = *(pl_file**)s1, *f2 = *(pl_file**)s2;
if ((f1->attrs & PL_FILE_DIRECTORY) == (f2->attrs & PL_FILE_DIRECTORY))
return strcasecmp(f1->name, f2->name);
else if (f1->attrs & PL_FILE_DIRECTORY)
return -1;
else return 1;
}
int pl_file_open_directory(const char *path,
const char *subdir,
char *result,
int result_len)
{
/* This routine should be made more robust */
/* to accept subdirs like ../../ etc... */
int path_len = strlen(path);
int copy_len;
/* Ascend one level */
if (strcmp(subdir, "..") == 0)
{
pl_file_get_parent_directory(path,
result,
result_len);
return 1;
}
else
{
copy_len = MIN(result_len - 1, strlen(subdir) + path_len + 2);
snprintf(result, copy_len, "%s%s/", path, subdir);
result[copy_len] = '\0';
return 1;
}
/* If we're here, then we couldn't figure out final path */
/* Just copy the original path */
copy_len = MIN(result_len - 1, path_len);
strncpy(result, path, copy_len);
result[copy_len] = '\0';
return (strcmp(subdir, ".") == 0);
}
int pl_file_is_directory(const char *path)
{
int len;
if ((len = strlen(path)) < 1)
return 0;
return (path[len - 1] == '/');
}

76
psp/psplib/pl_file.h Normal file
View File

@ -0,0 +1,76 @@
/* psplib/file.h
File and directory query routines
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#ifndef _PL_FILE_H
#define _PL_FILE_H
#ifdef __cplusplus
extern "C" {
#endif
#define PL_FILE_DIRECTORY 0x01
#define PL_FILE_MAX_PATH_LEN 1024
typedef char pl_file_path[PL_FILE_MAX_PATH_LEN];
typedef struct pl_file_t
{
char *name;
unsigned char attrs;
struct pl_file_t *next;
} pl_file;
typedef struct pl_file_list_t
{
struct pl_file_t *files;
} pl_file_list;
void pl_file_get_parent_directory(const char *path,
char *parent,
int length);
const char*
pl_file_get_filename(const char *path);
const char*
pl_file_get_extension(const char *path);
int pl_file_get_file_size(const char *path);
int pl_file_exists(const char *path);
int pl_file_rm(const char *path);
int pl_file_open_directory(const char *path,
const char *subdir,
char *result,
int result_len);
int pl_file_is_directory(const char *path);
int pl_file_is_root_directory(const char *path);
int pl_file_is_of_type(const char *path,
const char *extension);
int pl_file_mkdir_recursive(const char *path);
/* Returns number of files successfully read; <0 if error */
int pl_file_get_file_list(pl_file_list *list,
const char *path,
const char **filter);
void pl_file_destroy_file_list(pl_file_list *list);
int pl_file_get_file_list_count(const pl_file_list *list);
#ifdef __cplusplus
}
#endif
#endif // _PL_FILE_H

221
psp/psplib/pl_gfx.c Normal file
View File

@ -0,0 +1,221 @@
/* psplib/pl_gfx.c
Graphics rendering routines
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#include <pspdisplay.h>
#include <pspkernel.h>
#include <pspgu.h>
#include <math.h>
#include "pl_gfx.h"
#include "pl_image.h"
#define SLICE_SIZE 16
#define BUF_WIDTH 512
#define VRAM_START 0x04000000
#define VRAM_UNCACHED 0x40000000
typedef struct pl_gfx_vertex_t
{
unsigned short u, v;
unsigned short color;
short x, y, z;
} pl_gfx_vertex;
static unsigned int get_bytes_per_pixel(unsigned int format);
static unsigned int get_texture_format(pl_image_format format);
static void *_vram_alloc_ptr = NULL;
static void *_disp_buffer = NULL;
static void *_draw_buffer = NULL;
static void *_depth_buffer = NULL;
static unsigned int _format = 0;
static unsigned int __attribute__((aligned(16))) _disp_list[262144];
static unsigned int get_bytes_per_pixel(unsigned int format)
{
switch (format)
{
case GU_PSM_5650:
case GU_PSM_5551:
case GU_PSM_4444:
return 2;
case GU_PSM_8888:
return 4;
case GU_PSM_T8:
return 1;
default:
return 0;
}
}
static unsigned int get_texture_format(pl_image_format format)
{
switch (format)
{
case pl_image_indexed:
return GU_PSM_T8;
case pl_image_5551:
return GU_PSM_5551;
case pl_image_4444:
return GU_PSM_4444;
default:
return 0;
}
}
int pl_gfx_init(unsigned int format)
{
unsigned int bytes_per_pixel =
get_bytes_per_pixel(format);
unsigned int vram_offset = 0;
if (!bytes_per_pixel) return 0;
_format = 0;
_vram_alloc_ptr = (void*)(VRAM_START|VRAM_UNCACHED|0x00088000);
/* Initialize draw buffer */
int size = bytes_per_pixel * BUF_WIDTH * PL_GFX_SCREEN_HEIGHT;
_draw_buffer = (void*)vram_offset;
vram_offset += size;
/* TODO: bpp was originally 4 instead of 2 here */
_disp_buffer = (void*)vram_offset;
vram_offset += size;
_depth_buffer = (void*)vram_offset;
vram_offset += size;
sceGuInit();
sceGuStart(GU_DIRECT, _disp_list);
sceGuDrawBuffer(format,
_draw_buffer,
BUF_WIDTH);
sceGuDispBuffer(PL_GFX_SCREEN_WIDTH,
PL_GFX_SCREEN_HEIGHT,
_disp_buffer,
BUF_WIDTH);
sceGuDepthBuffer(_depth_buffer,
BUF_WIDTH);
sceGuDisable(GU_TEXTURE_2D);
sceGuOffset(0, 0);
sceGuViewport(PL_GFX_SCREEN_WIDTH/2,
PL_GFX_SCREEN_HEIGHT/2,
PL_GFX_SCREEN_WIDTH,
PL_GFX_SCREEN_HEIGHT);
sceGuDepthRange(0xc350, 0x2710);
sceGuDisable(GU_ALPHA_TEST);
sceGuBlendFunc(GU_ADD,
GU_SRC_ALPHA,
GU_ONE_MINUS_SRC_ALPHA,
0, 0);
sceGuEnable(GU_BLEND);
sceGuDisable(GU_DEPTH_TEST);
sceGuEnable(GU_CULL_FACE);
sceGuDisable(GU_LIGHTING);
sceGuFrontFace(GU_CW);
/* TODO: sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT); */
/* sceGuEnable(GU_SCISSOR_TEST); */
sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
sceGuAmbientColor(0xffffffff);
sceGuFinish();
sceGuSync(0,0);
sceGuDisplay(GU_TRUE);
return 1;
}
void pl_gfx_shutdown()
{
sceGuTerm();
}
void* pl_gfx_vram_alloc(unsigned int bytes)
{
void *ptr = _vram_alloc_ptr;
_vram_alloc_ptr += bytes;
/* Align pointer to 16 bytes */
int rem = (unsigned int)_vram_alloc_ptr & 15;
if (rem != 0)
_vram_alloc_ptr += 16 - rem;
return ptr;
}
void pl_video_put_image(const pl_image *image,
int dx,
int dy,
int dw,
int dh)
{
sceKernelDcacheWritebackAll();
sceGuEnable(GU_TEXTURE_2D);
/* TODO: Rewrite so that any format is rendered */
if (image->format == pl_image_indexed)
{
sceGuClutMode(get_texture_format(image->palette.format),
0, 0xff, 0);
sceGuClutLoad(image->palette.colors >> 3,
image->palette.palette);
}
sceGuTexMode(get_texture_format(image->format),
0, 0, GU_FALSE);
sceGuTexImage(0,
image->line_width,
image->line_width,
image->line_width,
image->bitmap);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
sceGuTexFilter(GU_LINEAR, GU_LINEAR);
pl_gfx_vertex *vertices;
int start, end, sc_end, slsz_scaled;
slsz_scaled = ceil((float)dw * (float)SLICE_SIZE) / (float)image->view.w;
start = image->view.x;
end = image->view.x + image->view.w;
sc_end = dx + dw;
for (; start < end; start += SLICE_SIZE, dx += slsz_scaled)
{
vertices = (pl_gfx_vertex*)sceGuGetMemory(2 * sizeof(pl_gfx_vertex));
vertices[0].u = start;
vertices[0].v = image->view.y;
vertices[1].u = start + SLICE_SIZE;
vertices[1].v = image->view.h + image->view.y;
vertices[0].x = dx; vertices[0].y = dy;
vertices[1].x = dx + slsz_scaled; vertices[1].y = dy + dh;
vertices[0].color
= vertices[1].color
= vertices[0].z
= vertices[1].z = 0;
sceGuDrawArray(GU_SPRITES,
GU_TEXTURE_16BIT|GU_COLOR_5551|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices);
}
sceGuDisable(GU_TEXTURE_2D);
}

41
psp/psplib/pl_gfx.h Normal file
View File

@ -0,0 +1,41 @@
/* psplib/pl_gfx.h
Graphics routines
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#ifndef _PL_GFX_H
#define _PL_GFX_H
#ifdef __cplusplus
extern "C" {
#endif
#define PL_GFX_SCREEN_WIDTH 480
#define PL_GFX_SCREEN_HEIGHT 272
int pl_gfx_init();
void pl_gfx_shutdown();
void* pl_gfx_vram_alloc(unsigned int bytes);
#ifdef __cplusplus
}
#endif
#endif // PL_GFX_H

735
psp/psplib/pl_image.c Normal file
View File

@ -0,0 +1,735 @@
/* psplib/pl_image.h
Image manipulation/saving/loading
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#include <malloc.h>
#include <string.h>
#include <png.h>
#include "pl_image.h"
#include "pl_file.h"
#ifdef PSP
#include "pl_gfx.h"
#endif
static uint get_next_power_of_two(uint n);
static uint get_bitmap_size(const pl_image *image);
int copy_from_void(pl_image_format format,
const void *from,
uint32_t *to);
int copy_to_void(pl_image_format format,
uint32_t from,
void *to);
int pl_image_create(pl_image *image,
uint width,
uint height,
pl_image_format format,
uint8_t flags)
{
uint bytes_per_pixel = pl_image_get_bytes_per_pixel(format);
if (!bytes_per_pixel)
return 0;
/* Allocate memory */
uint line_width = get_next_power_of_two(width);
uint pitch = line_width * bytes_per_pixel;
uint buf_len = pitch * height;
void *buffer = NULL;
#ifdef PSP
if (flags & PL_IMAGE_USE_VRAM) /* use VRAM */
buffer = pl_gfx_vram_alloc(buf_len);
else /* use heap */
#endif
buffer = memalign(16, buf_len);
if (!buffer) return 0;
memset(buffer, 0, buf_len);
/* Init. structure */
image->view.x = image->view.y = 0;
image->view.w = width;
image->view.h = height;
image->height = height;
image->line_width = line_width;
image->pitch = pitch;
image->format = format;
image->flags = flags;
image->bitmap = buffer;
image->palette.palette = NULL;
image->palette.colors = 0;
image->palette.format = 0;
return 1;
}
void pl_image_destroy(pl_image *image)
{
/* Release bitmap */
if (!(image->flags & PL_IMAGE_USE_VRAM))
free(image->bitmap);
/* Release palette */
if (image->palette.palette)
free(image->palette.palette);
}
int pl_image_palettize(pl_image *image,
pl_image_format pal_format,
uint pal_colors)
{
if ((image->format != pl_image_indexed) || /* palette only valid for indexed images */
(pal_colors == 0) || /* need at least 1 color */
(pal_colors & 15) || /* number of colors must be divisible by 16 */
(pal_format == pl_image_indexed)) /* 'indexed' not valid for palette format */
return 0;
/* Allocate pal. space */
uint bytes_per_pixel = pl_image_get_bytes_per_pixel(pal_format);
void *palette;
if (!(palette = memalign(16, bytes_per_pixel * pal_colors)))
return 0;
/* Release current pal. */
if (image->palette.palette)
free(image->palette.palette);
/* Reset image pal. */
image->palette.format = pal_format;
image->palette.colors = pal_colors;
image->palette.palette = palette;
return 1;
}
int pl_image_set_palette_color(pl_image *image,
uint index,
uint32_t color)
{
if (image->format != pl_image_indexed ||
index > image->palette.colors)
return 0;
switch (image->palette.format)
{
case pl_image_4444:
case pl_image_5551:
((uint16_t*)(image->palette.palette))[index] = color & 0xffff;
return 1;
default:
return 0;
}
}
int pl_image_create_duplicate(const pl_image *original,
pl_image *copy)
{
/* create image */
if (!pl_image_create(copy,
original->line_width,
original->height,
original->format,
0)) /* TODO: all but vram flag */
return 0;
/* copy palette */
if (original->palette.palette)
{
if (!pl_image_palettize(copy,
original->palette.format,
original->palette.colors))
{
pl_image_destroy(copy);
return 0;
}
uint pal_size = copy->palette.colors *
pl_image_get_bytes_per_pixel(copy->palette.format);
memcpy(copy->palette.palette,
original->palette.palette,
pal_size);
}
/* copy image */
memcpy(copy->bitmap,
original->bitmap,
get_bitmap_size(copy));
/* copy misc. attributes */
copy->view = original->view;
return 1;
}
int pl_image_compose_color(pl_image_format dest_format,
uint32_t *color,
uint8_t red,
uint8_t green,
uint8_t blue,
uint8_t alpha)
{
switch (dest_format)
{
case pl_image_indexed:
/* TODO: indexed color? */
return 0;
case pl_image_4444:
*color = (((alpha >> 4) & 0x0F) << 12) |
(((blue >> 4) & 0x0F) << 8) |
(((green >> 4) & 0x0F) << 4) |
((red >> 4) & 0x0F);
return 1;
case pl_image_5551:
*color = (((alpha >> 7) & 0x01) << 15) |
(((blue >> 3) & 0x1F) << 10) |
(((green >> 3) & 0x1F) << 5) |
((red >> 3) & 0x1F);
return 1;
default:
return 0;
}
}
int pl_image_split_color(pl_image_format src_format,
const pl_image_palette *src_palette,
uint32_t color,
uint8_t *red,
uint8_t *green,
uint8_t *blue,
uint8_t *alpha)
{
switch (src_format)
{
case pl_image_indexed:
/* Palette's format may not be indexed */
if (src_palette->format == pl_image_indexed)
return 0;
/* Get actual color */
copy_from_void(src_palette->format,
src_palette->palette + color *
pl_image_get_bytes_per_pixel(src_palette->format),
&color);
/* Split color */
return pl_image_split_color(src_palette->format,
NULL,
color,
red,
green,
blue,
alpha);
case pl_image_4444:
*red = (color & 0x0F) * 0xFF/0x0F;
*green = ((color >> 4) & 0x0F) * 0xFF/0x0F;
*blue = ((color >> 8) & 0x0F) * 0xFF/0x0F;
*alpha = ((color >> 12) & 0x0F) * 0xFF/0x0F;
return 1;
case pl_image_5551:
*red = (color & 0x1F) * 0xFF/0x1F;
*green = ((color >> 5) & 0x1F) * 0xFF/0x1F;
*blue = ((color >> 10) & 0x1F) * 0xFF/0x1F;
*alpha = ((color >> 15) & 0x01) * 0xFF/0x01;
return 1;
default:
return 0;
}
}
int pl_image_load_png_stream(pl_image *image,
FILE *stream)
{
/* hardcoded for now */
pl_image_format format = pl_image_5551;
const size_t nSigSize = 8;
uint8_t signature[nSigSize];
if (fread(signature, sizeof(uint8_t), nSigSize, stream) != nSigSize)
return 0;
if (!png_check_sig(signature, nSigSize))
return 0;
png_struct *pPngStruct = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!pPngStruct)
return 0;
png_info *pPngInfo = png_create_info_struct(pPngStruct);
if(!pPngInfo)
{
png_destroy_read_struct(&pPngStruct, NULL, NULL);
return 0;
}
if (setjmp(pPngStruct->jmpbuf))
{
png_destroy_read_struct(&pPngStruct, NULL, NULL);
return 0;
}
png_init_io(pPngStruct, stream);
png_set_sig_bytes(pPngStruct, nSigSize);
png_read_png(pPngStruct, pPngInfo,
PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING |
PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_BGR , NULL);
png_uint_32 width = pPngInfo->width;
png_uint_32 height = pPngInfo->height;
int color_type = pPngInfo->color_type;
if (!pl_image_create(image,
width,
height,
format,
0))
{
png_destroy_read_struct(&pPngStruct, &pPngInfo, NULL);
return 0;
}
png_byte **pRowTable = pPngInfo->row_pointers;
unsigned int x, y;
uint8_t r, g, b, a;
uint32_t color;
int bytes_per_pixel = pl_image_get_bytes_per_pixel(format);
void *line_ptr, *pel_ptr;
for (y = 0, line_ptr = image->bitmap;
y < height;
y++, line_ptr += image->pitch)
{
png_byte *pRow = pRowTable[y];
for (x = 0, pel_ptr = line_ptr;
x < width;
x++, pel_ptr += bytes_per_pixel)
{
switch(color_type)
{
case PNG_COLOR_TYPE_GRAY:
r = g = b = *pRow++;
a = 0xff;
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
r = g = b = pRow[0];
a = pRow[1];
pRow += 2;
break;
case PNG_COLOR_TYPE_RGB:
b = pRow[0];
g = pRow[1];
r = pRow[2];
a = 0xff;
pRow += 3;
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
b = pRow[0];
g = pRow[1];
r = pRow[2];
a = pRow[3];
pRow += 4;
break;
default:
r = g = b = a = 0;
break;
}
pl_image_compose_color(format, &color, r, g, b, a);
copy_to_void(format, color, pel_ptr);
}
}
png_destroy_read_struct(&pPngStruct, &pPngInfo, NULL);
return 1;
}
int pl_image_save_png_stream(const pl_image *image,
FILE *stream)
{
unsigned char *bitmap;
int i, j;
uint8_t r, g, b, a;
int width = image->view.w;
int height = image->view.h;
int bytes_per_pixel = pl_image_get_bytes_per_pixel(image->format);
void *line_ptr, *pel_ptr;
uint32_t color;
if (!(bitmap = (u8*)malloc(sizeof(u8) * width * height * 3)))
return 0;
for (i = 0, line_ptr = image->bitmap + (image->view.y * image->pitch);
i < height;
i++, line_ptr += image->pitch)
{
/* Skip to the start of the viewport */
for (j = 0, pel_ptr = line_ptr + (image->view.x * bytes_per_pixel);
j < width;
j++, pel_ptr += bytes_per_pixel)
{
copy_from_void(image->format, pel_ptr, &color);
pl_image_split_color(image->format,
&image->palette,
color,
&r,&g,&b,&a);
bitmap[i * width * 3 + j * 3 + 0] = r;
bitmap[i * width * 3 + j * 3 + 1] = g;
bitmap[i * width * 3 + j * 3 + 2] = b;
}
}
png_struct *pPngStruct = png_create_write_struct( PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL );
if (!pPngStruct)
{
free(bitmap);
return 0;
}
png_info *pPngInfo = png_create_info_struct( pPngStruct );
if (!pPngInfo)
{
png_destroy_write_struct( &pPngStruct, NULL );
free(bitmap);
return 0;
}
png_byte **buf = (png_byte**)malloc(height * sizeof(png_byte*));
if (!buf)
{
png_destroy_write_struct( &pPngStruct, &pPngInfo );
free(bitmap);
return 0;
}
unsigned int y;
for (y = 0; y < height; y++)
buf[y] = (uint8_t*)&bitmap[y * width * 3];
if (setjmp( pPngStruct->jmpbuf ))
{
free(buf);
free(bitmap);
png_destroy_write_struct( &pPngStruct, &pPngInfo );
return 0;
}
png_init_io( pPngStruct, stream );
png_set_IHDR( pPngStruct, pPngInfo, width, height, 8,
PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
png_write_info( pPngStruct, pPngInfo );
png_write_image( pPngStruct, buf );
png_write_end( pPngStruct, pPngInfo );
png_destroy_write_struct( &pPngStruct, &pPngInfo );
free(buf);
free(bitmap);
return 1;
}
int pl_image_load(pl_image *image,
const char *path)
{
int status = 0;
FILE *stream = NULL;
if (pl_file_is_of_type(path, "png"))
{
if ((stream = fopen(path, "r")))
status = pl_image_load_png_stream(image,
stream);
}
else status = 0;
if (stream) fclose(stream);
return status;
}
int pl_image_save(const pl_image *image,
const char *path)
{
int status = 0;
FILE *stream = NULL;
if (pl_file_is_of_type(path, "png"))
{
if ((stream = fopen(path, "w")))
status = pl_image_save_png_stream(image,
stream);
}
else status = 0;
if (stream) fclose(stream);
return status;
}
int pl_image_clear(pl_image *image,
uint8_t red,
uint8_t green,
uint8_t blue,
uint8_t alpha)
{
uint32_t color;
int x, y;
void *line_ptr, *pel_ptr;
uint bytes_per_pixel = pl_image_get_bytes_per_pixel(image->format);
if (!pl_image_compose_color(image->format,
&color,
red,
green,
blue,
alpha))
return 0;
for (y = 0, line_ptr = image->bitmap;
y < image->height;
y++, line_ptr += image->pitch)
{
for (x = 0, pel_ptr = line_ptr;
x < image->line_width;
x++, pel_ptr += bytes_per_pixel)
{
copy_to_void(image->format,
color,
pel_ptr);
}
}
return 1;
}
int pl_image_create_thumbnail(const pl_image *original,
pl_image *thumb)
{
/* create image */
if (!pl_image_create(thumb,
original->view.w / 2,
original->view.h / 2,
original->format,
0)) /* TODO: all but vram flag */
return 0;
/* copy palette */
if (original->format == pl_image_indexed &&
original->palette.palette)
{
if (!pl_image_palettize(thumb,
original->palette.format,
original->palette.colors))
{
pl_image_destroy(thumb);
return 0;
}
uint pal_size = thumb->palette.colors *
pl_image_get_bytes_per_pixel(thumb->palette.format);
memcpy(thumb->palette.palette,
original->palette.palette,
pal_size);
}
int x, y;
uint32_t color;
uint bytes_per_pixel =
pl_image_get_bytes_per_pixel(original->format);
void *slp = original->bitmap + original->view.y * original->pitch;
void *spp;
void *dlp = thumb->bitmap;
void *dpp;
/* copy bitmap */
for (y = 0;
y < thumb->view.h;
y++, dlp += thumb->pitch, slp += (original->pitch << 1))
{
for (x = 0, dpp = dlp, spp = slp + original->view.x * bytes_per_pixel;
x < thumb->view.w;
x++, dpp += bytes_per_pixel, spp += (bytes_per_pixel << 1))
{
copy_from_void(original->format, spp, &color);
copy_to_void(thumb->format, color, dpp);
}
}
return 1;
}
#if 0
int pl_image_rotate(const pl_image *original,
pl_image *rotated,
int angle_cw)
{
int status = 0;
/* Create image */
switch(angle_cw)
{
case 0: /* just duplicate */
return pl_image_create_duplicate(original,
rotated);
case 90:
case 270:
status = pl_image_create(rotated,
original->view.h,
original->view.w,
original->format,
0);
break;
case 180:
status = pl_image_create(rotated,
original->view.w,
original->view.h,
original->format,
0);
break;
default:
return 0;
}
if (!status) return 0;
/* copy palette */
if (original->format == pl_image_indexed &&
original->palette.palette)
{
if (!pl_image_palettize(rotated,
original->palette.format,
original->palette.colors))
{
pl_image_destroy(rotated);
return 0;
}
uint pal_size = rotated->palette.colors *
pl_image_get_bytes_per_pixel(rotated->palette.format);
memcpy(rotated->palette.palette,
original->palette.palette,
pal_size);
}
int x, y;
uint32_t color;
uint bytes_per_pixel =
pl_image_get_bytes_per_pixel(original->format);
void *slp = original->bitmap + original->view.y * original->pitch;
void *spp, *dpp;
/* copy bitmap */
for (y = 0;
y < original->view.h;
y++, slp += original->pitch)
{
for (x = 0, spp = slp + original->view.x * bytes_per_pixel;
x < original->view.w;
x++, spp += bytes_per_pixel)
{
copy_from_void(original->format, spp, &color);
switch(angle_cw)
{
case 90:
/*
dpp = rotated->bitmap + (rotated->line_width - (k / rotated->height) - 1) *
rotated->pitch;
dpp += (k % rotated->height) * rotated->pitch;
*/
// di = (width - (k / height) - 1) + (k % height) * width;
break;
case 180:
/*
(height - i - 1) * width +
(width - j - 1);
*/
dpp = rotated->bitmap + (rotated->height - y - 1) * rotated->pitch;
dpp += (rotated->line_width - x - 1) * bytes_per_pixel;
break;
case 270:
// di = (k / height) + (height - (k % height) - 1) * width;
break;
}
copy_to_void(rotated->format, color, dpp);
}
}
return 1;
}
#endif
static uint get_next_power_of_two(uint n)
{
uint i;
for (i = 0x10; i < n; i <<= 1);
return i;
}
static uint get_bitmap_size(const pl_image *image)
{
return image->pitch * image->height;
}
int copy_from_void(pl_image_format format,
const void *from,
uint32_t *to)
{
switch (pl_image_get_bytes_per_pixel(format))
{
case 1:
*to = *(uint8_t*)from;
return 1;
case 2:
*to = *(uint16_t*)from;
return 1;
case 4:
*to = *(uint32_t*)from;
default:
return 0;
}
}
int copy_to_void(pl_image_format format,
uint32_t from,
void *to)
{
switch (pl_image_get_bytes_per_pixel(format))
{
case 1:
*(uint8_t*)to = (uint8_t)from;
return 1;
case 2:
*(uint16_t*)to = (uint16_t)from;
return 1;
case 4:
*(uint32_t*)to = (uint32_t)from;
return 1;
default:
return 0;
}
}

139
psp/psplib/pl_image.h Normal file
View File

@ -0,0 +1,139 @@
/* psplib/pl_image.h
Image manipulation/saving/loading
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#ifndef _PL_IMAGE_H
#define _PL_IMAGE_H
#include <stdio.h>
#include <psptypes.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PL_IMAGE_USE_VRAM 0x01
#define uint unsigned int
typedef enum pl_image_format_t
{
pl_image_indexed = 0x01, /* & 0x07 gives */
pl_image_4444 = 0x02, /* bytes per pixel */
pl_image_5551 = 0x12,
} pl_image_format;
typedef struct pl_image_palette_t
{
void *palette;
uint colors;
pl_image_format
format;
} pl_image_palette;
typedef struct pl_image_view_t
{
uint x;
uint y;
uint w;
uint h;
} pl_image_view;
typedef struct pl_image_t
{
pl_image_view
view;
uint height;
uint line_width;
uint pitch;
pl_image_format
format;
pl_image_palette
palette;
uint8_t flags;
void *bitmap;
} pl_image;
int pl_image_create(pl_image *image,
uint width,
uint height,
pl_image_format format,
uint8_t flags);
void pl_image_destroy(pl_image *image);
int pl_image_palettize(pl_image *image,
pl_image_format pal_format,
uint pal_colors);
int pl_image_set_palette_color(pl_image *image,
uint index,
uint32_t color);
uint pl_image_get_depth(const pl_image *image);
int pl_image_compose_color(pl_image_format dest_format,
uint32_t *color,
uint8_t red,
uint8_t green,
uint8_t blue,
uint8_t alpha);
int pl_image_split_color(pl_image_format src_format,
const pl_image_palette *src_palette,
uint32_t color,
uint8_t *red,
uint8_t *green,
uint8_t *blue,
uint8_t *alpha);
int pl_image_load_png_stream(pl_image *image,
FILE *stream);
int pl_image_save_png_stream(const pl_image *image,
FILE *stream);
int pl_image_load(pl_image *image,
const char *path);
int pl_image_save(const pl_image *image,
const char *path);
int pl_image_create_duplicate(const pl_image *original,
pl_image *copy);
int pl_image_create_thumbnail(const pl_image *original,
pl_image *thumb);
#define pl_image_get_bytes_per_pixel(format) \
((format) & 0x07)
int pl_image_clear(pl_image *image,
uint8_t red,
uint8_t green,
uint8_t blue,
uint8_t alpha);
#if 0
int pl_image_rotate(const pl_image *original,
pl_image *rotated,
int angle_cw);
#endif
#undef uint
#ifdef __cplusplus
}
#endif
#endif // _PL_IMAGE_H

373
psp/psplib/pl_ini.c Normal file
View File

@ -0,0 +1,373 @@
/* psplib/pl_ini.h
INI file reading/writing
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#include "pl_ini.h"
#include <string.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#define PL_MAX_LINE_LENGTH 512
typedef struct pl_ini_pair_t
{
char *key;
char *value;
struct pl_ini_pair_t *next;
} pl_ini_pair;
typedef struct pl_ini_section_t
{
char *name;
struct pl_ini_pair_t *head;
struct pl_ini_section_t *next;
} pl_ini_section;
static pl_ini_section* create_section(const char *name);
static pl_ini_pair* create_pair(char *string);
static pl_ini_section* find_section(const pl_ini_file *file,
const char *section_name);
static pl_ini_pair* find_pair(const pl_ini_section *section,
const char *key_name);
static pl_ini_pair* locate(const pl_ini_file *file,
const char *section_name,
const char *key_name);
static pl_ini_pair* locate_or_create(pl_ini_file *file,
const char *section_name,
const char *key_name);
int pl_ini_create(pl_ini_file *file)
{
file->head = NULL;
return 1;
}
int pl_ini_load(pl_ini_file *file,
const char *path)
{
file->head = NULL;
FILE *stream;
if (!(stream = fopen(path, "r")))
return 0;
pl_ini_section *current_section = NULL;
pl_ini_pair *tail;
char string[PL_MAX_LINE_LENGTH],
name[PL_MAX_LINE_LENGTH];
char *ptr;
int len;
/* Create unnamed section */
current_section = NULL;
tail = NULL;
while(!feof(stream) && fgets(string, sizeof(string), stream))
{
/* TODO: Skip whitespace */
/* New section */
if (string[0] == '[')
{
if ((ptr = strrchr(string, ']')))
{
len = ptr - string - 1;
strncpy(name, string + 1, len);
name[len] = '\0';
if (!current_section)
current_section = file->head = create_section(name);
else
{
current_section->next = create_section(name);
current_section = current_section->next;
}
tail = NULL;
}
}
else if (string[0] =='#'); /* Do nothing - comment */
else
{
/* No section defined - create empty section */
if (!current_section)
{
current_section = create_section(strdup(""));
file->head = current_section;
tail = NULL;
}
pl_ini_pair *pair = create_pair(string);
if (pair)
{
if (tail) tail->next = pair;
else current_section->head = pair;
tail = pair;
}
}
}
fclose(stream);
return 1;
}
int pl_ini_save(const pl_ini_file *file,
const char *path)
{
FILE *stream;
if (!(stream = fopen(path, "w")))
return 0;
pl_ini_section *section;
pl_ini_pair *pair;
for (section = file->head; section; section = section->next)
{
fprintf(stream, "[%s]\n", section->name);
for (pair = section->head; pair; pair = pair->next)
fprintf(stream, "%s=%s\n", pair->key, pair->value);
}
fclose(stream);
return 1;
}
int pl_ini_get_int(const pl_ini_file *file,
const char *section,
const char *key,
int default_value)
{
pl_ini_pair *pair = locate(file, section, key);
return (pair) ? atoi(pair->value) : default_value;
}
int pl_ini_get_string(const pl_ini_file *file,
const char *section,
const char *key,
const char *default_value,
char *copy_to,
int dest_len)
{
pl_ini_pair *pair = locate(file, section, key);
if (pair)
{
strncpy(copy_to, pair->value, dest_len);
return 1;
}
else if (default_value)
{
strncpy(copy_to, default_value, dest_len);
return 1;
}
return 0;
}
void pl_ini_set_int(pl_ini_file *file,
const char *section,
const char *key,
int value)
{
pl_ini_pair *pair;
if (!(pair = locate_or_create(file, section, key)))
return;
/* Replace the value */
if (pair->value)
free(pair->value);
char temp[64];
snprintf(temp, 63, "%i", value);
pair->value = strdup(temp);
}
void pl_ini_set_string(pl_ini_file *file,
const char *section,
const char *key,
const char *string)
{
pl_ini_pair *pair;
if (!(pair = locate_or_create(file, section, key)))
return;
/* Replace the value */
if (pair->value)
free(pair->value);
pair->value = strdup(string);
}
void pl_ini_destroy(pl_ini_file *file)
{
pl_ini_section *section, *next_section;
pl_ini_pair *pair, *next_pair;
for (section = file->head; section; section = next_section)
{
next_section = section->next;
if (section->name)
free(section->name);
for (pair = section->head; pair; pair = next_pair)
{
next_pair = pair->next;
if (pair->key)
free(pair->key);
if (pair->value)
free(pair->value);
free(pair);
}
free(section);
}
}
static pl_ini_section* find_section(const pl_ini_file *file,
const char *section_name)
{
pl_ini_section *section;
for (section = file->head; section; section = section->next)
if (strcmp(section_name, section->name) == 0)
return section;
return NULL;
}
static pl_ini_pair* find_pair(const pl_ini_section *section,
const char *key_name)
{
pl_ini_pair *pair;
for (pair = section->head; pair; pair = pair->next)
if (strcmp(pair->key, key_name) == 0)
return pair;
return NULL;
}
static pl_ini_pair* locate(const pl_ini_file *file,
const char *section_name,
const char *key_name)
{
pl_ini_section *section;
if (!(section = find_section(file, section_name)))
return NULL;
return find_pair(section, key_name);
}
static pl_ini_pair* locate_or_create(pl_ini_file *file,
const char *section_name,
const char *key_name)
{
pl_ini_section *section = find_section(file, section_name);
pl_ini_pair *pair = NULL;
if (section)
pair = find_pair(section, key_name);
else
{
/* Create section */
section = create_section(section_name);
if (!file->head)
file->head = section;
else
{
pl_ini_section *s;
for (s = file->head; s->next; s = s->next); /* Find the tail */
s->next = section;
}
}
if (!pair)
{
/* Create pair */
pair = (pl_ini_pair*)malloc(sizeof(pl_ini_pair));
pair->key = strdup(key_name);
pair->value = NULL;
pair->next = NULL;
if (!section->head)
section->head = pair;
else
{
pl_ini_pair *p;
for (p = section->head; p->next; p = p->next); /* Find the tail */
p->next = pair;
}
}
return pair;
}
static pl_ini_section* create_section(const char *name)
{
pl_ini_section *section
= (pl_ini_section*)malloc(sizeof(pl_ini_section));
section->head = NULL;
section->next = NULL;
section->name = strdup(name);
return section;
}
static pl_ini_pair* create_pair(char *string)
{
char *ptr;
if (!(ptr = strchr(string, '=')))
return NULL;
int len;
char *name, *value;
/* Copy NAME */
len = ptr - string;
if (!(name = (char*)malloc(sizeof(char) * (len + 1))))
return NULL;
strncpy(name, string, len);
name[len] = '\0';
/* Copy VALUE */
if (!(value = strdup(ptr + 1)))
{
free(name);
return NULL;
}
len = strlen(value);
if (value[len - 1] == '\n') value[len - 1] = '\0';
/* Create struct */
pl_ini_pair *pair = (pl_ini_pair*)malloc(sizeof(pl_ini_pair));
if (!pair)
{
free(name);
free(value);
return NULL;
}
pair->key = name;
pair->value = value;
pair->next = NULL;
return pair;
}

65
psp/psplib/pl_ini.h Normal file
View File

@ -0,0 +1,65 @@
/* psplib/pl_ini.h
INI file reading/writing
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#ifndef _PL_INI_H
#define _PL_INI_H
#ifdef __cplusplus
extern "C" {
#endif
struct pl_ini_section_t;
typedef struct pl_ini_file_t
{
struct pl_ini_section_t *head;
} pl_ini_file;
int pl_ini_create(pl_ini_file *file);
void pl_ini_destroy(pl_ini_file *file);
int pl_ini_load(pl_ini_file *file,
const char *path);
int pl_ini_save(const pl_ini_file *file,
const char *path);
int pl_ini_get_int(const pl_ini_file *file,
const char *section,
const char *key,
const int default_value);
void pl_ini_set_int(pl_ini_file *file,
const char *section,
const char *key,
int value);
int pl_ini_get_string(const pl_ini_file *file,
const char *section,
const char *key,
const char *default_value,
char *copy_to,
int dest_len);
void pl_ini_set_string(pl_ini_file *file,
const char *section,
const char *key,
const char *string);
#ifdef __cplusplus
}
#endif
#endif // _PL_INI_H

351
psp/psplib/pl_menu.c Normal file
View File

@ -0,0 +1,351 @@
/* psplib/pl_menu.c
Simple menu implementation
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#include <malloc.h>
#include <string.h>
#include "pl_menu.h"
static void
destroy_item(pl_menu_item *item);
static pl_menu_item*
find_last_item(const pl_menu *menu);
static pl_menu_option*
find_last_option(const pl_menu_item *item);
int pl_menu_create(pl_menu *menu,
const pl_menu_def *def)
{
menu->items = NULL;
menu->selected = NULL;
/* No definition; nothing more to do */
if (!def) return 1;
pl_menu_item *item;
/* Initialize menu */
for (; def->id || def->caption; def++)
{
/* Append the item */
item = pl_menu_append_item(menu,
def->id,
def->caption);
if (item)
{
/* Add the options */
if (def->options)
{
const pl_menu_option_def *option_def;
for (option_def = def->options; option_def->text; option_def++)
pl_menu_append_option(item,
option_def->text,
option_def->value, 0);
}
/* Set help text */
item->help_text = (def->help_text)
? strdup(def->help_text) : NULL;
}
}
return 1;
}
void pl_menu_destroy(pl_menu *menu)
{
pl_menu_clear_items(menu);
}
void pl_menu_clear_items(pl_menu *menu)
{
pl_menu_item *item, *next;
for (item = menu->items; item; item = next)
{
next = item->next;
destroy_item(item);
}
menu->items = NULL;
menu->selected = NULL;
}
int pl_menu_remove_item(pl_menu *menu,
pl_menu_item *which)
{
pl_menu_item *item;
int found = 0;
/* Make sure the item is in the menu */
for (item = menu->items; item; item = item->next)
if (item == which)
{ found = 1; break; }
if (!found) return 0;
/* Redirect pointers */
if (item->prev)
item->prev->next = item->next;
else
menu->items = item->next;
if (item->next)
item->next->prev = item->prev;
if (menu->selected == item)
menu->selected = item->next;
/* Destroy the item */
destroy_item(item);
return 1;
}
static void destroy_item(pl_menu_item *item)
{
if (item->caption)
free(item->caption);
if (item->help_text)
free(item->help_text);
pl_menu_clear_options(item);
free(item);
}
void pl_menu_clear_options(pl_menu_item *item)
{
pl_menu_option *option, *next;
for (option = item->options; option; option = next)
{
next = option->next;
free(option->text);
free(option);
}
item->selected = NULL;
item->options = NULL;
}
static pl_menu_item* find_last_item(const pl_menu *menu)
{
if (!menu->items)
return NULL;
pl_menu_item *item;
for (item = menu->items; item->next; item = item->next);
return item;
}
static pl_menu_option* find_last_option(const pl_menu_item *item)
{
if (!item->options)
return NULL;
pl_menu_option *option;
for (option = item->options; option->next; option = option->next);
return option;
}
pl_menu_item* pl_menu_append_item(pl_menu *menu,
unsigned int id,
const char *caption)
{
pl_menu_item* item = (pl_menu_item*)malloc(sizeof(pl_menu_item));
if (!item) return NULL;
if (!caption)
item->caption = NULL;
else
{
if (!(item->caption = strdup(caption)))
{
free(item);
return NULL;
}
}
pl_menu_item *last = find_last_item(menu);
item->help_text = NULL;
item->id = id;
item->param = NULL;
item->options = NULL;
item->selected = NULL;
item->next = NULL;
item->prev = last;
if (last)
last->next = item;
else
menu->items = item;
return item;
}
pl_menu_item* pl_menu_find_item_by_index(const pl_menu *menu,
int index)
{
pl_menu_item *item;
int i = 0;
for (item = menu->items; item; item = item->next, i++)
if (i == index)
return item;
return NULL;
}
pl_menu_item* pl_menu_find_item_by_id(const pl_menu *menu,
unsigned int id)
{
pl_menu_item *item;
for (item = menu->items; item; item = item->next)
if (item->id == id)
return item;
return NULL;
}
int pl_menu_get_item_count(const pl_menu *menu)
{
int i = 0;
pl_menu_item *item = menu->items;
for (; item; item = item->next) i++;
return i;
}
pl_menu_option* pl_menu_append_option(pl_menu_item *item,
const char *text,
const void *value,
int select)
{
pl_menu_option *option;
if (!(option = (pl_menu_option*)malloc(sizeof(pl_menu_option))))
return NULL;
if (!(option->text = strdup(text)))
{
free(option);
return NULL;
}
option->value = value;
option->next = NULL;
if (item->options)
{
pl_menu_option *last = find_last_option(item);
last->next = option;
option->prev = last;
}
else
{
item->options = option;
option->prev = NULL;
}
if (select)
item->selected = option;
return option;
}
pl_menu_option* pl_menu_find_option_by_index(const pl_menu_item *item,
int index)
{
int i;
pl_menu_option *option;
for (i = 0, option = item->options;
option && (i <= index);
i++, option = option->next)
if (i == index)
return option;
return NULL;
}
pl_menu_option* pl_menu_find_option_by_value(const pl_menu_item *item,
const void *value)
{
pl_menu_option *option;
for (option = item->options; option; option = option->next)
if (option->value == value)
return option;
return NULL;
}
pl_menu_option* pl_menu_select_option_by_index(pl_menu_item *item,
int index)
{
pl_menu_option *option = pl_menu_find_option_by_index(item,
index);
if (!option)
return NULL;
return (item->selected = option);
}
pl_menu_option* pl_menu_select_option_by_value(pl_menu_item *item,
const void *value)
{
pl_menu_option *option = pl_menu_find_option_by_value(item,
value);
if (!option)
return NULL;
return (item->selected = option);
}
int pl_menu_update_option(pl_menu_option *option,
const char *text,
const void *value)
{
if (option->text)
free(option->text);
option->text = (text) ? strdup(text) : NULL;
option->value = value;
return (!text || option->text);
}
int pl_menu_set_item_caption(pl_menu_item *item,
const char *caption)
{
if (item->caption)
free(item->caption);
item->caption = (caption) ? strdup(caption) : NULL;
return (!caption || item->caption);
}
int pl_menu_set_item_help_text(pl_menu_item *item,
const char *help_text)
{
if (item->help_text)
free(item->help_text);
item->help_text = (help_text) ? strdup(help_text) : NULL;
return (!help_text || item->help_text);
}

132
psp/psplib/pl_menu.h Normal file
View File

@ -0,0 +1,132 @@
/* psplib/pl_menu.h
Simple menu implementation
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#ifndef _PL_MENU_H
#define _PL_MENU_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct pl_menu_option_t
{
char *text;
const void *value;
struct pl_menu_option_t *prev;
struct pl_menu_option_t *next;
} pl_menu_option;
typedef struct pl_menu_item_t
{
unsigned int id;
char *caption;
char *help_text;
const void *param;
struct pl_menu_option_t *selected;
struct pl_menu_option_t *options;
struct pl_menu_item_t *prev;
struct pl_menu_item_t *next;
} pl_menu_item;
typedef struct pl_menu_t
{
struct pl_menu_item_t *selected;
struct pl_menu_item_t *items;
} pl_menu;
#define PL_MENU_ITEMS_BEGIN(ident) \
pl_menu_def ident[] = {
#define PL_MENU_HEADER(text) \
{0,"\t"text,NULL,NULL},
#define PL_MENU_ITEM(caption,id,option_list,help) \
{id,caption,help,option_list},
#define PL_MENU_ITEMS_END \
{0,NULL,NULL,NULL}};
#define PL_MENU_OPTIONS_BEGIN(ident) \
pl_menu_option_def ident[] = {
#define PL_MENU_OPTION(text,param) \
{text,(const void*)(param)},
#define PL_MENU_OPTIONS_END \
{NULL,NULL}};
typedef struct pl_menu_option_def_t
{
const char *text;
const void *value;
} pl_menu_option_def;
typedef struct pl_menu_def_t
{
unsigned int id;
const char *caption;
const char *help_text;
pl_menu_option_def *options;
} pl_menu_def;
int pl_menu_create(pl_menu *menu,
const pl_menu_def *def);
void pl_menu_destroy(pl_menu *menu);
void pl_menu_clear_items(pl_menu *menu);
pl_menu_item*
pl_menu_append_item(pl_menu *menu,
unsigned int id,
const char *caption);
pl_menu_item*
pl_menu_find_item_by_index(const pl_menu *menu,
int index);
pl_menu_item*
pl_menu_find_item_by_id(const pl_menu *menu,
unsigned int id);
int pl_menu_remove_item(pl_menu *menu,
pl_menu_item *which);
int pl_menu_get_item_count(const pl_menu *menu);
int pl_menu_set_item_caption(pl_menu_item *item,
const char *caption);
int pl_menu_set_item_help_text(pl_menu_item *item,
const char *help_text);
void pl_menu_clear_options(pl_menu_item *item);
pl_menu_option*
pl_menu_append_option(pl_menu_item *item,
const char *text,
const void *value,
int select);
pl_menu_option*
pl_menu_find_option_by_index(const pl_menu_item *item,
int index);
pl_menu_option*
pl_menu_find_option_by_value(const pl_menu_item *item,
const void *value);
pl_menu_option*
pl_menu_select_option_by_index(pl_menu_item *item,
int index);
pl_menu_option*
pl_menu_select_option_by_value(pl_menu_item *item,
const void *value);
int pl_menu_update_option(pl_menu_option *option,
const char *text,
const void *value);
#ifdef __cplusplus
}
#endif
#endif // _PL_MENU_H

52
psp/psplib/pl_perf.c Normal file
View File

@ -0,0 +1,52 @@
/* psplib/pl_perf.c
Performance benchmarking
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#include <pspkernel.h>
#include <psprtc.h>
#include "pl_perf.h"
void pl_perf_init_counter(pl_perf_counter *counter)
{
counter->fps = 0;
counter->frame_count = 0;
counter->ticks_per_second = (float)sceRtcGetTickResolution();
sceRtcGetCurrentTick(&counter->last_tick);
}
float pl_perf_update_counter(pl_perf_counter *counter)
{
u64 current_tick;
sceRtcGetCurrentTick(&current_tick);
counter->frame_count++;
if (current_tick - counter->last_tick >=
counter->ticks_per_second)
{
/* A second elapsed; recompute FPS */
counter->fps = (float)counter->frame_count
/ (float)((current_tick - counter->last_tick) / counter->ticks_per_second);
counter->last_tick = current_tick;
counter->frame_count = 0;
}
return counter->fps;
}

46
psp/psplib/pl_perf.h Normal file
View File

@ -0,0 +1,46 @@
/* psplib/pl_perf.h
Performance benchmarking
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#ifndef _PL_PERF_H
#define _PL_PERF_H
#include <psptypes.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct pl_perf_counter_t
{
float ticks_per_second;
int frame_count;
u64 last_tick;
float fps;
} pl_perf_counter;
void pl_perf_init_counter(pl_perf_counter *counter);
float pl_perf_update_counter(pl_perf_counter *counter);
#ifdef __cplusplus
}
#endif
#endif // _PL_PERF_H

127
psp/psplib/pl_psp.c Normal file
View File

@ -0,0 +1,127 @@
/* psplib/pl_psp.c
Platform init/shutdown and various system routines
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#include <pspkernel.h>
#include <psppower.h>
#include <malloc.h>
#include <string.h>
#include "pl_psp.h"
typedef struct pl_psp_callback_t
{
void (*handler)(void *param);
void *param;
} pl_psp_callback;
static char _app_directory[1024];
static pl_psp_callback _exit_callback;
int ExitPSP;
static int _callback_thread(SceSize args, void* argp);
static int _callback(int arg1, int arg2, void* common);
int pl_psp_init(const char *app_path)
{
ExitPSP = 0;
char *pos;
if (!(pos = strrchr(app_path, '/')))
_app_directory[0] = '\0';
else
{
strncpy(_app_directory, app_path, pos - app_path + 1);
_app_directory[pos - app_path + 1] = '\0';
}
_exit_callback.handler = NULL;
_exit_callback.param = NULL;
return 1;
}
const char* pl_psp_get_app_directory()
{
return _app_directory;
}
void pl_psp_shutdown()
{
sceKernelExitGame();
}
void pl_psp_set_clock_freq(int freq)
{
if (freq < 222) freq = 222;
else if (freq > 333) freq = 333;
scePowerSetClockFrequency(freq, freq, freq/2);
}
static int _callback(int arg1, int arg2, void* common)
{
pl_psp_callback *callback = (pl_psp_callback*)common;
callback->handler(callback->param);
return 0;
}
static int _callback_thread(SceSize args, void* argp)
{
int cbid;
if (_exit_callback.handler)
{
cbid = sceKernelCreateCallback("Exit Callback", _callback, &_exit_callback);
sceKernelRegisterExitCallback(cbid);
}
sceKernelSleepThreadCB();
return 0;
}
int pl_psp_register_callback(pl_callback_type type,
void (*func)(void *param),
void *param)
{
switch (type)
{
case PSP_EXIT_CALLBACK:
_exit_callback.handler = func;
_exit_callback.param = param;
break;
default:
return 0;
}
return 1;
}
int pl_psp_start_callback_thread()
{
int thid;
if ((thid = sceKernelCreateThread("update_thread", _callback_thread, 0x11, 0xFA0, 0, 0)) < 0)
return 0;
sceKernelStartThread(thid, 0, NULL);
return thid;
}

50
psp/psplib/pl_psp.h Normal file
View File

@ -0,0 +1,50 @@
/* psplib/pl_psp.h
Platform init/shutdown and various system routines
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#ifndef _PL_PSP_H
#define _PL_PSP_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
PSP_EXIT_CALLBACK
} pl_callback_type;
extern int ExitPSP;
int pl_psp_init(const char *app_path);
void pl_psp_shutdown();
void pl_psp_set_clock_freq(int freq);
const char* pl_psp_get_app_directory();
int pl_psp_register_callback(pl_callback_type type,
void (*func)(void *param),
void *param);
int pl_psp_start_callback_thread();
#ifdef __cplusplus
}
#endif
#endif // _PL_PSP_H

195
psp/psplib/pl_rewind.c Normal file
View File

@ -0,0 +1,195 @@
/* psplib/pl_rewind.c
State rewinding routines
Copyright (C) 2009 Akop Karapetyan
Based on code by DaveX (efengeler@gmail.com)
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#include <stdlib.h>
#include <stdio.h>
#include "pl_rewind.h"
typedef struct rewind_state
{
void *data;
struct rewind_state *prev;
struct rewind_state *next;
} rewind_state_t;
static int get_free_memory();
int pl_rewind_init(pl_rewind *rewind,
int (*save_state)(void *),
int (*load_state)(void *),
int (*get_state_size)())
{
float memory_needed = (float)get_free_memory() * 0.85;
int state_data_size = get_state_size();
int state_count = (int)(memory_needed
/ (float)(state_data_size + sizeof(rewind_state_t)));
if (state_count < 1)
return 0;
/* First state */
rewind_state_t *prev, *curr = NULL;
if (!(rewind->start = (rewind_state_t*)malloc(sizeof(rewind_state_t))))
return 0;
if (!(rewind->start->data = malloc(state_data_size)))
{
free(rewind->start);
rewind->start = NULL;
return 0;
}
prev = rewind->start;
/* The rest */
int i;
for (i = 1; i < state_count; i++)
{
/* If allocation fails, compose a shorter state chain */
if (!(curr = (rewind_state_t*)malloc(sizeof(rewind_state_t))))
{
state_count = i + 1;
break;
}
/* If allocation fails, compose a shorter state chain */
if (!(curr->data = malloc(state_data_size)))
{
state_count = i + 1;
free(curr);
break;
}
prev->next = curr;
curr->prev = prev;
prev = curr;
}
/* Make circular */
rewind->start->prev = prev;
curr->next = rewind->start;
/* Init structure */
rewind->current = NULL;
rewind->save_state = save_state;
rewind->load_state = load_state;
rewind->get_state_size = get_state_size;
rewind->state_data_size = state_data_size;
rewind->state_count = state_count;
return 1;
}
void pl_rewind_realloc(pl_rewind *rewind)
{
pl_rewind_destroy(rewind);
pl_rewind_init(rewind,
rewind->save_state,
rewind->load_state,
rewind->get_state_size);
}
void pl_rewind_destroy(pl_rewind *rewind)
{
rewind->start->prev->next = NULL; /* Prevent infinite loop */
rewind_state_t *curr, *next;
for (curr = rewind->start; curr; curr = next)
{
next = curr->next;
free(curr->data);
free(curr);
}
rewind->start = NULL;
rewind->current = NULL;
}
void pl_rewind_reset(pl_rewind *rewind)
{
rewind->current = NULL;
}
int pl_rewind_save(pl_rewind *rewind)
{
rewind_state_t *save_slot =
(rewind->current) ? rewind->current->next
: rewind->start;
if (!rewind->save_state(save_slot->data))
return 0;
rewind->current = save_slot;
/* Move starting point forward, if we've reached the start node */
if (save_slot->next == rewind->start)
rewind->start = rewind->start->next;
return 1;
}
int pl_rewind_restore(pl_rewind *rewind)
{
rewind_state_t *load_slot = rewind->current;
if (!(load_slot && rewind->load_state(load_slot->data)))
return 0;
/* Can't go past the starting point */
if (load_slot != rewind->start)
rewind->current = rewind->current->prev;
return 1;
}
static int get_free_memory()
{
const int
chunk_size = 65536, // 64 kB
chunks = 1024; // 65536 * 1024 = 64 MB
void *mem_reserv[chunks];
int total_mem = 0, i;
/* Initialize */
for (i = 0; i < chunks; i++)
mem_reserv[i] = NULL;
/* Allocate */
for (i = 0; i < chunks; i++)
{
if (!(mem_reserv[i] = malloc(chunk_size)))
break;
total_mem += chunk_size;
}
/* Free */
for (i = 0; i < chunks; i++)
{
if (!mem_reserv[i])
break;
free(mem_reserv[i]);
}
return total_mem;
}

57
psp/psplib/pl_rewind.h Normal file
View File

@ -0,0 +1,57 @@
/* psplib/pl_rewind.h
State rewinding routines
Copyright (C) 2009 Akop Karapetyan
Based on code by DaveX (efengeler@gmail.com)
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#ifndef _PL_REWIND_H
#define _PL_REWIND_H
#ifdef __cplusplus
extern "C" {
#endif
struct rewind_state;
typedef struct
{
int state_data_size;
int state_count;
struct rewind_state *start;
struct rewind_state *current;
int (*save_state)(void *);
int (*load_state)(void *);
int (*get_state_size)();
} pl_rewind;
int pl_rewind_init(pl_rewind *rewind,
int (*save_state)(void *),
int (*load_state)(void *),
int (*get_state_size)());
void pl_rewind_realloc(pl_rewind *rewind);
void pl_rewind_destroy(pl_rewind *rewind);
void pl_rewind_reset(pl_rewind *rewind);
int pl_rewind_save(pl_rewind *rewind);
int pl_rewind_restore(pl_rewind *rewind);
#ifdef __cplusplus
}
#endif
#endif // _PL_REWIND_H

328
psp/psplib/pl_snd.c Normal file
View File

@ -0,0 +1,328 @@
/* psplib/pl_snd.c
Simple sound playback library
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#include "pl_snd.h"
#include <stdio.h>
#include <pspaudio.h>
#include <pspthreadman.h>
#include <string.h>
#include <malloc.h>
#define AUDIO_CHANNELS 1
#define DEFAULT_SAMPLES 512
#define VOLUME_MAX 0x8000
static int sound_ready;
static volatile int sound_stop;
typedef struct {
int thread_handle;
int sound_ch_handle;
int left_vol;
int right_vol;
pl_snd_callback callback;
void *user_data;
short *sample_buffer[2];
unsigned int samples[2];
unsigned char paused;
unsigned char stereo;
} pl_snd_channel_info;
static pl_snd_channel_info sound_stream[AUDIO_CHANNELS];
static int channel_thread(int args, void *argp);
static void free_buffers();
static unsigned int get_bytes_per_sample(int channel);
int pl_snd_init(int sample_count,
int stereo)
{
int i, j, failed;
sound_stop = 0;
sound_ready = 0;
/* Check sample count */
if (sample_count <= 0) sample_count = DEFAULT_SAMPLES;
sample_count = PSP_AUDIO_SAMPLE_ALIGN(sample_count);
pl_snd_channel_info *ch_info;
for (i = 0; i < AUDIO_CHANNELS; i++)
{
ch_info = &sound_stream[i];
ch_info->sound_ch_handle = -1;
ch_info->thread_handle = -1;
ch_info->left_vol = VOLUME_MAX;
ch_info->right_vol = VOLUME_MAX;
ch_info->callback = NULL;
ch_info->user_data = NULL;
ch_info->paused = 1;
ch_info->stereo = stereo;
for (j = 0; j < 2; j++)
{
ch_info->sample_buffer[j] = NULL;
ch_info->samples[j] = 0;
}
}
/* Initialize buffers */
for (i = 0; i < AUDIO_CHANNELS; i++)
{
ch_info = &sound_stream[i];
for (j = 0; j < 2; j++)
{
if (!(ch_info->sample_buffer[j] =
(short*)malloc(sample_count * get_bytes_per_sample(i))))
{
free_buffers();
return 0;
}
ch_info->samples[j] = sample_count;
}
}
/* Initialize channels */
for (i = 0, failed = 0; i < AUDIO_CHANNELS; i++)
{
sound_stream[i].sound_ch_handle =
sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL,
sample_count,
(stereo)
? PSP_AUDIO_FORMAT_STEREO
: PSP_AUDIO_FORMAT_MONO);
if (sound_stream[i].sound_ch_handle < 0)
{
failed = 1;
break;
}
}
if (failed)
{
for (i = 0; i < AUDIO_CHANNELS; i++)
{
if (sound_stream[i].sound_ch_handle != -1)
{
sceAudioChRelease(sound_stream[i].sound_ch_handle);
sound_stream[i].sound_ch_handle = -1;
}
}
free_buffers();
return 0;
}
sound_ready = 1;
char label[16];
strcpy(label, "audiotX");
for (i = 0; i < AUDIO_CHANNELS; i++)
{
label[6] = '0' + i;
sound_stream[i].thread_handle =
sceKernelCreateThread(label, (void*)&channel_thread, 0x12, 0x10000,
0, NULL);
if (sound_stream[i].thread_handle < 0)
{
sound_stream[i].thread_handle = -1;
failed = 1;
break;
}
if (sceKernelStartThread(sound_stream[i].thread_handle, sizeof(i), &i) != 0)
{
failed = 1;
break;
}
}
if (failed)
{
sound_stop = 1;
for (i = 0; i < AUDIO_CHANNELS; i++)
{
if (sound_stream[i].thread_handle != -1)
{
//sceKernelWaitThreadEnd(sound_stream[i].threadhandle,NULL);
sceKernelDeleteThread(sound_stream[i].thread_handle);
}
sound_stream[i].thread_handle = -1;
}
sound_ready = 0;
free_buffers();
return 0;
}
return sample_count;
}
void pl_snd_shutdown()
{
int i;
sound_ready = 0;
sound_stop = 1;
for (i = 0; i < AUDIO_CHANNELS; i++)
{
if (sound_stream[i].thread_handle != -1)
{
//sceKernelWaitThreadEnd(sound_stream[i].threadhandle,NULL);
sceKernelDeleteThread(sound_stream[i].thread_handle);
}
sound_stream[i].thread_handle = -1;
}
for (i = 0; i < AUDIO_CHANNELS; i++)
{
if (sound_stream[i].sound_ch_handle != -1)
{
sceAudioChRelease(sound_stream[i].sound_ch_handle);
sound_stream[i].sound_ch_handle = -1;
}
}
free_buffers();
}
static inline int play_blocking(unsigned int channel,
unsigned int vol1,
unsigned int vol2,
void *buf)
{
if (!sound_ready) return -1;
if (channel >= AUDIO_CHANNELS) return -1;
return sceAudioOutputPannedBlocking(sound_stream[channel].sound_ch_handle,
vol1, vol2, buf);
}
static int channel_thread(int args, void *argp)
{
volatile int bufidx = 0;
int channel = *(int*)argp;
int i, j;
unsigned short *ptr_m;
unsigned int *ptr_s;
void *bufptr;
unsigned int samples;
pl_snd_callback callback;
pl_snd_channel_info *ch_info;
ch_info = &sound_stream[channel];
for (j = 0; j < 2; j++)
memset(ch_info->sample_buffer[j], 0,
ch_info->samples[j] * get_bytes_per_sample(channel));
while (!sound_stop)
{
callback = ch_info->callback;
bufptr = ch_info->sample_buffer[bufidx];
samples = ch_info->samples[bufidx];
if (callback && !ch_info->paused)
/* Use callback to fill buffer */
callback(bufptr, samples, ch_info->user_data);
else
{
/* Fill buffer with silence */
if (ch_info->stereo)
for (i = 0, ptr_s = bufptr; i < samples; i++) *(ptr_s++) = 0;
else
for (i = 0, ptr_m = bufptr; i < samples; i++) *(ptr_m++) = 0;
}
/* Play sound */
play_blocking(channel,
ch_info->left_vol,
ch_info->right_vol,
bufptr);
/* Switch active buffer */
bufidx = (bufidx ? 0 : 1);
}
sceKernelExitThread(0);
return 0;
}
static void free_buffers()
{
int i, j;
pl_snd_channel_info *ch_info;
for (i = 0; i < AUDIO_CHANNELS; i++)
{
ch_info = &sound_stream[i];
for (j = 0; j < 2; j++)
{
if (ch_info->sample_buffer[j])
{
free(ch_info->sample_buffer[j]);
ch_info->sample_buffer[j] = NULL;
}
}
}
}
int pl_snd_set_callback(int channel,
pl_snd_callback callback,
void *userdata)
{
if (channel < 0 || channel > AUDIO_CHANNELS)
return 0;
volatile pl_snd_channel_info *pci = &sound_stream[channel];
pci->callback = NULL;
pci->user_data = userdata;
pci->callback = callback;
return 1;
}
static unsigned int get_bytes_per_sample(int channel)
{
return (sound_stream[channel].stereo)
? sizeof(pl_snd_stereo_sample)
: sizeof(pl_snd_mono_sample);
}
int pl_snd_pause(int channel)
{
if (channel < 0 || channel > AUDIO_CHANNELS)
return 0;
sound_stream[channel].paused = 1;
return 1;
}
int pl_snd_resume(int channel)
{
if (channel < 0 || channel > AUDIO_CHANNELS)
return 0;
sound_stream[channel].paused = 0;
return 1;
}

67
psp/psplib/pl_snd.h Normal file
View File

@ -0,0 +1,67 @@
/* psplib/pl_snd.h
Simple sound playback library
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#ifndef _PL_SND_H
#define _PL_SND_H
#ifdef __cplusplus
extern "C" {
#endif
#define PL_SND_ALIGN_SAMPLE(s) (((s) + 63) & ~63)
#define PL_SND_TRUNCATE_SAMPLE(s) ((s) & ~63)
typedef struct pl_snd_stereo_sample_t
{
short l;
short r;
} pl_snd_stereo_sample;
typedef struct pl_snd_mono_sample_t
{
short ch;
} pl_snd_mono_sample;
typedef union pl_snd_sample_t
{
pl_snd_stereo_sample stereo;
pl_snd_mono_sample mono;
} pl_snd_sample;
typedef void (*pl_snd_callback)(pl_snd_sample *buffer,
unsigned int samples,
void *user_data);
int pl_snd_init(int samples,
int stereo);
int pl_snd_set_callback(int channel,
pl_snd_callback callback,
void *userdata);
int pl_snd_pause(int channel);
int pl_snd_resume(int channel);
void pl_snd_shutdown();
#ifdef __cplusplus
}
#endif
#endif // _PL_SND_H

193
psp/psplib/pl_util.c Normal file
View File

@ -0,0 +1,193 @@
/* psplib/pl_util.c
Various utility functions
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#include "pl_util.h"
#include <string.h>
#include <malloc.h>
#include <stdio.h>
#include <pspkernel.h>
#include <psprtc.h>
#include "pl_file.h"
#include "video.h"
#define CRC_BUFFER_SIZE 8192
static uint32_t compute_buffer_crc(uint32_t inCrc32,
const void *buf,
size_t bufLen);
int pl_util_save_image_seq(const char *path,
const char *filename,
const PspImage *image)
{
/* If screenshot path does not exist, create it */
if (!pl_file_exists(path))
if (!pl_file_mkdir_recursive(path))
return 0;
/* Loop until first free screenshot slot is found */
int i = 0;
pl_file_path full_path;
do
{
snprintf(full_path,
sizeof(full_path) - 1,
"%s%s-%02i.png",
path, filename, i);
} while (pl_file_exists(full_path) && ++i < 100);
/* Save the screenshot */
return pspImageSavePng(full_path, image);
}
int pl_util_save_vram_seq(const char *path,
const char *filename)
{
PspImage* vram = pspVideoGetVramBufferCopy();
if (!vram) return 0;
int exit_code = pl_util_save_image_seq(path,
filename,
vram);
pspImageDestroy(vram);
return exit_code;
}
int pl_util_date_compare(const ScePspDateTime *date1,
const ScePspDateTime *date2)
{
if (date1->year != date2->year)
return date1->year - date2->year;
if (date1->month != date2->month)
return date1->month - date2->month;
if (date1->day != date2->day)
return date1->day - date2->day;
if (date1->hour != date2->hour)
return date1->hour - date2->hour;
if (date1->minute != date2->minute)
return date1->minute - date2->minute;
if (date1->second != date2->second)
return date1->second - date2->second;
return 0;
}
int pl_util_compute_crc32_buffer(const void *buf,
size_t buf_len,
uint32_t *crc_32)
{
*crc_32 = compute_buffer_crc(0,
buf,
buf_len);
return 1;
}
int pl_util_compute_crc32_file(const char *path,
uint32_t *outCrc32)
{
FILE *file;
if (!(file = fopen(path, "r")))
return 0;
int status = pl_util_compute_crc32_fd(file, outCrc32);
fclose(file);
return status;
}
int pl_util_compute_crc32_fd(FILE *file,
uint32_t *outCrc32)
{
unsigned char buf[CRC_BUFFER_SIZE];
size_t bufLen;
/** accumulate crc32 from file **/
*outCrc32 = 0;
while (1)
{
if ((bufLen = fread( buf, 1, CRC_BUFFER_SIZE, file )) == 0)
{
if (ferror(file))
return -1;
break;
}
*outCrc32 = compute_buffer_crc(*outCrc32, buf, bufLen);
}
return 0;
}
static uint32_t compute_buffer_crc(uint32_t inCrc32,
const void *buf,
size_t bufLen)
{
static const unsigned long crcTable[256] = {
0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,
0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,
0xE7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,
0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,
0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,0x3B6E20C8,0x4C69105E,0xD56041E4,
0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C,
0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,0x26D930AC,
0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F,
0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,
0xB6662D3D,0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,
0x9FBFE4A5,0xE8B8D433,0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,
0x086D3D2D,0x91646C97,0xE6635C01,0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,
0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,0x8BBEB8EA,
0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,0x4DB26158,0x3AB551CE,
0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB,0x4369E96A,
0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,
0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,
0xCE61E49F,0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,
0xB7BD5C3B,0xC0BA6CAD,0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,
0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,
0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,0xF00F9344,0x8708A3D2,0x1E01F268,
0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,
0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,0xD6D6A3E8,
0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B,
0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,
0x4669BE79,0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,
0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,
0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,
0x9C0906A9,0xEB0E363F,0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,
0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,0x86D3D2D4,0xF1D4E242,
0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,0x88085AE6,
0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45,
0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,
0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,
0x47B2CF7F,0x30B5FFE9,0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,
0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,
0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D };
unsigned long crc32;
unsigned char *byteBuf;
size_t i;
/** accumulate crc32 for buffer **/
crc32 = inCrc32 ^ 0xFFFFFFFF;
byteBuf = (unsigned char*) buf;
for (i=0; i < bufLen; i++)
crc32 = (crc32 >> 8) ^ crcTable[ (crc32 ^ byteBuf[i]) & 0xFF ];
return( crc32 ^ 0xFFFFFFFF );
}

52
psp/psplib/pl_util.h Normal file
View File

@ -0,0 +1,52 @@
/* psplib/pl_util.h
Various utility functions
Copyright (C) 2007-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#ifndef _PL_UTIL_H
#define _PL_UTIL_H
#include <psptypes.h>
#include "image.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Sequential image saves */
int pl_util_save_image_seq(const char *path,
const char *filename,
const PspImage *image);
int pl_util_save_vram_seq(const char *path,
const char *prefix);
int pl_util_date_compare(const ScePspDateTime *date1,
const ScePspDateTime *date2);
int pl_util_compute_crc32_buffer(const void *buf,
size_t buf_len,
uint32_t *crc_32);
int pl_util_compute_crc32_fd(FILE *file,
uint32_t *outCrc32);
int pl_util_compute_crc32_file(const char *path,
uint32_t *outCrc32);
#ifdef __cplusplus
}
#endif
#endif // _PL_UTIL_H

541
psp/psplib/pl_vk.c Normal file
View File

@ -0,0 +1,541 @@
/* psplib/pl_vk.c
Virtual keyboard implementation
Copyright (C) 2008-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#include <time.h>
#include <psptypes.h>
#include <psprtc.h>
#include <malloc.h>
#include <pspgu.h>
#include <string.h>
#include <pspkernel.h>
#include <stdio.h>
#include "video.h"
#include "pl_vk.h"
#define PL_VK_DELAY 400
#define PL_VK_THRESHOLD 50
#define PL_VK_BUTTON_BG COLOR(0x44,0x44,0x44,0x33)
#define PL_VK_LAYOUT_BG COLOR(0,0,0,0x22)
#define PL_VK_STUCK_COLOR COLOR(0xff,0,0,0x33)
#define PL_VK_SELECTED_COLOR COLOR(0xff,0xff,0xff,0x88)
static const int _button_map[] =
{
PSP_CTRL_UP,
PSP_CTRL_DOWN,
PSP_CTRL_LEFT,
PSP_CTRL_RIGHT,
PSP_CTRL_CIRCLE,
PSP_CTRL_TRIANGLE,
0
};
static u64 _push_time[6];
typedef struct pl_vk_button_t
{
uint16_t code;
uint16_t x;
uint16_t y;
uint16_t w;
uint16_t h;
uint8_t is_sticky;
} pl_vk_button;
typedef struct pl_vk_sticky_t
{
uint16_t code;
uint8_t status;
uint16_t *key_index;
uint8_t index_count;
} pl_vk_sticky;
static void filter_repeats(SceCtrlData *pad);
static void render_to_display_list(pl_vk_layout *layout);
int pl_vk_load(pl_vk_layout *layout,
const char *data_path,
const char *image_path,
int(*read_callback)(unsigned int),
void(*write_callback)(unsigned int, int))
{
/* Reset physical button status */
int i;
for (i = 0; _button_map[i]; i++)
_push_time[i] = 0;
/* Initialize */
layout->keys = NULL;
layout->stickies = NULL;
layout->keyb_image = NULL;
layout->key_count = layout->sticky_count =
layout->offset_x = layout->offset_y =
layout->selected = layout->held_down = 0;
/* Load image */
if (image_path && !(layout->keyb_image = pspImageLoadPng(image_path)))
return 0;
/* Init callbacks */
layout->read_callback = read_callback;
layout->write_callback = write_callback;
/* Try opening file */
FILE *file;
if (!(file = fopen(data_path, "r")))
{
pl_vk_destroy(layout);
return 0;
}
int code;
uint16_t x, y, w, h;
/* Determine button count */
while ((fscanf(file, "0x%x\t%hi\t%hi\t%hi\t%hi\n",
&code, &x, &y, &w, &h) == 5) && code)
layout->key_count++;
/* Rewind to start */
rewind(file);
layout->keys = (pl_vk_button*)malloc(layout->key_count *
sizeof(pl_vk_button));
if (!layout->keys)
{
fclose(file);
pl_vk_destroy(layout);
return 0;
}
/* Start reading keys */
pl_vk_button *button;
for (i = 0, button = layout->keys; i < layout->key_count; i++, button++)
{
if (fscanf(file, "0x%x\t%hi\t%hi\t%hi\t%hi\n",
&code, &x, &y, &w, &h) < 5)
{
fclose(file);
pl_vk_destroy(layout);
return 0;
}
button->code = code & 0xffff;
button->x = x;
button->y = y;
button->w = w;
button->h = h;
button->is_sticky = 0;
}
/* "Swallow" last record */
fscanf(file, "0x%x\t%hi\t%hi\t%hi\t%hi\n",
&code, &x, &y, &w, &h);
/* Determine sticky count */
long pos = ftell(file);
while ((fscanf(file, "0x%x\t", &code) == 1) && code)
layout->sticky_count++;
/* Rewind again */
fseek(file, pos, SEEK_SET);
if (layout->sticky_count > 0)
{
layout->stickies = (pl_vk_sticky*)malloc(layout->sticky_count *
sizeof(pl_vk_sticky));
if (!layout->stickies)
{
fclose(file);
pl_vk_destroy(layout);
return 0;
}
/* Start reading stickies */
pl_vk_sticky *sticky;
for (i = 0, sticky = layout->stickies; i < layout->sticky_count; i++, sticky++)
{
if (fscanf(file, "0x%x\t", &code) < 1)
{
fclose(file);
pl_vk_destroy(layout);
return 0;
}
sticky->code = code & 0xffff;
sticky->status = 0;
sticky->index_count = 0;
sticky->key_index = NULL;
int j;
for (j = 0; j < layout->key_count; j++)
{
/* Mark sticky status */
if (layout->keys[j].code == sticky->code)
layout->keys[j].is_sticky = 1;
/* Determine number of matching sticky keys */
if (layout->keys[j].code == sticky->code)
sticky->index_count++;
}
/* Allocate space */
if (sticky->index_count > 0)
{
sticky->key_index = (uint16_t*)malloc(sticky->index_count *
sizeof(uint16_t));
if (!sticky->index_count)
{
fclose(file);
pl_vk_destroy(layout);
return 0;
}
}
/* Save indices */
int count;
for (j = 0, count = 0; j < layout->key_count; j++)
if (layout->keys[j].code == sticky->code)
sticky->key_index[count++] = j;
}
}
/* "Swallow" last record */
fscanf(file, "0x%x\t", &code);
/* Read the offsets */
if (fscanf(file, "%hi\t%hi\n",
&layout->offset_x, &layout->offset_y) < 2)
{
fclose(file);
pl_vk_destroy(layout);
return 0;
}
render_to_display_list(layout);
/* Close the file */
fclose(file);
return 1;
}
static void filter_repeats(SceCtrlData *pad)
{
SceCtrlData p = *pad;
int i;
u64 tick;
u32 tick_res;
/* Get current tick count */
sceRtcGetCurrentTick(&tick);
tick_res = sceRtcGetTickResolution();
/* Check each button */
for (i = 0; i < _button_map[i]; i++)
{
if (p.Buttons & _button_map[i])
{
if (!_push_time[i] || tick >= _push_time[i])
{
/* Button was pushed for the first time, or time to repeat */
pad->Buttons |= _button_map[i];
/* Compute next press time */
_push_time[i] = tick + ((_push_time[i]) ? PL_VK_THRESHOLD : PL_VK_DELAY)
* (tick_res / 1000);
}
else
{
/* No need to repeat yet */
pad->Buttons &= ~_button_map[i];
}
}
else
{
/* Button was released */
pad->Buttons &= ~_button_map[i];
_push_time[i] = 0;
}
}
}
void pl_vk_release_all(pl_vk_layout *layout)
{
/* Release 'held down' key */
if (layout->held_down && layout->write_callback)
{
layout->write_callback(layout->held_down, 0);
layout->held_down = 0;
}
/* Unset all sticky keys */
int i;
pl_vk_sticky *sticky;
for (i = 0, sticky = layout->stickies;
i < layout->sticky_count;
i++, sticky++)
{
sticky->status = 0;
if (layout->write_callback)
layout->write_callback(sticky->code, 0);
}
}
void pl_vk_reinit(pl_vk_layout *layout)
{
int i;
for (i = 0; _button_map[i]; i++)
_push_time[i] = 0;
layout->held_down = 0;
pl_vk_sticky *sticky;
for (i = 0, sticky = layout->stickies; i < layout->sticky_count; i++, sticky++)
sticky->status = (layout->read_callback)
? layout->read_callback(sticky->code) : 0;
}
void pl_vk_navigate(pl_vk_layout *layout,
SceCtrlData *pad)
{
int i;
filter_repeats(pad);
if ((pad->Buttons & PSP_CTRL_SQUARE)
&& layout->write_callback && !layout->held_down)
{
/* Button pressed */
layout->held_down = layout->keys[layout->selected].code;
layout->write_callback(layout->held_down, 1);
/* Unstick if the key is stuck */
if (layout->keys[layout->selected].is_sticky)
{
pl_vk_sticky *sticky;
for (i = 0, sticky = layout->stickies; i < layout->sticky_count; i++, sticky++)
{
/* Active sticky key; toggle status */
if (sticky->status &&
layout->keys[layout->selected].code == sticky->code)
{
sticky->status = !sticky->status;
break;
}
}
}
}
else if (!(pad->Buttons & PSP_CTRL_SQUARE)
&& layout->write_callback && layout->held_down)
{
/* Button released */
layout->write_callback(layout->held_down, 0);
layout->held_down = 0;
}
if (pad->Buttons & PSP_CTRL_RIGHT)
{
if (layout->selected + 1 < layout->key_count
&& layout->keys[layout->selected].y == layout->keys[layout->selected + 1].y)
layout->selected++;
}
else if (pad->Buttons & PSP_CTRL_LEFT)
{
if (layout->selected > 0
&& layout->keys[layout->selected].y == layout->keys[layout->selected - 1].y)
layout->selected--;
}
else if (pad->Buttons & PSP_CTRL_DOWN)
{
/* Find first button on the next row */
for (i = layout->selected + 1;
i < layout->key_count && layout->keys[i].y == layout->keys[layout->selected].y;
i++);
if (i < layout->key_count)
{
/* Find button below the current one */
int r = i;
for (; i < layout->key_count && layout->keys[i].y == layout->keys[r].y; i++)
if (layout->keys[i].x + layout->keys[i].w / 2 >= layout->keys[layout->selected].x + layout->keys[layout->selected].w / 2)
break;
layout->selected = (i < layout->key_count && layout->keys[r].y == layout->keys[i].y)
? i : i - 1;
}
}
else if (pad->Buttons & PSP_CTRL_UP)
{
/* Find first button on the previous row */
for (i = layout->selected - 1;
i >= 0 && layout->keys[i].y == layout->keys[layout->selected].y;
i--);
if (i >= 0)
{
/* Find button above the current one */
int r = i;
for (; i >= 0 && layout->keys[i].y == layout->keys[r].y; i--)
if (layout->keys[i].x + layout->keys[i].w / 2 <=
layout->keys[layout->selected].x + layout->keys[layout->selected].w / 2)
break;
layout->selected = (i >= 0 && layout->keys[r].y == layout->keys[i].y)
? i : i + 1;
}
}
if (layout->write_callback)
{
if (pad->Buttons & PSP_CTRL_CIRCLE &&
layout->keys[layout->selected].is_sticky)
{
pl_vk_sticky *sticky;
for (i = 0, sticky = layout->stickies; i < layout->sticky_count; i++, sticky++)
{
/* Sticky key; toggle status */
if (layout->keys[layout->selected].code == sticky->code)
{
sticky->status = !sticky->status;
layout->write_callback(sticky->code, sticky->status);
break;
}
}
}
else if (pad->Buttons & PSP_CTRL_TRIANGLE)
{
/* Unset all sticky keys */
pl_vk_sticky *sticky;
for (i = 0, sticky = layout->stickies; i < layout->sticky_count; i++, sticky++)
{
sticky->status = 0;
layout->write_callback(sticky->code, 0);
}
}
}
/* Unset used buttons */
for (i = 0; _button_map[i]; i++)
pad->Buttons &= ~_button_map[i];
}
void pl_vk_render(const pl_vk_layout *layout)
{
int off_x, off_y, i, j;
const pl_vk_button *button;
pspVideoCallList(layout->call_list);
off_x = (SCR_WIDTH / 2 - layout->keyb_image->Viewport.Width / 2);
off_y = (SCR_HEIGHT / 2 - layout->keyb_image->Viewport.Height / 2);
if (layout->keyb_image)
pspVideoPutImage(layout->keyb_image,
off_x, off_y,
layout->keyb_image->Viewport.Width,
layout->keyb_image->Viewport.Height);
else
{
/* TODO: render the entire layout */
}
off_x += layout->offset_x;
off_y += layout->offset_y;
/* Highlight sticky buttons */
pl_vk_sticky *sticky;
for (i = 0, sticky = layout->stickies;
i < layout->sticky_count;
i++, sticky++)
{
if (sticky->status)
{
for (j = 0; j < sticky->index_count; j++)
{
button = &(layout->keys[sticky->key_index[j]]);
pspVideoFillRect(off_x + button->x + 1,
off_y + button->y + 1,
off_x + button->x + button->w,
off_y + button->y + button->h,
PL_VK_STUCK_COLOR);
}
}
}
/* Highlight selected button */
button = &(layout->keys[layout->selected]);
pspVideoFillRect(off_x + button->x + 1,
off_y + button->y + 1,
off_x + button->x + button->w,
off_y + button->y + button->h,
PL_VK_SELECTED_COLOR);
}
void pl_vk_destroy(pl_vk_layout *layout)
{
/* Destroy sticky keys */
if (layout->stickies)
{
int i;
pl_vk_sticky *sticky;
for (i = 0, sticky = layout->stickies; i < layout->sticky_count; i++, sticky++)
free(sticky->key_index);
free(layout->stickies);
}
if (layout->keys)
free(layout->keys);
if (layout->keyb_image)
pspImageDestroy(layout->keyb_image);
}
static void render_to_display_list(pl_vk_layout *layout)
{
/* Render the virtual keyboard to a call list */
memset(layout->call_list, 0, sizeof(layout->call_list));
sceGuStart(GU_CALL, layout->call_list);
const pl_vk_button *button;
int off_x, off_y;
int i;
off_x = (SCR_WIDTH / 2 - layout->keyb_image->Viewport.Width / 2);
off_y = (SCR_HEIGHT / 2 - layout->keyb_image->Viewport.Height / 2);
pspVideoFillRect(off_x,
off_y,
off_x + layout->keyb_image->Viewport.Width + 1,
off_y + layout->keyb_image->Viewport.Height + 1,
PL_VK_LAYOUT_BG);
off_x += layout->offset_x;
off_y += layout->offset_y;
for (i = 0, button = layout->keys; i < layout->key_count; i++, button++)
pspVideoFillRect(off_x + button->x,
off_y + button->y,
off_x + button->x + button->w + 1,
off_y + button->y + button->h + 1,
PL_VK_BUTTON_BG);
sceGuFinish();
}

66
psp/psplib/pl_vk.h Normal file
View File

@ -0,0 +1,66 @@
/* psplib/pl_vk.h
Virtual keyboard implementation
Copyright (C) 2008-2009 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: dev@psp.akop.org
*/
#ifndef _PL_VK_H
#define _PL_VK_H
#include "ctrl.h"
#include "image.h"
#ifdef __cplusplus
extern "C" {
#endif
struct pl_vk_button_t;
struct pl_vk_sticky_t;
typedef struct pl_vk_layout_t
{
uint16_t key_count;
struct pl_vk_button_t *keys;
uint16_t sticky_count;
struct pl_vk_sticky_t *stickies;
uint16_t offset_x;
uint16_t offset_y;
uint16_t selected;
uint16_t held_down;
PspImage *keyb_image;
unsigned int __attribute__((aligned(16))) call_list[262144];
int(*read_callback)(unsigned int code);
void(*write_callback)(unsigned int code, int status);
} pl_vk_layout;
int pl_vk_load(pl_vk_layout *layout,
const char *data_path,
const char *image_path,
int(*read_callback)(unsigned int),
void(*write_callback)(unsigned int, int));
void pl_vk_destroy(pl_vk_layout *layout);
void pl_vk_reinit(pl_vk_layout *layout);
void pl_vk_render(const pl_vk_layout *layout);
void pl_vk_navigate(pl_vk_layout *layout, SceCtrlData *pad);
void pl_vk_release_all(pl_vk_layout *layout);
#ifdef __cplusplus
}
#endif
#endif // _PL_VK_H

4099
psp/psplib/stockfont.fd Normal file

File diff suppressed because it is too large Load Diff

328
psp/psplib/stockfont.h Normal file
View File

@ -0,0 +1,328 @@
unsigned short _ch[][13] = {
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 0 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 1 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 2 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 3 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 4 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 5 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 6 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 7 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 8 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 9 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 10 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 11 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 12 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 13 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 14 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 15 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 16 */
{ 0x0000,0x0000,0x0000,0x003f,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 17 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x003f,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 18 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x003f,0x0000,0x0000,0x0000 }, /* 19 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x003f }, /* 20 */
{ 0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x000f,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008 }, /* 21 */
{ 0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0038,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008 }, /* 22 */
{ 0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x003f,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 23 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x003f,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008 }, /* 24 */
{ 0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008 }, /* 25 */
{ 0x0000,0x0000,0x0000,0x0006,0x0018,0x0020,0x0018,0x0006,0x0000,0x003e,0x0000,0x0000,0x0000 }, /* 26 */
{ 0x0000,0x0000,0x0000,0x0030,0x000c,0x0002,0x000c,0x0030,0x0000,0x003e,0x0000,0x0000,0x0000 }, /* 27 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x003e,0x0014,0x0014,0x0014,0x0014,0x0014,0x0000,0x0000 }, /* 28 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0002,0x003e,0x0008,0x003e,0x0020,0x0000,0x0000,0x0000 }, /* 29 */
{ 0x0000,0x0000,0x000c,0x0012,0x0010,0x0010,0x0038,0x0010,0x0010,0x0012,0x002c,0x0000,0x0000 }, /* 30 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 31 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 32 */
{ 0x0000,0x0000,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0000,0x0008,0x0000,0x0000 }, /* 33 */
{ 0x0000,0x0000,0x0014,0x0014,0x0014,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 34 */
{ 0x0000,0x0000,0x0000,0x0014,0x0014,0x003e,0x0014,0x003e,0x0014,0x0014,0x0000,0x0000,0x0000 }, /* 35 */
{ 0x0000,0x0000,0x0008,0x001e,0x0028,0x0028,0x001c,0x000a,0x000a,0x003c,0x0008,0x0000,0x0000 }, /* 36 */
{ 0x0000,0x0000,0x0012,0x002a,0x0014,0x0004,0x0008,0x0010,0x0014,0x002a,0x0024,0x0000,0x0000 }, /* 37 */
{ 0x0000,0x0000,0x0000,0x0010,0x0028,0x0028,0x0010,0x0028,0x0026,0x0024,0x001a,0x0000,0x0000 }, /* 38 */
{ 0x0000,0x0000,0x000c,0x0008,0x0010,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 39 */
{ 0x0000,0x0004,0x0008,0x0008,0x0010,0x0010,0x0010,0x0010,0x0010,0x0008,0x0008,0x0004,0x0000 }, /* 40 */
{ 0x0000,0x0010,0x0008,0x0008,0x0004,0x0004,0x0004,0x0004,0x0004,0x0008,0x0008,0x0010,0x0000 }, /* 41 */
{ 0x0000,0x0000,0x0008,0x002a,0x001c,0x002a,0x0008,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 42 */
{ 0x0000,0x0000,0x0000,0x0000,0x0008,0x0008,0x003e,0x0008,0x0008,0x0000,0x0000,0x0000,0x0000 }, /* 43 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000c,0x0008,0x0010,0x0000 }, /* 44 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x003e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 45 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0008,0x001c,0x0008,0x0000 }, /* 46 */
{ 0x0000,0x0000,0x0002,0x0002,0x0004,0x0004,0x0008,0x0010,0x0010,0x0020,0x0020,0x0000,0x0000 }, /* 47 */
{ 0x0000,0x0000,0x0000,0x001c,0x0036,0x0022,0x0022,0x0022,0x0022,0x0036,0x001c,0x0000,0x0000 }, /* 48 */
{ 0x0000,0x0000,0x0000,0x0038,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x003e,0x0000,0x0000 }, /* 49 */
{ 0x0000,0x0000,0x0000,0x001c,0x0022,0x0002,0x0002,0x0004,0x0008,0x0010,0x003e,0x0000,0x0000 }, /* 50 */
{ 0x0000,0x0000,0x0000,0x001c,0x0022,0x0002,0x001c,0x0002,0x0002,0x0022,0x001c,0x0000,0x0000 }, /* 51 */
{ 0x0000,0x0000,0x0000,0x0004,0x000c,0x0014,0x0024,0x0044,0x007e,0x0004,0x0004,0x0000,0x0000 }, /* 52 */
{ 0x0000,0x0000,0x0000,0x0078,0x0040,0x0040,0x0078,0x0004,0x0004,0x0004,0x0078,0x0000,0x0000 }, /* 53 */
{ 0x0000,0x0000,0x0000,0x000e,0x0010,0x0020,0x003c,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 54 */
{ 0x0000,0x0000,0x0000,0x003e,0x0002,0x0004,0x0004,0x0008,0x0008,0x0008,0x0010,0x0000,0x0000 }, /* 55 */
{ 0x0000,0x0000,0x0000,0x001c,0x0022,0x0022,0x001c,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 56 */
{ 0x0000,0x0000,0x0000,0x0038,0x0044,0x0044,0x0044,0x003c,0x0004,0x0008,0x0070,0x0000,0x0000 }, /* 57 */
{ 0x0000,0x0000,0x0000,0x0008,0x001c,0x0008,0x0000,0x0000,0x0008,0x001c,0x0008,0x0000,0x0000 }, /* 58 */
{ 0x0000,0x0000,0x0000,0x0000,0x0008,0x001c,0x0008,0x0000,0x0000,0x000c,0x0008,0x0010,0x0000 }, /* 59 */
{ 0x0000,0x0000,0x0002,0x0004,0x0008,0x0010,0x0020,0x0010,0x0008,0x0004,0x0002,0x0000,0x0000 }, /* 60 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x003e,0x0000,0x0000,0x003e,0x0000,0x0000,0x0000,0x0000 }, /* 61 */
{ 0x0000,0x0000,0x0020,0x0010,0x0008,0x0004,0x0002,0x0004,0x0008,0x0010,0x0020,0x0000,0x0000 }, /* 62 */
{ 0x0000,0x0000,0x001c,0x0022,0x0022,0x0002,0x0004,0x0008,0x0008,0x0000,0x0008,0x0000,0x0000 }, /* 63 */
{ 0x0000,0x0000,0x001c,0x0022,0x0022,0x0026,0x002a,0x002a,0x002c,0x0020,0x001e,0x0000,0x0000 }, /* 64 */
{ 0x0000,0x0000,0x0000,0x0010,0x0028,0x0028,0x0028,0x0044,0x007c,0x0044,0x0082,0x0000,0x0000 }, /* 65 */
{ 0x0000,0x0000,0x0000,0x007c,0x0042,0x0042,0x007c,0x0042,0x0042,0x0042,0x007c,0x0000,0x0000 }, /* 66 */
{ 0x0000,0x0000,0x0000,0x001c,0x0022,0x0040,0x0040,0x0040,0x0040,0x0022,0x001c,0x0000,0x0000 }, /* 67 */
{ 0x0000,0x0000,0x0000,0x00f0,0x0088,0x0084,0x0084,0x0084,0x0084,0x0088,0x00f0,0x0000,0x0000 }, /* 68 */
{ 0x0000,0x0000,0x0000,0x003e,0x0020,0x0020,0x003e,0x0020,0x0020,0x0020,0x003e,0x0000,0x0000 }, /* 69 */
{ 0x0000,0x0000,0x0000,0x003e,0x0020,0x0020,0x003e,0x0020,0x0020,0x0020,0x0020,0x0000,0x0000 }, /* 70 */
{ 0x0000,0x0000,0x0000,0x003c,0x0042,0x0080,0x0080,0x008e,0x0082,0x0042,0x003c,0x0000,0x0000 }, /* 71 */
{ 0x0000,0x0000,0x0000,0x0042,0x0042,0x0042,0x007e,0x0042,0x0042,0x0042,0x0042,0x0000,0x0000 }, /* 72 */
{ 0x0000,0x0000,0x0000,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0000,0x0000 }, /* 73 */
{ 0x0000,0x0000,0x0000,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x000c }, /* 74 */
{ 0x0000,0x0000,0x0000,0x0044,0x0048,0x0050,0x0060,0x0050,0x0048,0x0044,0x0042,0x0000,0x0000 }, /* 75 */
{ 0x0000,0x0000,0x0000,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x003e,0x0000,0x0000 }, /* 76 */
{ 0x0000,0x0000,0x0000,0x0082,0x00c6,0x00c6,0x00aa,0x00aa,0x0092,0x0082,0x0082,0x0000,0x0000 }, /* 77 */
{ 0x0000,0x0000,0x0000,0x0062,0x0062,0x0052,0x0052,0x004a,0x004a,0x0046,0x0046,0x0000,0x0000 }, /* 78 */
{ 0x0000,0x0000,0x0000,0x0038,0x0044,0x0082,0x0082,0x0082,0x0082,0x0044,0x0038,0x0000,0x0000 }, /* 79 */
{ 0x0000,0x0000,0x0000,0x003c,0x0022,0x0022,0x0022,0x003c,0x0020,0x0020,0x0020,0x0000,0x0000 }, /* 80 */
{ 0x0000,0x0000,0x0000,0x0038,0x0044,0x0082,0x0082,0x0082,0x0082,0x0044,0x0038,0x000c,0x0000 }, /* 81 */
{ 0x0000,0x0000,0x0000,0x0078,0x0044,0x0044,0x0044,0x0078,0x0048,0x0044,0x0042,0x0000,0x0000 }, /* 82 */
{ 0x0000,0x0000,0x0000,0x003c,0x0042,0x0040,0x0078,0x0006,0x0002,0x0042,0x003c,0x0000,0x0000 }, /* 83 */
{ 0x0000,0x0000,0x0000,0x00fe,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0000,0x0000 }, /* 84 */
{ 0x0000,0x0000,0x0000,0x0042,0x0042,0x0042,0x0042,0x0042,0x0042,0x0066,0x003c,0x0000,0x0000 }, /* 85 */
{ 0x0000,0x0000,0x0000,0x0104,0x0104,0x0088,0x0088,0x0050,0x0050,0x0020,0x0020,0x0000,0x0000 }, /* 86 */
{ 0x0000,0x0000,0x0000,0x0222,0x0222,0x0124,0x0154,0x0154,0x0154,0x0088,0x0088,0x0000,0x0000 }, /* 87 */
{ 0x0000,0x0000,0x0000,0x0082,0x0044,0x0028,0x0010,0x0010,0x0028,0x0044,0x0082,0x0000,0x0000 }, /* 88 */
{ 0x0000,0x0000,0x0000,0x0082,0x0044,0x0028,0x0010,0x0010,0x0010,0x0010,0x0010,0x0000,0x0000 }, /* 89 */
{ 0x0000,0x0000,0x0000,0x00fe,0x0004,0x0008,0x0010,0x0010,0x0020,0x0040,0x00fe,0x0000,0x0000 }, /* 90 */
{ 0x0000,0x001c,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x0010,0x001c,0x0000 }, /* 91 */
{ 0x0000,0x0000,0x0020,0x0020,0x0010,0x0010,0x0008,0x0004,0x0004,0x0002,0x0002,0x0000,0x0000 }, /* 92 */
{ 0x0000,0x001c,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x001c,0x0000 }, /* 93 */
{ 0x0000,0x0000,0x0008,0x0014,0x0022,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 94 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x003e,0x0000 }, /* 95 */
{ 0x0000,0x0000,0x000c,0x0004,0x0002,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 96 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x0002,0x001e,0x0022,0x0022,0x001e,0x0000,0x0000 }, /* 97 */
{ 0x0000,0x0000,0x0020,0x0020,0x0020,0x003c,0x0022,0x0022,0x0022,0x0022,0x003c,0x0000,0x0000 }, /* 98 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x000e,0x0010,0x0010,0x0010,0x0010,0x000e,0x0000,0x0000 }, /* 99 */
{ 0x0000,0x0000,0x0002,0x0002,0x0002,0x001e,0x0022,0x0022,0x0022,0x0022,0x001e,0x0000,0x0000 }, /* 100 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x0022,0x003e,0x0020,0x0032,0x001c,0x0000,0x0000 }, /* 101 */
{ 0x0000,0x0000,0x000e,0x0008,0x0008,0x001e,0x0008,0x0008,0x0008,0x0008,0x0008,0x0000,0x0000 }, /* 102 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x001e,0x0022,0x0022,0x0022,0x0022,0x001e,0x0002,0x001c }, /* 103 */
{ 0x0000,0x0000,0x0020,0x0020,0x0020,0x0020,0x003c,0x0022,0x0022,0x0022,0x0022,0x0000,0x0000 }, /* 104 */
{ 0x0000,0x0000,0x0000,0x0000,0x0002,0x0000,0x0002,0x0002,0x0002,0x0002,0x0002,0x0000,0x0000 }, /* 105 */
{ 0x0000,0x0000,0x0000,0x0000,0x0002,0x0000,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0006 }, /* 106 */
{ 0x0000,0x0000,0x0040,0x0040,0x0040,0x0048,0x0050,0x0060,0x0050,0x0048,0x0044,0x0000,0x0000 }, /* 107 */
{ 0x0000,0x0000,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0000,0x0000 }, /* 108 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x0222,0x0222,0x0222,0x0222,0x0222,0x0000,0x0000 }, /* 109 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x003c,0x0022,0x0022,0x0022,0x0022,0x0022,0x0000,0x0000 }, /* 110 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 111 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x003c,0x0022,0x0022,0x0022,0x0022,0x003c,0x0020,0x0020 }, /* 112 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x001e,0x0022,0x0022,0x0022,0x0022,0x001e,0x0002,0x0002 }, /* 113 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0016,0x0018,0x0010,0x0010,0x0010,0x0010,0x0000,0x0000 }, /* 114 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x0022,0x0038,0x0006,0x0022,0x001c,0x0000,0x0000 }, /* 115 */
{ 0x0000,0x0000,0x0000,0x0008,0x0008,0x001e,0x0008,0x0008,0x0008,0x0008,0x000e,0x0000,0x0000 }, /* 116 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0022,0x0022,0x0022,0x0022,0x0022,0x001e,0x0000,0x0000 }, /* 117 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0042,0x0042,0x0024,0x0024,0x0018,0x0018,0x0000,0x0000 }, /* 118 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0092,0x0092,0x00aa,0x00aa,0x0044,0x0044,0x0000,0x0000 }, /* 119 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0042,0x0024,0x0018,0x0018,0x0024,0x0042,0x0000,0x0000 }, /* 120 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0042,0x0042,0x0024,0x0024,0x0018,0x0018,0x0010,0x0060 }, /* 121 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x003e,0x0002,0x0004,0x0008,0x0010,0x003e,0x0000,0x0000 }, /* 122 */
{ 0x0000,0x0006,0x0008,0x0008,0x0008,0x0008,0x0030,0x0008,0x0008,0x0008,0x0008,0x0006,0x0000 }, /* 123 */
{ 0x0000,0x0000,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0000,0x0000 }, /* 124 */
{ 0x0000,0x0030,0x0008,0x0008,0x0008,0x0008,0x0006,0x0008,0x0008,0x0008,0x0008,0x0030,0x0000 }, /* 125 */
{ 0x0000,0x0000,0x0012,0x002a,0x0024,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 126 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 127 */
{ 0x0000,0x0000,0x000e,0x0010,0x0010,0x003c,0x0010,0x003c,0x0010,0x0010,0x000e,0x0000,0x0000 }, /* 128 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 129 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000c,0x0004,0x0008,0x0000 }, /* 130 */
{ 0x0000,0x0000,0x0004,0x000a,0x0008,0x0008,0x001c,0x0008,0x0008,0x0008,0x0008,0x0028,0x0010 }, /* 131 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0036,0x0012,0x0024,0x0000 }, /* 132 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x002a,0x0000,0x0000 }, /* 133 */
{ 0x0000,0x0000,0x0008,0x0008,0x003e,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0000,0x0000 }, /* 134 */
{ 0x0000,0x0000,0x0008,0x0008,0x003e,0x0008,0x0008,0x003e,0x0008,0x0008,0x0008,0x0000,0x0000 }, /* 135 */
{ 0x0000,0x000c,0x0012,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 136 */
{ 0x0000,0x0000,0x0012,0x002a,0x0014,0x0004,0x0008,0x0010,0x001a,0x0035,0x002a,0x0000,0x0000 }, /* 137 */
{ 0x0000,0x0012,0x000c,0x0000,0x001c,0x0022,0x0020,0x001c,0x0002,0x0022,0x001c,0x0000,0x0000 }, /* 138 */
{ 0x0000,0x0000,0x0000,0x0000,0x0004,0x0008,0x0010,0x0010,0x0008,0x0004,0x0000,0x0000,0x0000 }, /* 139 */
{ 0x0000,0x0000,0x001e,0x0028,0x0028,0x0028,0x002c,0x0028,0x0028,0x0028,0x001e,0x0000,0x0000 }, /* 140 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 141 */
{ 0x0000,0x0012,0x000c,0x0000,0x003e,0x0002,0x0004,0x0008,0x0010,0x0020,0x003e,0x0000,0x0000 }, /* 142 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 143 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 144 */
{ 0x0000,0x0000,0x0004,0x0008,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 145 */
{ 0x0000,0x0000,0x000c,0x0004,0x0008,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 146 */
{ 0x0000,0x0000,0x0012,0x0024,0x0036,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 147 */
{ 0x0000,0x0000,0x0036,0x0012,0x0024,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 148 */
{ 0x0000,0x0000,0x0000,0x0000,0x001c,0x003e,0x003e,0x003e,0x001c,0x0000,0x0000,0x0000,0x0000 }, /* 149 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x003e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 150 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x003f,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 151 */
{ 0x0000,0x000a,0x0014,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 152 */
{ 0x0000,0x0000,0x003d,0x0017,0x0015,0x0015,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 153 */
{ 0x0000,0x0000,0x0024,0x0018,0x0000,0x001c,0x0022,0x0018,0x0004,0x0022,0x001c,0x0000,0x0000 }, /* 154 */
{ 0x0000,0x0000,0x0000,0x0000,0x0010,0x0008,0x0004,0x0004,0x0008,0x0010,0x0000,0x0000,0x0000 }, /* 155 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0014,0x002a,0x002e,0x0028,0x002a,0x0014,0x0000,0x0000 }, /* 156 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 157 */
{ 0x0000,0x0000,0x0012,0x000c,0x0000,0x003e,0x0004,0x0008,0x0010,0x0020,0x003e,0x0000,0x0000 }, /* 158 */
{ 0x0000,0x0014,0x0014,0x0000,0x0022,0x0014,0x0014,0x0008,0x0008,0x0008,0x0008,0x0000,0x0000 }, /* 159 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 }, /* 160 */
{ 0x0000,0x0000,0x0000,0x0082,0x0044,0x0028,0x0010,0x0028,0x0044,0x0082,0x0000,0x0000,0x0000 }, /* 161 */
{ 0x0000,0x0000,0x0000,0x0038,0x0044,0x0082,0x0082,0x0082,0x0044,0x0038,0x0000,0x0000,0x0000 }, /* 162 */
{ 0x0000,0x0000,0x0000,0x0000,0x0020,0x0050,0x0088,0x0104,0x03fe,0x0000,0x0000,0x0000,0x0000 }, /* 163 */
{ 0x0000,0x0000,0x0000,0x00fe,0x0082,0x0082,0x0082,0x0082,0x0082,0x00fe,0x0000,0x0000,0x0000 }, /* 164 */
{ 0x0000,0x0000,0x01fe,0x0102,0x0102,0x0132,0x017a,0x0102,0x0084,0x0048,0x0030,0x0000,0x0000 }, /* 165 */
{ 0x0000,0x0000,0x0030,0x0048,0x0084,0x0102,0x017a,0x0132,0x0102,0x0102,0x01fe,0x0000,0x0000 }, /* 166 */
{ 0x0000,0x0000,0x0000,0x03f0,0x0208,0x0244,0x02c2,0x02c2,0x0244,0x0208,0x03f0,0x0000,0x0000 }, /* 167 */
{ 0x0000,0x0000,0x0000,0x007e,0x0082,0x0112,0x021a,0x021a,0x0112,0x0082,0x007e,0x0000,0x0000 }, /* 168 */
{ 0x0000,0x0000,0x00f8,0x0104,0x0222,0x0272,0x02aa,0x0222,0x0222,0x0104,0x00f8,0x0000,0x0000 }, /* 169 */
{ 0x0000,0x0000,0x00f8,0x0104,0x0222,0x0222,0x02aa,0x0272,0x0222,0x0104,0x00f8,0x0000,0x0000 }, /* 170 */
{ 0x0000,0x0000,0x00f8,0x0104,0x0222,0x0242,0x02fa,0x0242,0x0222,0x0104,0x00f8,0x0000,0x0000 }, /* 171 */
{ 0x0000,0x0000,0x00f8,0x0104,0x0222,0x0212,0x02fa,0x0212,0x0222,0x0104,0x00f8,0x0000,0x0000 }, /* 172 */
{ 0x0000,0x0000,0xfffe,0x8002,0x8402,0x8402,0x8402,0x8402,0x87c2,0x8002,0xfffe,0x0000,0x0000 }, /* 173 */
{ 0x0000,0x0000,0xfffe,0x8002,0x8782,0x8442,0x8782,0x8442,0x8442,0x8002,0xfffe,0x0000,0x0000 }, /* 174 */
{ 0x0000,0x0000,0x0000,0x6e8e,0x8888,0x8888,0x4c8c,0x2888,0x2888,0xceee,0x0000,0x0000,0x0000 }, /* 175 */
{ 0x0000,0x0000,0x0000,0x006e,0x0084,0x0084,0x0084,0x0084,0x0084,0x0064,0x0000,0x0000,0x0000 }, /* 176 */
{ 0x0000,0x0000,0x0000,0x6e4c,0x84aa,0x84aa,0x44ec,0x24aa,0x24aa,0xc4aa,0x0000,0x0000,0x0000 }, /* 177 */
{ 0x0000,0x0000,0x0000,0x000e,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,0x0000,0x0000,0x0000 }, /* 178 */
{ 0x0000,0x0000,0x1ffe,0x1002,0x16da,0x76da,0x76da,0x76da,0x16da,0x1002,0x1ffe,0x0000,0x0000 }, /* 179 */
{ 0x0000,0x0000,0x1ffe,0x1002,0x10da,0x70da,0x70da,0x70da,0x10da,0x1002,0x1ffe,0x0000,0x0000 }, /* 180 */
{ 0x0000,0x0000,0x1ffe,0x1002,0x101a,0x701a,0x701a,0x701a,0x101a,0x1002,0x1ffe,0x0000,0x0000 }, /* 181 */
{ 0x0000,0x0000,0x1ffe,0x1002,0x1002,0x7002,0x7002,0x7002,0x1002,0x1002,0x1ffe,0x0000,0x0000 }, /* 182 */
{ 0x0000,0x0044,0x0044,0x00fe,0x0082,0x0082,0x0044,0x0038,0x0010,0x0008,0x0006,0x0000,0x0000 }, /* 183 */
{ 0x0000,0x0000,0x00f8,0x0104,0x0222,0x0222,0x023a,0x0202,0x0202,0x0104,0x00f8,0x0000,0x0000 }, /* 184 */
{ 0x0000,0x0000,0x7ffe,0x4002,0x4002,0x4002,0x4802,0x5802,0x4802,0x2002,0x1ffe,0x0000,0x0000 }, /* 185 */
{ 0x0000,0x0000,0x0008,0x001c,0x002a,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x0000,0x0000 }, /* 186 */
{ 0x0000,0x0000,0x0008,0x0008,0x0008,0x0008,0x0008,0x0008,0x002a,0x001c,0x0008,0x0000,0x0000 }, /* 187 */
{ 0x0000,0x0000,0x03fc,0x02ea,0x02ea,0x02fa,0x0202,0x02fa,0x02fa,0x02fa,0x03fe,0x0000,0x0000 }, /* 188 */
{ 0x0000,0x0000,0x0000,0x0000,0x0008,0x0008,0x003e,0x001c,0x0036,0x0022,0x0000,0x0000,0x0000 }, /* 189 */
{ 0x0000,0x0010,0x0028,0x0010,0x0008,0x0028,0x0012,0x0006,0x000a,0x000e,0x0002,0x0000,0x0000 }, /* 190 */
{ 0x0000,0x0000,0x0008,0x0000,0x0008,0x0008,0x0010,0x0020,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 191 */
{ 0x0000,0x0010,0x0008,0x0000,0x0008,0x0014,0x0022,0x0022,0x003e,0x0022,0x0022,0x0000,0x0000 }, /* 192 */
{ 0x0000,0x0004,0x0008,0x0000,0x0008,0x0014,0x0022,0x0022,0x003e,0x0022,0x0022,0x0000,0x0000 }, /* 193 */
{ 0x0000,0x000c,0x0012,0x0000,0x0008,0x0014,0x0022,0x0022,0x003e,0x0022,0x0022,0x0000,0x0000 }, /* 194 */
{ 0x0000,0x000a,0x0014,0x0000,0x0008,0x0014,0x0022,0x0022,0x003e,0x0022,0x0022,0x0000,0x0000 }, /* 195 */
{ 0x0000,0x0014,0x0014,0x0000,0x0008,0x0014,0x0022,0x0022,0x003e,0x0022,0x0022,0x0000,0x0000 }, /* 196 */
{ 0x0000,0x0008,0x0014,0x0008,0x0008,0x0014,0x0022,0x0022,0x003e,0x0022,0x0022,0x0000,0x0000 }, /* 197 */
{ 0x0000,0x0000,0x0016,0x0028,0x0028,0x0028,0x002c,0x0038,0x0028,0x0028,0x002e,0x0000,0x0000 }, /* 198 */
{ 0x0000,0x0000,0x001c,0x0022,0x0020,0x0020,0x0020,0x0020,0x0020,0x0022,0x001c,0x0008,0x0010 }, /* 199 */
{ 0x0000,0x0010,0x0008,0x0000,0x003e,0x0020,0x0020,0x003c,0x0020,0x0020,0x003e,0x0000,0x0000 }, /* 200 */
{ 0x0000,0x0004,0x0008,0x0000,0x003e,0x0020,0x0020,0x003c,0x0020,0x0020,0x003e,0x0000,0x0000 }, /* 201 */
{ 0x0000,0x000c,0x0012,0x0000,0x003e,0x0020,0x0020,0x003c,0x0020,0x0020,0x003e,0x0000,0x0000 }, /* 202 */
{ 0x0000,0x0014,0x0014,0x0000,0x003e,0x0020,0x0020,0x003c,0x0020,0x0020,0x003e,0x0000,0x0000 }, /* 203 */
{ 0x0000,0x0010,0x0008,0x0000,0x001c,0x0008,0x0008,0x0008,0x0008,0x0008,0x001c,0x0000,0x0000 }, /* 204 */
{ 0x0000,0x0004,0x0008,0x0000,0x001c,0x0008,0x0008,0x0008,0x0008,0x0008,0x001c,0x0000,0x0000 }, /* 205 */
{ 0x0000,0x000c,0x0012,0x0000,0x001c,0x0008,0x0008,0x0008,0x0008,0x0008,0x001c,0x0000,0x0000 }, /* 206 */
{ 0x0000,0x0014,0x0014,0x0000,0x001c,0x0008,0x0008,0x0008,0x0008,0x0008,0x001c,0x0000,0x0000 }, /* 207 */
{ 0x0000,0x0000,0x003c,0x0012,0x0012,0x0012,0x003a,0x0012,0x0012,0x0012,0x003c,0x0000,0x0000 }, /* 208 */
{ 0x0000,0x000a,0x0014,0x0000,0x0022,0x0022,0x0032,0x002a,0x0026,0x0022,0x0022,0x0000,0x0000 }, /* 209 */
{ 0x0000,0x0010,0x0008,0x0000,0x001c,0x0022,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 210 */
{ 0x0000,0x0004,0x0008,0x0000,0x001c,0x0022,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 211 */
{ 0x0000,0x000c,0x0012,0x0000,0x001c,0x0022,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 212 */
{ 0x0000,0x000a,0x0014,0x0000,0x001c,0x0022,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 213 */
{ 0x0000,0x0014,0x0014,0x0000,0x001c,0x0022,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 214 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0022,0x0014,0x0008,0x0014,0x0022,0x0000,0x0000,0x0000 }, /* 215 */
{ 0x0000,0x0002,0x001c,0x0026,0x0026,0x002a,0x002a,0x002a,0x0032,0x0032,0x001c,0x0020,0x0000 }, /* 216 */
{ 0x0000,0x0010,0x0008,0x0000,0x0022,0x0022,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 217 */
{ 0x0000,0x0004,0x0008,0x0000,0x0022,0x0022,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 218 */
{ 0x0000,0x000c,0x0012,0x0000,0x0022,0x0022,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 219 */
{ 0x0000,0x0014,0x0014,0x0000,0x0022,0x0022,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 220 */
{ 0x0000,0x0004,0x0008,0x0000,0x0022,0x0022,0x0014,0x0008,0x0008,0x0008,0x0008,0x0000,0x0000 }, /* 221 */
{ 0x0000,0x0000,0x0020,0x003c,0x0022,0x0022,0x0022,0x003c,0x0020,0x0020,0x0020,0x0000,0x0000 }, /* 222 */
{ 0x0000,0x0000,0x0018,0x0024,0x0024,0x0028,0x0028,0x0024,0x0022,0x0022,0x002c,0x0000,0x0000 }, /* 223 */
{ 0x0000,0x0000,0x0010,0x0008,0x0000,0x001c,0x0002,0x001e,0x0022,0x0026,0x001a,0x0000,0x0000 }, /* 224 */
{ 0x0000,0x0000,0x0004,0x0008,0x0000,0x001c,0x0002,0x001e,0x0022,0x0026,0x001a,0x0000,0x0000 }, /* 225 */
{ 0x0000,0x0000,0x000c,0x0012,0x0000,0x001c,0x0002,0x001e,0x0022,0x0026,0x001a,0x0000,0x0000 }, /* 226 */
{ 0x0000,0x0000,0x000a,0x0014,0x0000,0x001c,0x0002,0x001e,0x0022,0x0026,0x001a,0x0000,0x0000 }, /* 227 */
{ 0x0000,0x0000,0x0014,0x0014,0x0000,0x001c,0x0002,0x001e,0x0022,0x0026,0x001a,0x0000,0x0000 }, /* 228 */
{ 0x0000,0x000c,0x0012,0x000c,0x0000,0x001c,0x0002,0x001e,0x0022,0x0026,0x001a,0x0000,0x0000 }, /* 229 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x000a,0x001c,0x0028,0x002a,0x0014,0x0000,0x0000 }, /* 230 */
{ 0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x0022,0x0020,0x0020,0x0022,0x001c,0x0008,0x0010 }, /* 231 */
{ 0x0000,0x0000,0x0010,0x0008,0x0000,0x001c,0x0022,0x003e,0x0020,0x0022,0x001c,0x0000,0x0000 }, /* 232 */
{ 0x0000,0x0000,0x0004,0x0008,0x0000,0x001c,0x0022,0x003e,0x0020,0x0022,0x001c,0x0000,0x0000 }, /* 233 */
{ 0x0000,0x0000,0x000c,0x0012,0x0000,0x001c,0x0022,0x003e,0x0020,0x0022,0x001c,0x0000,0x0000 }, /* 234 */
{ 0x0000,0x0000,0x0014,0x0014,0x0000,0x001c,0x0022,0x003e,0x0020,0x0022,0x001c,0x0000,0x0000 }, /* 235 */
{ 0x0000,0x0000,0x0010,0x0008,0x0000,0x0018,0x0008,0x0008,0x0008,0x0008,0x001c,0x0000,0x0000 }, /* 236 */
{ 0x0000,0x0000,0x0004,0x0008,0x0000,0x0018,0x0008,0x0008,0x0008,0x0008,0x001c,0x0000,0x0000 }, /* 237 */
{ 0x0000,0x0000,0x000c,0x0012,0x0000,0x0018,0x0008,0x0008,0x0008,0x0008,0x001c,0x0000,0x0000 }, /* 238 */
{ 0x0000,0x0000,0x0014,0x0014,0x0000,0x0018,0x0008,0x0008,0x0008,0x0008,0x001c,0x0000,0x0000 }, /* 239 */
{ 0x0000,0x0014,0x0008,0x0018,0x0004,0x001c,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 240 */
{ 0x0000,0x0000,0x000a,0x0014,0x0000,0x002c,0x0032,0x0022,0x0022,0x0022,0x0022,0x0000,0x0000 }, /* 241 */
{ 0x0000,0x0000,0x0010,0x0008,0x0000,0x001c,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 242 */
{ 0x0000,0x0000,0x0004,0x0008,0x0000,0x001c,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 243 */
{ 0x0000,0x0000,0x000c,0x0012,0x0000,0x001c,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 244 */
{ 0x0000,0x0000,0x000a,0x0014,0x0000,0x001c,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 245 */
{ 0x0000,0x0000,0x0014,0x0014,0x0000,0x001c,0x0022,0x0022,0x0022,0x0022,0x001c,0x0000,0x0000 }, /* 246 */
{ 0x0000,0x0000,0x0000,0x0008,0x0008,0x0000,0x003e,0x0000,0x0008,0x0008,0x0000,0x0000,0x0000 }, /* 247 */
{ 0x0000,0x0000,0x0000,0x0000,0x0002,0x001c,0x0026,0x002a,0x002a,0x0032,0x001c,0x0020,0x0000 }, /* 248 */
{ 0x0000,0x0000,0x0010,0x0008,0x0000,0x0022,0x0022,0x0022,0x0022,0x0026,0x001a,0x0000,0x0000 }, /* 249 */
{ 0x0000,0x0000,0x0004,0x0008,0x0000,0x0022,0x0022,0x0022,0x0022,0x0026,0x001a,0x0000,0x0000 }, /* 250 */
{ 0x0000,0x0000,0x000c,0x0012,0x0000,0x0022,0x0022,0x0022,0x0022,0x0026,0x001a,0x0000,0x0000 }, /* 251 */
{ 0x0000,0x0000,0x0014,0x0014,0x0000,0x0022,0x0022,0x0022,0x0022,0x0026,0x001a,0x0000,0x0000 }, /* 252 */
{ 0x0000,0x0000,0x0004,0x0008,0x0000,0x0022,0x0022,0x0022,0x0026,0x001a,0x0002,0x0022,0x001c }, /* 253 */
{ 0x0000,0x0000,0x0000,0x0020,0x0020,0x002c,0x0032,0x0022,0x0022,0x0032,0x002c,0x0020,0x0020 }, /* 254 */
{ 0x0000,0x0000,0x0014,0x0014,0x0000,0x0022,0x0022,0x0022,0x0026,0x001a,0x0002,0x0022,0x001c }, /* 255 */
};
const PspFont PspStockFont =
{ 13, 11,
{
{ 0x06,_ch[0x00] },{ 0x06,_ch[0x01] },{ 0x06,_ch[0x02] },{ 0x06,_ch[0x03] },
{ 0x06,_ch[0x04] },{ 0x06,_ch[0x05] },{ 0x06,_ch[0x06] },{ 0x06,_ch[0x07] },
{ 0x06,_ch[0x08] },{ 0x06,_ch[0x09] },{ 0x06,_ch[0x0a] },{ 0x06,_ch[0x0b] },
{ 0x06,_ch[0x0c] },{ 0x06,_ch[0x0d] },{ 0x06,_ch[0x0e] },{ 0x06,_ch[0x0f] },
{ 0x06,_ch[0x10] },{ 0x06,_ch[0x11] },{ 0x06,_ch[0x12] },{ 0x06,_ch[0x13] },
{ 0x06,_ch[0x14] },{ 0x06,_ch[0x15] },{ 0x06,_ch[0x16] },{ 0x06,_ch[0x17] },
{ 0x06,_ch[0x18] },{ 0x06,_ch[0x19] },{ 0x06,_ch[0x1a] },{ 0x06,_ch[0x1b] },
{ 0x06,_ch[0x1c] },{ 0x06,_ch[0x1d] },{ 0x06,_ch[0x1e] },{ 0x06,_ch[0x1f] },
{ 0x06,_ch[0x20] },{ 0x06,_ch[0x21] },{ 0x06,_ch[0x22] },{ 0x06,_ch[0x23] },
{ 0x06,_ch[0x24] },{ 0x06,_ch[0x25] },{ 0x06,_ch[0x26] },{ 0x06,_ch[0x27] },
{ 0x06,_ch[0x28] },{ 0x06,_ch[0x29] },{ 0x06,_ch[0x2a] },{ 0x06,_ch[0x2b] },
{ 0x06,_ch[0x2c] },{ 0x06,_ch[0x2d] },{ 0x06,_ch[0x2e] },{ 0x06,_ch[0x2f] },
{ 0x06,_ch[0x30] },{ 0x06,_ch[0x31] },{ 0x06,_ch[0x32] },{ 0x06,_ch[0x33] },
{ 0x07,_ch[0x34] },{ 0x07,_ch[0x35] },{ 0x06,_ch[0x36] },{ 0x06,_ch[0x37] },
{ 0x06,_ch[0x38] },{ 0x07,_ch[0x39] },{ 0x06,_ch[0x3a] },{ 0x06,_ch[0x3b] },
{ 0x06,_ch[0x3c] },{ 0x06,_ch[0x3d] },{ 0x06,_ch[0x3e] },{ 0x06,_ch[0x3f] },
{ 0x06,_ch[0x40] },{ 0x08,_ch[0x41] },{ 0x07,_ch[0x42] },{ 0x07,_ch[0x43] },
{ 0x08,_ch[0x44] },{ 0x06,_ch[0x45] },{ 0x06,_ch[0x46] },{ 0x08,_ch[0x47] },
{ 0x07,_ch[0x48] },{ 0x02,_ch[0x49] },{ 0x04,_ch[0x4a] },{ 0x07,_ch[0x4b] },
{ 0x06,_ch[0x4c] },{ 0x08,_ch[0x4d] },{ 0x07,_ch[0x4e] },{ 0x08,_ch[0x4f] },
{ 0x06,_ch[0x50] },{ 0x08,_ch[0x51] },{ 0x07,_ch[0x52] },{ 0x07,_ch[0x53] },
{ 0x08,_ch[0x54] },{ 0x07,_ch[0x55] },{ 0x09,_ch[0x56] },{ 0x0a,_ch[0x57] },
{ 0x08,_ch[0x58] },{ 0x08,_ch[0x59] },{ 0x08,_ch[0x5a] },{ 0x06,_ch[0x5b] },
{ 0x06,_ch[0x5c] },{ 0x06,_ch[0x5d] },{ 0x06,_ch[0x5e] },{ 0x06,_ch[0x5f] },
{ 0x06,_ch[0x60] },{ 0x06,_ch[0x61] },{ 0x06,_ch[0x62] },{ 0x05,_ch[0x63] },
{ 0x06,_ch[0x64] },{ 0x06,_ch[0x65] },{ 0x05,_ch[0x66] },{ 0x06,_ch[0x67] },
{ 0x06,_ch[0x68] },{ 0x02,_ch[0x69] },{ 0x03,_ch[0x6a] },{ 0x07,_ch[0x6b] },
{ 0x02,_ch[0x6c] },{ 0x0a,_ch[0x6d] },{ 0x06,_ch[0x6e] },{ 0x06,_ch[0x6f] },
{ 0x06,_ch[0x70] },{ 0x06,_ch[0x71] },{ 0x05,_ch[0x72] },{ 0x06,_ch[0x73] },
{ 0x05,_ch[0x74] },{ 0x06,_ch[0x75] },{ 0x07,_ch[0x76] },{ 0x08,_ch[0x77] },
{ 0x07,_ch[0x78] },{ 0x07,_ch[0x79] },{ 0x06,_ch[0x7a] },{ 0x06,_ch[0x7b] },
{ 0x06,_ch[0x7c] },{ 0x06,_ch[0x7d] },{ 0x06,_ch[0x7e] },{ 0x06,_ch[0x7f] },
{ 0x06,_ch[0x80] },{ 0x06,_ch[0x81] },{ 0x06,_ch[0x82] },{ 0x06,_ch[0x83] },
{ 0x06,_ch[0x84] },{ 0x06,_ch[0x85] },{ 0x06,_ch[0x86] },{ 0x06,_ch[0x87] },
{ 0x06,_ch[0x88] },{ 0x06,_ch[0x89] },{ 0x06,_ch[0x8a] },{ 0x06,_ch[0x8b] },
{ 0x06,_ch[0x8c] },{ 0x06,_ch[0x8d] },{ 0x06,_ch[0x8e] },{ 0x06,_ch[0x8f] },
{ 0x06,_ch[0x90] },{ 0x06,_ch[0x91] },{ 0x06,_ch[0x92] },{ 0x06,_ch[0x93] },
{ 0x06,_ch[0x94] },{ 0x06,_ch[0x95] },{ 0x06,_ch[0x96] },{ 0x06,_ch[0x97] },
{ 0x06,_ch[0x98] },{ 0x06,_ch[0x99] },{ 0x06,_ch[0x9a] },{ 0x06,_ch[0x9b] },
{ 0x06,_ch[0x9c] },{ 0x06,_ch[0x9d] },{ 0x06,_ch[0x9e] },{ 0x06,_ch[0x9f] },
{ 0x06,_ch[0xa0] },{ 0x09,_ch[0xa1] },{ 0x09,_ch[0xa2] },{ 0x0a,_ch[0xa3] },
{ 0x09,_ch[0xa4] },{ 0x0a,_ch[0xa5] },{ 0x0a,_ch[0xa6] },{ 0x0b,_ch[0xa7] },
{ 0x0b,_ch[0xa8] },{ 0x0a,_ch[0xa9] },{ 0x0a,_ch[0xaa] },{ 0x0a,_ch[0xab] },
{ 0x0a,_ch[0xac] },{ 0x10,_ch[0xad] },{ 0x10,_ch[0xae] },{ 0x10,_ch[0xaf] },
{ 0x08,_ch[0xb0] },{ 0x10,_ch[0xb1] },{ 0x04,_ch[0xb2] },{ 0x0f,_ch[0xb3] },
{ 0x0f,_ch[0xb4] },{ 0x0f,_ch[0xb5] },{ 0x0f,_ch[0xb6] },{ 0x09,_ch[0xb7] },
{ 0x0a,_ch[0xb8] },{ 0x0f,_ch[0xb9] },{ 0x06,_ch[0xba] },{ 0x06,_ch[0xbb] },
{ 0x0a,_ch[0xbc] },{ 0x06,_ch[0xbd] },{ 0x06,_ch[0xbe] },{ 0x06,_ch[0xbf] },
{ 0x06,_ch[0xc0] },{ 0x06,_ch[0xc1] },{ 0x06,_ch[0xc2] },{ 0x06,_ch[0xc3] },
{ 0x06,_ch[0xc4] },{ 0x06,_ch[0xc5] },{ 0x06,_ch[0xc6] },{ 0x06,_ch[0xc7] },
{ 0x06,_ch[0xc8] },{ 0x06,_ch[0xc9] },{ 0x06,_ch[0xca] },{ 0x06,_ch[0xcb] },
{ 0x06,_ch[0xcc] },{ 0x06,_ch[0xcd] },{ 0x06,_ch[0xce] },{ 0x06,_ch[0xcf] },
{ 0x06,_ch[0xd0] },{ 0x06,_ch[0xd1] },{ 0x06,_ch[0xd2] },{ 0x06,_ch[0xd3] },
{ 0x06,_ch[0xd4] },{ 0x06,_ch[0xd5] },{ 0x06,_ch[0xd6] },{ 0x06,_ch[0xd7] },
{ 0x06,_ch[0xd8] },{ 0x06,_ch[0xd9] },{ 0x06,_ch[0xda] },{ 0x06,_ch[0xdb] },
{ 0x06,_ch[0xdc] },{ 0x06,_ch[0xdd] },{ 0x06,_ch[0xde] },{ 0x06,_ch[0xdf] },
{ 0x06,_ch[0xe0] },{ 0x06,_ch[0xe1] },{ 0x06,_ch[0xe2] },{ 0x06,_ch[0xe3] },
{ 0x06,_ch[0xe4] },{ 0x06,_ch[0xe5] },{ 0x06,_ch[0xe6] },{ 0x06,_ch[0xe7] },
{ 0x06,_ch[0xe8] },{ 0x06,_ch[0xe9] },{ 0x06,_ch[0xea] },{ 0x06,_ch[0xeb] },
{ 0x06,_ch[0xec] },{ 0x06,_ch[0xed] },{ 0x06,_ch[0xee] },{ 0x06,_ch[0xef] },
{ 0x06,_ch[0xf0] },{ 0x06,_ch[0xf1] },{ 0x06,_ch[0xf2] },{ 0x06,_ch[0xf3] },
{ 0x06,_ch[0xf4] },{ 0x06,_ch[0xf5] },{ 0x06,_ch[0xf6] },{ 0x06,_ch[0xf7] },
{ 0x06,_ch[0xf8] },{ 0x06,_ch[0xf9] },{ 0x06,_ch[0xfa] },{ 0x06,_ch[0xfb] },
{ 0x06,_ch[0xfc] },{ 0x06,_ch[0xfd] },{ 0x06,_ch[0xfe] },{ 0x06,_ch[0xff] },
}
};

2846
psp/psplib/ui.c Normal file

File diff suppressed because it is too large Load Diff

146
psp/psplib/ui.h Normal file
View File

@ -0,0 +1,146 @@
/* psplib/ui.h
Simple user interface implementation
Copyright (C) 2007-2008 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: pspdev@akop.org
*/
#ifndef _PSP_UI_H
#define _PSP_UI_H
#include "video.h"
#include "pl_menu.h"
#include "adhoc.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct PspUiMetric
{
const PspImage *Background;
const PspFont *Font;
u64 CancelButton;
u64 OkButton;
int Left;
int Top;
int Right;
int Bottom;
u32 ScrollbarColor;
u32 ScrollbarBgColor;
int ScrollbarWidth;
u32 TextColor;
u32 SelectedColor;
u32 SelectedBgColor;
u32 StatusBarColor;
int MenuFps;
u32 DialogFogColor;
u32 BrowserFileColor;
u32 BrowserDirectoryColor;
u32 BrowserScreenshotDelay;
const char *BrowserScreenshotPath;
int GalleryIconsPerRow;
int GalleryIconMarginWidth;
int MenuItemMargin;
u32 MenuSelOptionBg;
u32 MenuOptionBoxColor;
u32 MenuOptionBoxBg;
u32 MenuDecorColor;
int TitlePadding;
u32 TitleColor;
u32 TabBgColor;
int Animate;
} PspUiMetric;
typedef struct PspUiFileBrowser
{
void (*OnRender)(const void *browser, const void *path);
int (*OnOk)(const void *browser, const void *file);
int (*OnCancel)(const void *gallery, const void *parent_dir);
int (*OnButtonPress)(const struct PspUiFileBrowser* browser,
const char *selected, u32 button_mask);
const char **Filter;
void *Userdata;
} PspUiFileBrowser;
typedef struct PspUiMenu
{
void (*OnRender)(const void *uimenu, const void *item);
int (*OnOk)(const void *menu, const void *item);
int (*OnCancel)(const void *menu, const void *item);
int (*OnButtonPress)(const struct PspUiMenu *menu, pl_menu_item *item,
u32 button_mask);
int (*OnItemChanged)(const struct PspUiMenu *menu, pl_menu_item *item,
const pl_menu_option *option);
pl_menu Menu;
} PspUiMenu;
typedef struct PspUiGallery
{
void (*OnRender)(const void *gallery, const void *item);
int (*OnOk)(const void *gallery, const void *item);
int (*OnCancel)(const void *gallery, const void *item);
int (*OnButtonPress)(const struct PspUiGallery *gallery, pl_menu_item* item,
u32 button_mask);
void *Userdata;
pl_menu Menu;
} PspUiGallery;
typedef struct PspUiSplash
{
void (*OnRender)(const void *splash, const void *null);
int (*OnCancel)(const void *splash, const void *null);
int (*OnButtonPress)(const struct PspUiSplash *splash, u32 button_mask);
const char* (*OnGetStatusBarText)(const struct PspUiSplash *splash);
} PspUiSplash;
#define PSP_UI_YES 2
#define PSP_UI_NO 1
#define PSP_UI_CANCEL 0
#define PSP_UI_CONFIRM 1
char pspUiGetButtonIcon(u32 button_mask);
void pspUiOpenBrowser(PspUiFileBrowser *browser, const char *start_path);
void pspUiOpenGallery(PspUiGallery *gallery, const char *title);
void pspUiOpenMenu(PspUiMenu *uimenu, const char *title);
void pspUiSplashScreen(PspUiSplash *splash);
int pspUiAdhocHost(const char *name, PspMAC mac);
int pspUiAdhocJoin(PspMAC mac);
int pspUiConfirm(const char *message);
int pspUiYesNoCancel(const char *message);
void pspUiAlert(const char *message);
void pspUiFlashMessage(const char *message);
const pl_menu_item* pspUiSelect(const char *title, const pl_menu *menu);
void pspUiFadeout();
PspUiMetric UiMetric;
#ifdef __cplusplus
}
#endif
#endif // _PSP_UI_H

762
psp/psplib/video.c Normal file
View File

@ -0,0 +1,762 @@
/* psplib/video.c
Graphics rendering routines
Copyright (C) 2007-2008 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: pspdev@akop.org
*/
/* TODO: move ScratchBuffer into VRAM */
#include <pspgu.h>
#include <pspkernel.h>
#include <pspdisplay.h>
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <psprtc.h>
#include "video.h"
#define SLICE_SIZE 64
#define VRAM_START 0x04000000
#define VRAM_SIZE 0x00200000
int res2x;
int vertical;
int bilinear;
const unsigned int PspFontColor[] =
{
0, /* Restore */
PSP_COLOR_BLACK,
PSP_COLOR_RED,
PSP_COLOR_GREEN,
PSP_COLOR_BLUE,
PSP_COLOR_GRAY,
PSP_COLOR_YELLOW,
PSP_COLOR_MAGENTA,
PSP_COLOR_WHITE
};
struct TexVertex
{
unsigned short u, v;
unsigned short color;
short x, y, z;
};
static u8 FrameIndex;
static void *DisplayBuffer;
static void *DrawBuffer;
static int PixelFormat;
static int TexColor;
static unsigned int VBlankFreq;
static void *VramOffset;
static void *VramChunkOffset;
static unsigned short __attribute__((aligned(16))) ScratchBuffer[BUF_WIDTH * SCR_HEIGHT];
//static void *ScratchBuffer;
//static int ScratchBufferSize;
static unsigned int __attribute__((aligned(16))) List[262144]; /* TODO: ? */
static void* GetBuffer(const PspImage *image);
static inline int PutChar(const PspFont *font, int sx, int sy, unsigned char sym, int color);
void pspVideoInit()
{
PixelFormat = GU_PSM_5551;
TexColor = GU_COLOR_5551;
VramOffset = 0;
FrameIndex = 0;
VramChunkOffset = (void*)0x44088000;
// ScratchBufferSize = sizeof(unsigned short) * BUF_WIDTH * SCR_HEIGHT;
// ScratchBuffer = pspVideoAllocateVramChunk(ScratchBufferSize); //;memalign(16, ScratchBufferSize);
int size;
unsigned int vram_buffer_offset = 0;
/* Initialize draw buffer */
size = 2 * BUF_WIDTH * SCR_HEIGHT;
DrawBuffer = (void*)vram_buffer_offset;
vram_buffer_offset += size;
/* Initialize display buffer */
size = 4 * BUF_WIDTH * SCR_HEIGHT;
DisplayBuffer = (void*)vram_buffer_offset;
vram_buffer_offset += size;
/* Initialize depth buffer */
size = 2 * BUF_WIDTH * SCR_HEIGHT;
void *depth_buf = (void*)vram_buffer_offset;
vram_buffer_offset += size;
sceGuInit();
sceGuStart(GU_DIRECT, List);
sceGuDrawBuffer(PixelFormat, DrawBuffer, BUF_WIDTH);
sceGuDispBuffer(SCR_WIDTH, SCR_HEIGHT, DisplayBuffer, BUF_WIDTH);
sceGuDepthBuffer(depth_buf, BUF_WIDTH);
sceGuDisable(GU_TEXTURE_2D);
sceGuOffset(0, 0);
sceGuViewport(SCR_WIDTH/2, SCR_HEIGHT/2, SCR_WIDTH, SCR_HEIGHT);
sceGuDepthRange(0xc350, 0x2710);
sceGuDisable(GU_ALPHA_TEST);
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
sceGuEnable(GU_BLEND);
sceGuDisable(GU_DEPTH_TEST);
sceGuEnable(GU_CULL_FACE);
sceGuDisable(GU_LIGHTING);
sceGuFrontFace(GU_CW);
sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT);
sceGuEnable(GU_SCISSOR_TEST);
sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
sceGuAmbientColor(0xffffffff);
sceGuFinish();
sceGuSync(0,0);
/* Compute VBlank frequency */
u64 t[2];
int i;
for (i = 0; i < 2; i++)
{
sceDisplayWaitVblankStart();
sceRtcGetCurrentTick(&t[i]);
}
VBlankFreq = round(1.00 / ((double)(t[1] - t[0])
* (1.00 / (double)sceRtcGetTickResolution())));
sceGuDisplay(GU_TRUE);
}
void* GetBuffer(const PspImage *image)
{
int i, j, w, h;
static int last_w = -1, last_h = -1;
int x_offset, x_skip, x_buf_skip;
w = (image->Viewport.Width > BUF_WIDTH)
? BUF_WIDTH : image->Viewport.Width;
h = (image->Viewport.Height > SCR_HEIGHT)
? SCR_HEIGHT : image->Viewport.Height;
if (w != last_w || h != last_h)
memset(ScratchBuffer, 0, sizeof(ScratchBuffer));
x_offset = image->Viewport.X;
x_skip = image->Width - (image->Viewport.X + image->Viewport.Width);
x_buf_skip = BUF_WIDTH - w;
if (image->Depth == PSP_IMAGE_INDEXED)
{
unsigned char *img_ptr = &((unsigned char*)image->Pixels)[image->Viewport.Y * image->Width];
unsigned char *buf_ptr = (unsigned char*)ScratchBuffer;
for (i = 0; i < h; i++)
{
img_ptr += x_offset;
for (j = 0; j < w; j++, img_ptr++, buf_ptr++)
*buf_ptr = *img_ptr;
buf_ptr += x_buf_skip;
img_ptr += x_skip;
}
}
else if (image->Depth == PSP_IMAGE_16BPP)
{
unsigned short *img_ptr = &((unsigned short*)image->Pixels)[image->Viewport.Y * image->Width];
unsigned short *buf_ptr = ScratchBuffer;
for (i = 0; i < h; i++)
{
img_ptr += x_offset;
for (j = 0; j < w; j++, img_ptr++, buf_ptr++)
*buf_ptr = *img_ptr;
buf_ptr += x_buf_skip;
img_ptr += x_skip;
}
}
last_w = w;
last_h = h;
return ScratchBuffer;
}
void pspVideoBeginList(void *list)
{
sceGuStart(GU_CALL, list);
}
void pspVideoBegin()
{
sceGuStart(GU_DIRECT, List);
}
void pspVideoEnd()
{
sceGuFinish();
sceGuSync(0, 0);
}
void pspVideoPutImage(const PspImage *image, int dx, int dy, int dw, int dh)
{
sceGuScissor(dx, dy, dx + dw, dy + dh);
void *pixels;
int width;
if (image->PowerOfTwo)
{
pixels = image->Pixels;
width = image->Width;
}
else
{
pixels = GetBuffer(image);
width = BUF_WIDTH;
}
sceKernelDcacheWritebackAll();
/*
if (image->Depth != PSP_IMAGE_INDEXED &&
dw == image->Viewport.Width && dh == image->Viewport.Height)
{
sceGuCopyImage(PixelFormat,
image->Viewport.X, image->Viewport.Y,
image->Viewport.Width, image->Viewport.Height,
width, pixels, dx, dy,
BUF_WIDTH, (void *)(VRAM_START + (u32)VramOffset));
}
else
*/
{
sceGuEnable(GU_TEXTURE_2D);
if (image->Depth == PSP_IMAGE_INDEXED)
{
sceGuClutMode(PixelFormat, 0, 0xff, 0);
sceGuClutLoad(image->PalSize >> 3, image->Palette);
}
sceGuTexMode(image->TextureFormat, 0, 0, GU_FALSE);
sceGuTexImage(0, width, width, width, pixels);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
if (bilinear == 0 )
{
sceGuTexFilter(GU_NEAREST, GU_NEAREST);
}
else if (bilinear == 1 )
{
sceGuTexFilter(GU_LINEAR, GU_LINEAR);
}
struct TexVertex* vertices;
int start, end, sc_end, slsz_scaled;
slsz_scaled = ceil((float)dw * (float)SLICE_SIZE) / (float)image->Viewport.Width;
start = image->Viewport.X;
end = image->Viewport.X + image->Viewport.Width;
sc_end = dx + dw;
/* TODO: Convert to floating-point coords */
for (; start < end; start += SLICE_SIZE, dx += slsz_scaled)
{
vertices = (struct TexVertex*)sceGuGetMemory(2 * sizeof(struct TexVertex));
vertices[0].u = start;
vertices[0].v = image->Viewport.Y;
vertices[1].u = start + SLICE_SIZE;
vertices[1].v = image->Viewport.Height + image->Viewport.Y;
/* NOTA*/
if (res2x == 0)
{vertices[0].x = dx; vertices[0].y = dy;}
else if (res2x == 1)
{vertices[0].x = dx; vertices[0].y = dy-vertical;}
vertices[1].x = dx + slsz_scaled; vertices[1].y = dy + dh;
vertices[0].color
= vertices[1].color
= vertices[0].z
= vertices[1].z = 0;
sceGuDrawArray(GU_SPRITES,
GU_TEXTURE_16BIT|TexColor|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices);
}
sceGuDisable(GU_TEXTURE_2D);
}
sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT);
}
void pspVideoPutImage1(const PspImage *image, int dx, int dy, int dw, int dh)
{
sceGuScissor(dx, dy, dx + dw, dy + dh);
void *pixels;
int width;
if (image->PowerOfTwo)
{
pixels = image->Pixels;
width = image->Width;
}
else
{
pixels = GetBuffer(image);
width = BUF_WIDTH;
}
sceKernelDcacheWritebackAll();
/*
if (image->Depth != PSP_IMAGE_INDEXED &&
dw == image->Viewport.Width && dh == image->Viewport.Height)
{
sceGuCopyImage(PixelFormat,
image->Viewport.X, image->Viewport.Y,
image->Viewport.Width, image->Viewport.Height,
width, pixels, dx, dy,
BUF_WIDTH, (void *)(VRAM_START + (u32)VramOffset));
}
else
*/
{
sceGuEnable(GU_TEXTURE_2D);
if (image->Depth == PSP_IMAGE_INDEXED)
{
sceGuClutMode(PixelFormat, 0, 0xff, 0);
sceGuClutLoad(image->PalSize >> 3, image->Palette);
}
sceGuTexMode(image->TextureFormat, 0, 0, GU_FALSE);
sceGuTexImage(0, width, width, width, pixels);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
sceGuTexFilter(GU_NEAREST, GU_NEAREST);
struct TexVertex* vertices;
int start, end, sc_end, slsz_scaled;
slsz_scaled = ceil((float)dw * (float)SLICE_SIZE) / (float)image->Viewport.Width;
start = image->Viewport.X;
end = image->Viewport.X + image->Viewport.Width;
sc_end = dx + dw;
/* TODO: Convert to floating-point coords */
for (; start < end; start += SLICE_SIZE, dx += slsz_scaled)
{
vertices = (struct TexVertex*)sceGuGetMemory(2 * sizeof(struct TexVertex));
vertices[0].u = start;
vertices[0].v = image->Viewport.Y;
vertices[1].u = start + SLICE_SIZE;
vertices[1].v = image->Viewport.Height + image->Viewport.Y;
/* NOTA*/
{vertices[0].x = dx; vertices[0].y = dy;}
vertices[1].x = dx + slsz_scaled; vertices[1].y = dy + dh;
vertices[0].color
= vertices[1].color
= vertices[0].z
= vertices[1].z = 0;
sceGuDrawArray(GU_SPRITES,
GU_TEXTURE_16BIT|TexColor|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices);
}
sceGuDisable(GU_TEXTURE_2D);
}
sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT);
}
void pspVideoPutImageAlpha(const PspImage *image, int dx, int dy, int dw, int dh,
unsigned char alpha)
{
sceGuScissor(dx, dy, dx + dw, dy + dh);
void *pixels;
int width;
if (image->PowerOfTwo)
{
pixels = image->Pixels;
width = image->Width;
}
else
{
pixels = GetBuffer(image);
width = BUF_WIDTH;
}
sceKernelDcacheWritebackAll();
/*
if (image->Depth != PSP_IMAGE_INDEXED &&
dw == image->Viewport.Width && dh == image->Viewport.Height)
{
sceGuCopyImage(PixelFormat,
image->Viewport.X, image->Viewport.Y,
image->Viewport.Width, image->Viewport.Height,
width, pixels, dx, dy,
BUF_WIDTH, (void *)(VRAM_START + (u32)VramOffset));
}
else
*/
{
unsigned int alpha_color = 0xff
| ((unsigned int)alpha << 8)
| ((unsigned int)alpha << 16)
| ((unsigned int)alpha << 24);
sceGuEnable(GU_TEXTURE_2D);
sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, alpha_color, alpha_color);
if (image->Depth == PSP_IMAGE_INDEXED)
{
sceGuClutMode(PixelFormat, 0, 0xff, 0);
sceGuClutLoad(image->PalSize >> 3, image->Palette);
}
sceGuTexMode(image->TextureFormat, 0, 0, GU_FALSE);
sceGuTexImage(0, width, width, width, pixels);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
sceGuTexFilter(GU_LINEAR, GU_LINEAR);
struct TexVertex* vertices;
int start, end, sc_end, slsz_scaled;
slsz_scaled = ceil((float)dw * (float)SLICE_SIZE) / (float)image->Viewport.Width;
start = image->Viewport.X;
end = image->Viewport.X + image->Viewport.Width;
sc_end = dx + dw;
/* TODO: Convert to floating-point coords */
for (; start < end; start += SLICE_SIZE, dx += slsz_scaled)
{
vertices = (struct TexVertex*)sceGuGetMemory(2 * sizeof(struct TexVertex));
vertices[0].u = start;
vertices[0].v = image->Viewport.Y;
vertices[1].u = start + SLICE_SIZE;
vertices[1].v = image->Viewport.Height + image->Viewport.Y;
vertices[0].x = dx; vertices[0].y = dy;
vertices[1].x = dx + slsz_scaled; vertices[1].y = dy + dh;
vertices[0].color
= vertices[1].color
= vertices[0].z
= vertices[1].z = 0;
sceGuDrawArray(GU_SPRITES,
GU_TEXTURE_16BIT|TexColor|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices);
}
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
sceGuDisable(GU_TEXTURE_2D);
}
sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT);
}
void pspVideoSwapBuffers()
{
VramOffset = sceGuSwapBuffers();
FrameIndex = !FrameIndex;
}
void pspVideoShutdown()
{
sceGuTerm();
}
void pspVideoWaitVSync()
{
sceDisplayWaitVblankStart();
}
void pspVideoDrawLine(int sx, int sy, int dx, int dy, u32 color)
{
PspVertex *vert = (PspVertex*)sceGuGetMemory(sizeof(PspVertex) * 2);
memset(vert, 0, sizeof(PspVertex) * 2);
vert[0].x = sx; vert[0].y = sy; vert[0].color = color;
vert[1].x = dx; vert[1].y = dy; vert[1].color = color;
sceGuDrawArray(GU_LINES, GU_COLOR_8888 | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, NULL, vert);
}
void pspVideoDrawRect(int sx, int sy, int dx, int dy, u32 color)
{
PspVertex *vert = (PspVertex*)sceGuGetMemory(sizeof(PspVertex) * 5);
memset(vert, 0, sizeof(PspVertex) * 5);
vert[0].x=sx; vert[0].y=sy; vert[0].color = color;
vert[1].x=sx; vert[1].y=dy; vert[1].color = color;
vert[2].x=dx; vert[2].y=dy; vert[2].color = color;
vert[3].x=dx; vert[3].y=sy; vert[3].color = color;
vert[4].x=sx; vert[4].y=sy; vert[4].color = color;
sceGuDrawArray(GU_LINE_STRIP, GU_COLOR_8888|GU_VERTEX_16BIT|GU_TRANSFORM_2D, 5, NULL, vert);
}
void pspVideoShadowRect(int sx, int sy, int dx, int dy, u32 color, int depth)
{
int i;
u32 alpha;
color &= ~0xff000000;
for (i = depth, alpha = 0x30000000; i > 0; i--, alpha += 0x20000000)
{
pspVideoDrawLine(sx + i, dy + i, dx + i, dy + i, color | alpha);
pspVideoDrawLine(dx + i, sy + i, dx + i, dy + i + 1, color | alpha);
}
}
void pspVideoGlowRect(int sx, int sy, int dx, int dy, u32 color, int radius)
{
int i;
u32 alpha;
color &= ~0xff000000;
for (i = radius, alpha = 0x30000000; i > 0; i--, alpha += 0x20000000)
pspVideoDrawRect(sx - i, sy - i, dx + i, dy + i, color | alpha);
}
void pspVideoFillRect(int sx, int sy, int dx, int dy, u32 color)
{
PspVertex *vert = (PspVertex*)sceGuGetMemory(4 * sizeof(PspVertex));
memset(vert, 0, sizeof(PspVertex) * 4);
vert[0].x = sx; vert[0].y = sy; vert[0].color = color;
vert[1].x = dx; vert[1].y = sy; vert[1].color = color;
vert[2].x = dx; vert[2].y = dy; vert[2].color = color;
vert[3].x = sx; vert[3].y = dy; vert[3].color = color;
sceGuDrawArray(GU_TRIANGLE_FAN, GU_COLOR_8888|GU_VERTEX_16BIT|GU_TRANSFORM_2D, 4, NULL, vert);
}
void pspVideoCallList(const void *list)
{
sceGuCallList(list);
}
void pspVideoClearScreen()
{
sceGuClear(GU_COLOR_BUFFER_BIT);
}
inline int PutChar(const PspFont *font, int sx, int sy, unsigned char sym, int color)
{
/* Instead of a tab, skip 4 spaces */
if (sym == (u8)'\t')
return font->Chars[(int)' '].Width * 4;
/* This function should be rewritten to write directly to VRAM, probably */
int h, v, i, j, w, s;
w = font->Chars[(int)sym].Width;
h = font->Height;
/* Allocate and clear enough memory to write the pixels of the char */
s = sizeof(PspVertex) * (w + 2) * (h + 2);
PspVertex *vert = (PspVertex*)sceGuGetMemory(s);
memset(vert, 0, s);
unsigned short row;
int shift;
v = 0;
for (j = 0; j < w; j++)
if (font->Chars[(int)sym].Char[0] & (1 << (w - j)))
{ vert[v].x = sx + j; vert[v].y = sy - 1; vert[v].color = 0xff000000; v++; }
/* Initialize pixel values */
for (i = 0; i < h; i++)
{
for (j = 0; j < w; j++)
{
row = font->Chars[(int)sym].Char[i];
shift = w - j;
if (row & (1 << shift))
{
if (j == 0 || !(row & (1 << (shift + 1))))
{ vert[v].x = sx + j - 1; vert[v].y = sy + i; vert[v].color = 0xff000000; v++; }
vert[v].x = sx + j; vert[v].y = sy + i; vert[v].color = color; v++;
vert[v].x = sx + j + 1; vert[v].y = sy + i; vert[v].color = 0xff000000; v++;
}
else if (i > 0 && i < h - 1)
{
if ((i > 0) && (font->Chars[(int)sym].Char[i - 1] & (1 << shift)))
{ vert[v].x = sx + j; vert[v].y = sy + i; vert[v].color = 0xff000000; v++; }
else if ((i < h - 1) && (font->Chars[(int)sym].Char[i + 1] & (1 << shift)))
{ vert[v].x = sx + j; vert[v].y = sy + i; vert[v].color = 0xff000000; v++; }
}
}
}
for (j = 0; j < w; j++)
if (font->Chars[(int)sym].Char[h - 1] & (1 << (w - j)))
{ vert[v].x = sx + j; vert[v].y = sy + h; vert[v].color = 0xff000000; v++; }
/* Render the char as a set of pixels */
sceGuDrawArray(GU_POINTS, GU_COLOR_8888|GU_VERTEX_16BIT|GU_TRANSFORM_2D, v, NULL, vert);
/* Return total width */
return w;
}
int pspVideoPrint(const PspFont *font, int sx, int sy, const char *string, u32 color)
{
return pspVideoPrintN(font, sx, sy, string, -1, color);
}
int pspVideoPrintCenter(const PspFont *font, int sx, int sy, int dx, const char *string, u32 color)
{
const unsigned char *ch;
int width, c = color, max;
width = pspFontGetTextWidth(font, string);
sx += (dx - sx) / 2 - width / 2;
for (ch = (unsigned char*)string, width = 0, max = 0; *ch; ch++)
{
if (*ch < 32)
{
if (*ch >= PSP_FONT_RESTORE && *ch <= PSP_FONT_WHITE)
{
c = (*ch == PSP_FONT_RESTORE) ? color : PspFontColor[(int)(*ch) - PSP_FONT_RESTORE];
continue;
}
else if (*ch == '\n')
{
sy += font->Height;
width = 0;
continue;
}
}
width += PutChar(font, sx + width, sy, (u8)(*ch), c);
if (width > max) max = width;
}
return max;
}
int pspVideoPrintN(const PspFont *font, int sx, int sy, const char *string, int count, u32 color)
{
const unsigned char *ch;
int width, i, c = color, max;
for (ch = (unsigned char*)string, width = 0, i = 0, max = 0; *ch && (count < 0 || i < count); ch++, i++)
{
if (*ch < 32)
{
if (*ch >= PSP_FONT_RESTORE && *ch <= PSP_FONT_WHITE)
{
c = (*ch == PSP_FONT_RESTORE) ? color : PspFontColor[(int)(*ch) - PSP_FONT_RESTORE];
continue;
}
else if (*ch == '\n')
{
sy += font->Height;
width = 0;
continue;
}
}
width += PutChar(font, sx + width, sy, (u8)(*ch), c);
if (width > max) max = width;
}
return max;
}
int pspVideoPrintClipped(const PspFont *font, int sx, int sy, const char* string, int max_w, char* clip, u32 color)
{
int str_w = pspFontGetTextWidth(font, string);
if (str_w <= max_w)
return pspVideoPrint(font, sx, sy, string, color);
int w, len;
const char *ch;
int clip_w = pspFontGetTextWidth(font, clip);
for (ch=string, w=0, len=0; *ch && (w + clip_w < max_w); ch++, len++)
{
if (*ch == '\t') w += font->Chars[(u8)' '].Width * 4;
else w += font->Chars[(u8)(*ch)].Width;
}
w = pspVideoPrintN(font, sx, sy, string, len - 1, color);
pspVideoPrint(font, sx + w, sy, clip, color);
return w + clip_w;
}
PspImage* pspVideoGetVramBufferCopy()
{
int i, j;
unsigned short *pixel,
*vram_addr = (u16*)((u8*)VRAM_START + 0x40000000);
PspImage *image;
if (!(image = pspImageCreate(BUF_WIDTH, SCR_HEIGHT, PSP_IMAGE_16BPP)))
return NULL;
image->Viewport.Width = SCR_WIDTH;
for (i = 0; i < image->Height; i++)
{
for (j = 0; j < image->Viewport.Width; j++)
{
pixel = (unsigned short*)image->Pixels + (i * image->Width + j);
*pixel = *(vram_addr + (i * BUF_WIDTH + j)) | 0x8000;
}
}
return image;
}
void* pspVideoAllocateVramChunk(unsigned int bytes)
{
void *ptr = VramChunkOffset;
VramChunkOffset += bytes;
return ptr;
}
unsigned int pspVideoGetVSyncFreq()
{
return VBlankFreq;
}

118
psp/psplib/video.h Normal file
View File

@ -0,0 +1,118 @@
/* psplib/video.h
Graphics rendering routines
Copyright (C) 2007-2008 Akop Karapetyan
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 3 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, see <http://www.gnu.org/licenses/>.
Author contact information: pspdev@akop.org
*/
#ifndef _PSP_VIDEO_H
#define _PSP_VIDEO_H
#include <psptypes.h>
#include "font.h"
#include "image.h"
#ifdef __cplusplus
extern "C" {
#endif
#define PSP_COLOR_WHITE (u32)0xffffffff
#define PSP_COLOR_BLACK (u32)0xff000000
#define PSP_COLOR_GRAY (u32)0xffcccccc
#define PSP_COLOR_DARKGRAY (u32)0xff777777
#define PSP_COLOR_RED (u32)0xff0000ff
#define PSP_COLOR_GREEN (u32)0xff00ff00
#define PSP_COLOR_BLUE (u32)0xffff0000
#define PSP_COLOR_YELLOW (u32)0xff00ffff
#define PSP_COLOR_MAGENTA (u32)0xffff00ff
#define PSP_VIDEO_UNSCALED 0
#define PSP_VIDEO_FIT_HEIGHT 1
#define PSP_VIDEO_FILL_SCREEN 2
#define BUF_WIDTH 512
#define SCR_WIDTH 480
#define SCR_HEIGHT 272
#define COLOR(r,g,b,a) (((int)(r)&0xff)|(((int)(g)&0xff)<<8)|\
(((int)(b)&0xff)<<16)|(((int)(a)&0xff)<<24))
#define RGB(r,g,b) (((((b)>>3)&0x1F)<<10)|((((g)>>3)&0x1F)<<5)|\
(((r)>>3)&0x1F)|0x8000)
#define RED(pixel) ((((pixel))&0x1f)*0xff/0x1f)
#define GREEN(pixel) ((((pixel)>>5)&0x1f)*0xff/0x1f)
#define BLUE(pixel) ((((pixel)>>10)&0x1f)*0xff/0x1f)
#define RGB_32(r,g,b) COLOR(r,g,b,0xff)
#define RGBA_32(r,g,b,a) COLOR(r,g,b,a)
#define RED_32(c) ((c)&0xff)
#define GREEN_32(c) (((c)>>8)&0xff)
#define BLUE_32(c) (((c)>>16)&0xff)
#define ALPHA_32(c) (((c)>>24)&0xff)
extern const unsigned int PspFontColor[];
typedef struct PspVertex
{
unsigned int color;
short x, y, z;
} PspVertex;
void pspVideoInit();
void pspVideoShutdown();
void pspVideoClearScreen();
void pspVideoWaitVSync();
void pspVideoSwapBuffers();
void pspVideoBegin();
void pspVideoEnd();
void pspVideoDrawLine(int sx, int sy, int dx, int dy, u32 color);
void pspVideoDrawRect(int sx, int sy, int dx, int dy, u32 color);
void pspVideoFillRect(int sx, int sy, int dx, int dy, u32 color);
int pspVideoPrint(const PspFont *font, int sx, int sy, const char *string, u32 color);
int pspVideoPrintCenter(const PspFont *font, int sx, int sy, int dx, const char *string, u32 color);
int pspVideoPrintN(const PspFont *font, int sx, int sy, const char *string, int count, u32 color);
int pspVideoPrintClipped(const PspFont *font, int sx, int sy, const char* string, int max_w, char* clip, u32 color);
int pspVideoPrintNRaw(const PspFont *font, int sx, int sy, const char *string, int count, u32 color);
int pspVideoPrintRaw(const PspFont *font, int sx, int sy, const char *string, u32 color);
void pspVideoPutImage(const PspImage *image, int dx, int dy, int dw, int dh);
void pspVideoPutImage1(const PspImage *image, int dx, int dy, int dw, int dh);
void pspVideoPutImageAlpha(const PspImage *image, int dx, int dy, int dw, int dh,
unsigned char alpha);
void pspVideoGlowRect(int sx, int sy, int dx, int dy, u32 color, int radius);
void pspVideoShadowRect(int sx, int sy, int dx, int dy, u32 color, int depth);
PspImage* pspVideoGetVramBufferCopy();
void pspVideoBeginList(void *list);
void pspVideoCallList(const void *list);
void* pspVideoAllocateVramChunk(unsigned int bytes);
unsigned int pspVideoGetVSyncFreq();
#ifdef __cplusplus
}
#endif
#endif // _PSP_VIDEO_H

BIN
psp/race-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

90
readme.txt Normal file
View File

@ -0,0 +1,90 @@
/ __/ /
/ _// / . ||//.\/ ./
/_/ /_/_/|_|_/\_/_/\_\
===================================================================================
Full Name: RACE! (As In Koyote-Land)
Date: 5-18-06
Original Author: Judge_
Website: http://www.personal.triticom.com/~erm/GP2X/
Contact: http://www.gp32x.com/board/index.php?showuser=300
http://www.neo-geo.com/forums/member.php?userid=1670
GPL: Yes
(R)ather
(A)
(C)ardfighter
(E)mulator
(!)
RACE! is a Neo Geo Pocket (NGP) and Neo Geo Pocket Color (NGPC) emulator for
multiple platforms.
===================================================================================
Known Issues:
-------------
Must exit emulator using L+R to make sure save-game file gets written
Missing file selector
No emulator state saving
Portability:
------------
The GP2X and PC versions use SDL. The code should be very portable to any
Little Endian system. If your system is Big Endian, the TLCS900h core may
be problematic.
Please contact Flavor if you have any interest in porting RACE! to another system.
Credits:
--------
Judge_ - RACE! is based on Judge_'s MHE (Multiple Handheld Emulator) code.
Judge_ is a guru of the NGPC devel scene.
Flavor - Flavor has been the head of the project to port Judge_'s emulator
to GP2X. Porting/Optimizing/Testing/Fixing/etc.
Thor - Thor has been integral to the RACE! project. He was originally
contacted to help fix a sound problem. Since then he was fixed
numerous items, optimized many parts of the emulation, and ported RACE!
to the GP32 among other things.
Reesy - Thanks to Reesy, we have DrZ80, a hand optimized ARM ASM Z80 core.
Hooka - TJ Hooka is head of the PR department.
NeoPop_uk- Author of the NeoPop NGPC emulator. Some of his code is in RACE!
and some ideas have come from his emulator.
Cal2 - AKA David Raingeard. Koyote has been an inspiration, and some
information and example code has come from Koyote.
Tom at www.Play-Asia.com
- Without you, I might not own a GP2X or may not have owned a GP32!
Mr. Spiv - ARM assembly code and more
Mithris - Code pointers and GP2X hardware help
RobBrown - Morale support and code help
Empee - Sometimes just being there is enough.
Sweater Fish Deluxe
- Help with NGPC flash cart codes from my days of working on my
MultiROM project.
Craigix at www.gp2x.co.uk and www.gbax.com
- Thanks for pushing the GP32 and GP2X scenes with great competitions,
prizes, games, etc. Also, thanks for dealing with GamePark and GPH for us.
Other people that have helped me along the way.
Fuz, Ivan, Darkfader, JeffF, and everyone on the NGPCdev Yahoo! Groups List
Comic Kaze and all the people at the Sector: NGP forum.
Miq01, Paeryn, Guyfawkes, DZZ, and the developers from #gp2xdev
Firefly, Don Miguel, Ph0x, and others from #gp32dev
www.gp32x.com and www.neo-geo.com forum people

112
sound.cpp Normal file
View File

@ -0,0 +1,112 @@
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
// sound.cpp: implementation of the sound class.
//
//////////////////////////////////////////////////////////////////////
//Flavor - Convert from DirectSound to SDL
#ifndef __GP32__
#include "StdAfx.h"
#endif
#include "main.h"
#include "sound.h"
#include "memory.h"
#ifdef DRZ80
#include "DrZ80_support.h"
#else
#if defined(CZ80)
#include "cz80_support.h"
#else
#include "z80.h"
#endif
#endif
#ifndef __GP32__
#include <math.h>
#endif
#define Machine (&m_emuInfo)
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
int sndCycles = 0;
void soundStep(int cycles)
{
sndCycles+= cycles;
}
/////////////////////////////////////////////////////////////////////////////////
///
/// Neogeo Pocket Sound system
///
/////////////////////////////////////////////////////////////////////////////////
unsigned int ngpRunning;
void ngpSoundStart()
{
ngpRunning = 1; // ?
#if defined(DRZ80) || defined(CZ80)
Z80_Reset();
#else
z80Init();
z80SetRunning(1);
#endif
}
/// Execute all gained cycles (divided by 2)
void ngpSoundExecute()
{
#if defined(DRZ80) || defined(CZ80)
int toRun = sndCycles/2;
if(ngpRunning)
{
Z80_Execute(toRun);
}
//timer_add_cycles(toRun);
sndCycles -= toRun;
#else
int elapsed;
while(sndCycles > 0)
{
elapsed = z80Step();
sndCycles-= (2*elapsed);
//timer_add_cycles(elapsed);
}
#endif
}
/// Switch sound system off
void ngpSoundOff() {
ngpRunning = 0;
#if defined(DRZ80) || defined(CZ80)
#else
z80SetRunning(0);
#endif
}
// Generate interrupt to ngp sound system
void ngpSoundInterrupt() {
if (ngpRunning)
{
#if defined(DRZ80) || defined(CZ80)
Z80_Cause_Interrupt(0x100);//Z80_IRQ_INT???
#else
z80Interrupt(0);
#endif
}
}

68
sound.h Normal file
View File

@ -0,0 +1,68 @@
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
// sound.h: interface for the sound class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_SOUND_H__15E0A182_A0FD_11D4_8645_0050DA4EEEA0__INCLUDED_)
#define AFX_SOUND_H__15E0A182_A0FD_11D4_8645_0050DA4EEEA0__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __GP32__
#include "StdAfx.h"
#endif
#include "main.h"
int initSound();
void soundCleanup();
#ifndef __GP32__
void setHwnd(HWND hWnd);
#endif
//
// stolen MAME things
//
int osd_start_audio_stream(int stereo);
void osd_stop_audio_stream(void);
int osd_update_audio_stream(short *buffer);
void osd_set_mastervolume(int _attenuation);
int osd_get_mastervolume(void);
//
// General sound system functions
//
void soundStep(int cycles);
void soundOutput();
#define NUM_CHANNELS 32
#if !defined(__GP32__) && !defined(PSP)
extern Mix_Chunk *chunks[NUM_CHANNELS];
#endif
//
// Gameboy sound system
//
void gbSoundInit();
void gbSoundUpdate();
void gbSoundWrite(int reg, unsigned char data);
///
/// Neogeo pocket sound functions
///
void sound_update(void);
void ngpSoundStart();
void ngpSoundExecute();
void ngpSoundOff();
void ngpSoundInterrupt();
#endif // !defined(AFX_SOUND_H__15E0A182_A0FD_11D4_8645_0050DA4EEEA0__INCLUDED_)

421
state.cpp Normal file
View File

@ -0,0 +1,421 @@
//---------------------------------------------------------------------------
// 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. See also the license.txt file for
// additional informations.
//---------------------------------------------------------------------------
// state.cpp: state saving
//
// 01/20/2009 Cleaned up interface, added loading from memory
// Moved signature-related stuff out of race_state (A.K.)
// 09/11/2008 Initial version (Akop Karapetyan)
//
//////////////////////////////////////////////////////////////////////
#include "cz80.h"
#include "neopopsound.h"
#include <string.h>
#include <stdio.h>
#include "state.h"
#include "tlcs900h.h"
#include "memory.h"
#ifdef PC
#undef PC
#endif
#define CURRENT_SAVE_STATE_VERSION 0x11
struct race_state_header
{
u8 state_version; /* State version */
u8 rom_signature[0x40]; /* Rom signature, for verification */
};
struct race_state_0x11
{
/* Memory */
u8 ram[0xc000];
u8 cpuram[0x08a0];
/* TLCS-900h Registers */
u32 pc, sr;
u8 f_dash;
u32 gpr[23];
/* Z80 Registers */
cz80_struc RACE_cz80_struc;
u32 PC_offset;
s32 Z80_ICount;
/* Sound */
int sndCycles;
SoundChip toneChip;
SoundChip noiseChip;
/* Timers */
int timer0, timer1, timer2, timer3;
/* DMA */
u8 ldcRegs[64];
};
struct race_state_0x10 /* Older state format */
{
//Save state version
u8 state_version; // = 0x10
//Rom signature
u8 rom_signature[0x40];
//Memory
u8 ram[0xc000];
u8 cpuram[0x08a0];// 0xC000]; 0x38000
//TLCS-900h Registers
u32 pc, sr;
u8 f_dash;
u32 gpr[23];
//Z80 Registers
cz80_struc RACE_cz80_struc;
u32 PC_offset;
s32 Z80_ICount;
//Sound Chips
int sndCycles;
SoundChip toneChip;
SoundChip noiseChip;
//Timers
int timer0, timer1, timer2, timer3;
//DMA
u8 ldcRegs[64];
};
typedef struct race_state_0x11 race_state_t;
static int state_store(race_state_t *rs);
static int state_restore(race_state_t *rs);
static int state_restore_0x10(FILE *stream);
int state_store_mem(void *state)
{
return state_store((race_state_t*)state);
}
int state_restore_mem(void *state)
{
return state_restore((race_state_t*)state);
}
int state_get_size()
{
return sizeof(race_state_t);
}
static int state_store(race_state_t *rs)
{
int i = 0;
/* TLCS-900h Registers */
rs->pc = gen_regsPC;
rs->sr = gen_regsSR;
rs->f_dash = F2;
rs->gpr[i++] = gen_regsXWA0;
rs->gpr[i++] = gen_regsXBC0;
rs->gpr[i++] = gen_regsXDE0;
rs->gpr[i++] = gen_regsXHL0;
rs->gpr[i++] = gen_regsXWA1;
rs->gpr[i++] = gen_regsXBC1;
rs->gpr[i++] = gen_regsXDE1;
rs->gpr[i++] = gen_regsXHL1;
rs->gpr[i++] = gen_regsXWA2;
rs->gpr[i++] = gen_regsXBC2;
rs->gpr[i++] = gen_regsXDE2;
rs->gpr[i++] = gen_regsXHL2;
rs->gpr[i++] = gen_regsXWA3;
rs->gpr[i++] = gen_regsXBC3;
rs->gpr[i++] = gen_regsXDE3;
rs->gpr[i++] = gen_regsXHL3;
rs->gpr[i++] = gen_regsXIX;
rs->gpr[i++] = gen_regsXIY;
rs->gpr[i++] = gen_regsXIZ;
rs->gpr[i++] = gen_regsXSP;
rs->gpr[i++] = gen_regsSP;
rs->gpr[i++] = gen_regsXSSP;
rs->gpr[i++] = gen_regsXNSP;
/* Z80 Registers */
extern cz80_struc *RACE_cz80_struc;
extern s32 Z80_ICount;
int size_of_z80 =
(u32)(&(RACE_cz80_struc->CycleSup)) - (u32)(&(RACE_cz80_struc->BC));
memcpy(&rs->RACE_cz80_struc, RACE_cz80_struc, size_of_z80);
rs->Z80_ICount = Z80_ICount;
rs->PC_offset = Cz80_Get_PC(RACE_cz80_struc);
/* Sound */
extern int sndCycles;
rs->sndCycles = sndCycles;
memcpy(&rs->toneChip, &toneChip, sizeof(SoundChip));
memcpy(&rs->noiseChip, &noiseChip, sizeof(SoundChip));
/* Timers */
rs->timer0 = timer0;
rs->timer1 = timer1;
rs->timer2 = timer2;
rs->timer3 = timer3;
/* DMA */
memcpy(&rs->ldcRegs, &ldcRegs, sizeof(ldcRegs));
/* Memory */
memcpy(rs->ram, mainram, sizeof(rs->ram));
memcpy(rs->cpuram, &mainram[0x20000], sizeof(rs->cpuram));
return 1;
}
static int state_restore(race_state_t *rs)
{
int i = 0;
/* TLCS-900h Registers */
gen_regsPC = rs->pc;
gen_regsSR = rs->sr;
F2 = rs->f_dash;
gen_regsXWA0 = rs->gpr[i++];
gen_regsXBC0 = rs->gpr[i++];
gen_regsXDE0 = rs->gpr[i++];
gen_regsXHL0 = rs->gpr[i++];
gen_regsXWA1 = rs->gpr[i++];
gen_regsXBC1 = rs->gpr[i++];
gen_regsXDE1 = rs->gpr[i++];
gen_regsXHL1 = rs->gpr[i++];
gen_regsXWA2 = rs->gpr[i++];
gen_regsXBC2 = rs->gpr[i++];
gen_regsXDE2 = rs->gpr[i++];
gen_regsXHL2 = rs->gpr[i++];
gen_regsXWA3 = rs->gpr[i++];
gen_regsXBC3 = rs->gpr[i++];
gen_regsXDE3 = rs->gpr[i++];
gen_regsXHL3 = rs->gpr[i++];
gen_regsXIX = rs->gpr[i++];
gen_regsXIY = rs->gpr[i++];
gen_regsXIZ = rs->gpr[i++];
gen_regsXSP = rs->gpr[i++];
gen_regsSP = rs->gpr[i++];
gen_regsXSSP = rs->gpr[i++];
gen_regsXNSP = rs->gpr[i++];
/* Z80 Registers */
extern cz80_struc *RACE_cz80_struc;
extern s32 Z80_ICount;
int size_of_z80 =
(u32)(&(RACE_cz80_struc->CycleSup)) - (u32)(&(RACE_cz80_struc->BC));
memcpy(RACE_cz80_struc, &rs->RACE_cz80_struc, size_of_z80);
Z80_ICount = rs->Z80_ICount;
Cz80_Set_PC(RACE_cz80_struc, rs->PC_offset);
/* Sound */
extern int sndCycles;
sndCycles = rs->sndCycles;
memcpy(&toneChip, &rs->toneChip, sizeof(SoundChip));
memcpy(&noiseChip, &rs->noiseChip, sizeof(SoundChip));
/* Timers */
timer0 = rs->timer0;
timer1 = rs->timer1;
timer2 = rs->timer2;
timer3 = rs->timer3;
/* DMA */
memcpy(&ldcRegs, &rs->ldcRegs, sizeof(ldcRegs));
/* Memory */
memcpy(mainram, rs->ram, sizeof(rs->ram));
memcpy(&mainram[0x20000], rs->cpuram, sizeof(rs->cpuram));
/* Reinitialize TLCS (mainly redirect pointers) */
tlcs_reinit();
return 1;
}
int state_restore(FILE *stream)
{
/* Note current position (in case of compatibility rewinds */
long read_pos = ftell(stream);
/* Read header */
struct race_state_header rsh;
if (fread(&rsh, sizeof(rsh), 1, stream) < 1)
return 0;
/* Verify state version */
if (rsh.state_version == 0x10)
{
fseek(stream, read_pos, SEEK_SET); /* Rewind and load old format */
return state_restore_0x10(stream);
}
else if (rsh.state_version != CURRENT_SAVE_STATE_VERSION)
return 0; /* Unsupported version */
/* Verify ROM signature */
if (memcmp(mainrom, rsh.rom_signature, sizeof(rsh.rom_signature)) != 0)
return 0;
/* Read state data */
race_state_t rs;
if (fread(&rs, sizeof(rs), 1, stream) < 1)
return 0;
/* Restore state */
return state_restore(&rs);
}
int state_store(FILE *stream)
{
/* Set version & ROM signature information */
struct race_state_header rsh;
rsh.state_version = CURRENT_SAVE_STATE_VERSION;
memcpy(rsh.rom_signature, mainrom, sizeof(rsh.rom_signature));
/* Initialize state data */
race_state_t rs;
if (!state_store(&rs))
return 0;
/* Write to file */
if (fwrite(&rsh, sizeof(rsh), 1, stream) < 1)
return 0;
if (fwrite(&rs, sizeof(rs), 1, stream) < 1)
return 0;
return 1;
}
int state_store(char* filename)
{
FILE *stream;
if (!(stream = fopen(filename, "w")))
return 0;
int status = state_store(stream);
fclose(stream);
return status;
}
int state_restore(char* filename)
{
FILE *stream;
if (!(stream = fopen(filename, "r")))
return 0;
int status = state_restore(stream);
fclose(stream);
return status;
}
static int state_restore_0x10(FILE *stream)
{
struct race_state_0x10 rs;
if (fread(&rs, sizeof(rs), 1, stream) < 1)
return 0;
// Verify state version
if (rs.state_version != 0x10)
return 0;
// Verify ROM signature
if (memcmp(mainrom, rs.rom_signature, sizeof(rs.rom_signature)) != 0)
return 0;
//TLCS-900h Registers
gen_regsPC = rs.pc;
gen_regsSR = rs.sr;
F2 = rs.f_dash;
int i = 0;
gen_regsXWA0 = rs.gpr[i++];
gen_regsXBC0 = rs.gpr[i++];
gen_regsXDE0 = rs.gpr[i++];
gen_regsXHL0 = rs.gpr[i++];
gen_regsXWA1 = rs.gpr[i++];
gen_regsXBC1 = rs.gpr[i++];
gen_regsXDE1 = rs.gpr[i++];
gen_regsXHL1 = rs.gpr[i++];
gen_regsXWA2 = rs.gpr[i++];
gen_regsXBC2 = rs.gpr[i++];
gen_regsXDE2 = rs.gpr[i++];
gen_regsXHL2 = rs.gpr[i++];
gen_regsXWA3 = rs.gpr[i++];
gen_regsXBC3 = rs.gpr[i++];
gen_regsXDE3 = rs.gpr[i++];
gen_regsXHL3 = rs.gpr[i++];
gen_regsXIX = rs.gpr[i++];
gen_regsXIY = rs.gpr[i++];
gen_regsXIZ = rs.gpr[i++];
gen_regsXSP = rs.gpr[i++];
gen_regsSP = rs.gpr[i++];
gen_regsXSSP = rs.gpr[i++];
gen_regsXNSP = rs.gpr[i++];
//Z80 Registers
extern cz80_struc *RACE_cz80_struc;
extern s32 Z80_ICount;
int size_of_z80 =
(u32)(&(RACE_cz80_struc->CycleSup)) - (u32)(&(RACE_cz80_struc->BC));
memcpy(RACE_cz80_struc, &rs.RACE_cz80_struc, size_of_z80);
Z80_ICount = rs.Z80_ICount;
Cz80_Set_PC(RACE_cz80_struc, rs.PC_offset);
//Sound Chips
extern int sndCycles;
sndCycles = rs.sndCycles;
memcpy(&toneChip, &rs.toneChip, sizeof(SoundChip));
memcpy(&noiseChip, &rs.noiseChip, sizeof(SoundChip));
//Timers
timer0 = rs.timer0;
timer1 = rs.timer1;
timer2 = rs.timer2;
timer3 = rs.timer3;
//DMA
memcpy(&ldcRegs, &rs.ldcRegs, sizeof(ldcRegs));
//Memory
memcpy(mainram, rs.ram, sizeof(rs.ram));
memcpy(&mainram[0x20000], rs.cpuram, sizeof(rs.cpuram));
tlcs_reinit();
return 1;
}

Some files were not shown because too many files have changed in this diff Show More